如何在网站上绘制矩形以进行突出显示?

7
有没有办法实现一个类似谷歌反馈的功能,就像这里展示的那样?我们可以使用CSS使网站略微变暗,但是如何在特定界面上绘制一个矩形,就像突出显示某些文本或错误一样呢?我们可以使用与Sprite Cow相同的概念,在特定图像上突出显示矩形链接。欢迎任何想法和资源。
谢谢。

你是想要创建这个效果,还是想要模仿一些底层功能呢?如果你在Chrome调试器中查看它,就会发现底层使用了非常复杂的系统。 - Greg Guida
5个回答

7

最简单的方法可能就是在拖动鼠标时创建一个div,覆盖整个页面。

我猜Google使用的是类似这样的方法:

  • Draw a slightly dimmed div ("dimmer") on top of the whole page
  • When the user clicks and drags on the dimmer, they split it in multiple divs like this:

    ### | ## | ###
    ----+----+----
    ### |    | ###
    ----+----+----
    ### | ## | ###
    
  • In the above, the center area is the area the user was dragging over

  • The center area is now empty, and you can see the site through it, because the dimmer was split into 8 smaller divs.
  • While the user keeps the mouse button held down, the script keeps resizing the split dimmer divs to accommodate the rectangular area the user has dragged.
(它也可能省略我在图表中包含的额外div,因此只有一个div位于矩形上方,一个div位于下方,因为即使没有它们也可以工作)

:-D,逻辑非常出色。谢谢。 - A.P.S
但问题是...你如何拍摄快照? - TheBrain
@TheBrain 虽然不熟悉谷歌的做法,但最简单的方法是在页面上提供某种管理员视图。然后,在页面上使用脚本将矩形渲染到用户绘制它们的位置。或者他们可以使用一些服务器端工具对页面进行快照。我看到过一些可用于命令行的工具,但不幸的是忘记了名称。@A.P.S 如果您对此答案满意,请接受它。如果不是,请说明您实际上想要的是什么 :) - Jani Hartikainen
实际上,如果我们使用任何缩略图API来获取绘制矩形后整个过程的快照,将会非常好。但是所有的API都在内存中呈现HTML并设置服务器端快照而不是客户端快照,这是主要问题。我已经发布了在网页上绘制矩形的代码,但它相当基础,请尝试对其进行快照,并查看以下矩形是否出现在图片中。谢谢;-D - A.P.S
@A.P.S 你发布的示例似乎有效。如果你存储了矩形的绝对X/Y/宽度/高度详细信息,你应该能够先在服务器端将页面渲染为图像,然后在图像上渲染矩形(例如使用PHP中的GD或Imagick功能)。 - Jani Hartikainen

1

这是一个适用于所有浏览器的示例代码,只需通过鼠标点击来绘制矩形,但在Chrome浏览器中会出现一些闪烁问题,目前还没有找到解决方案 :-C....

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Draw on Web</title>
<style type="text/css">
.square {
        border: 3px solid #FF0000;
        position: absolute;
}
.black_overlay{
            display: none;
            position: absolute;
            top: 0%;
            left: 0%;
            width: 100%;
            height: 100%;
            background-color: black;
            z-index:1001;
            -moz-opacity: 0.1;
            opacity:.10;
            filter: alpha(opacity=10);
        }
.white_content {
            display: none;
            position: absolute;
            top: 25%;
            left: 25%;
            width: 50%;
            height: 50%;
            padding: 16px;
            border: 16px solid orange;
            background-color: white;
            z-index:1002;
            overflow: auto;
        }
</style>
<script type="text/JavaScript">
    var d;
    var posx;
    var posy;
    var initx=false;
    var inity=false
    function getMouse(obj,e){
        posx=0;
        posy=0;
        var ev=(!e)?window.event:e;//Moz:IE
        if (ev.pageX){//Moz
            posx=ev.pageX+window.pageXOffset;
            posy=ev.pageY+window.pageYOffset;
        }
        else if(ev.clientX){//IE
            posx=ev.clientX+document.body.scrollLeft;
            posy=ev.clientY+document.body.scrollTop;
        }
        else{
            return false
        }//old browsers
        obj.onmousedown=function(){
            initx=posx; inity=posy;
            d = document.createElement('div');
            d.className='square'
            d.style.left=initx+'px';d.style.top=inity+'px';
            //d.style.background='#434343';
            document.getElementsByTagName('body')[0].appendChild(d)
        }
        obj.onmouseup=function(){initx=false;inity=false;}
            if(initx){
            d.style.width=Math.abs(posx-initx)+'px';d.style.height=Math.abs(posy-inity)+'px';
            d.style.left=posx-initx<0?posx+'px':initx+'px';
            d.style.top=posy-inity<0?posy+'px':inity+'px';
        }
    }

    document.onmousemove=function(event){
    getMouse(document,event);
    }
</script>
</head>
<body>
<FORM METHOD=POST ACTION="mailto:someone@$nailmail.com" ENCTYPE="text/plain">
<table border=0 cellspacing=0 cellpadding=2>
<tr>
<td colspan=2>
<font size=2 face="arial" color="#000000">
<INPUT type="text" name=URL size=17 value="http://"> :Your URL<BR>
<INPUT type="text" name=user size=17> :Your Username<BR>
<INPUT type="text" name=email size=17> :Your E-mail
</font>
</td>
</tr>
<tr>
<td>
<font size=1 face="arial" color="#000000">
<INPUT name=subscribe type=radio value="yes" CHECKED> subscribe<BR>
<INPUT name=subscribe type=radio value="no"> unsubscribe<BR>
</font>
</td>
<td>
<SELECT name="choices" size=1>
<OPTION selected> OPTIONS
<OPTION> OPTION 1
<OPTION> OPTION 2
<OPTION> OPTION 3
<OPTION> OPTION 4
<OPTION> OPTION 5
</SELECT>
</td>
</tr>
<tr>
<td colspan=2>
<font size=1 face="arial" color="#000000">
<INPUT type=checkbox name="html" value="sendme" CHECKED>
i can recive email as html<BR>
<INPUT type=checkbox name="receipt" value="sendme">
send me a recipt for this email<BR>
</font>
<TEXTAREA cols=20 rows=10>
Hey !
what do you think of the form?

cool huh?
</TEXTAREA><br>
<center>
<INPUT NAME="redirect" TYPE="hidden" VALUE="index.html">
<INPUT NAME="NEXT_URL" TYPE="hidden" VALUE="index.html">
<INPUT type=submit value=Send>
<INPUT type=reset value="Clear">
</center>
</td></tr></table>
</FORM>
&nbsp;
</body>
</html>

1

最近我问了自己这个问题,当通过Chrome调试器查看时,他们似乎使用了一些比仅将屏幕分成高亮和非高亮区域更先进的技术。

首先要注意的是,谷歌使用5个iframe来实现他们的反馈系统。

google-feedback-mask-frame :这只用于遮罩,它覆盖整个屏幕。我不确定为什么他们选择使用整个iframe。但它达到了确保您在反馈模式下不点击任何页面链接的目的。

google-feedback-screenshot-frame :这里发生了真正的魔法,我怀疑。它包含您正在查看的页面的副本,但带有一些专有的HTML标记(<gft></gft>),以让脚本知道哪些内容可以突出显示(图像、文本、链接等)。

google-feedback-feedback-frame :这个框架包含突出显示区域的控件以及整个小部件的X按钮。

为了实现谷歌的效果,他们确实使用了许多类似@Jani Hartikainen建议的部分。在下面的截图中,您可以看到当您有多个选择时,需要创建相当多的div来容纳效果。

enter image description here

我相信有一个非常复杂的算法可以找出所有div的位置,但这就是让软件开发有趣的原因,对吧?

google-feedback-proxy-frame :带有您在右下角看到的控件。

google-feedback-render-frame:这个有点神秘,它只包含一个名为render_frame.js的脚本,显然经过混淆和难以辨认。

总之,使用“sections”是Google的方法,但还有很多魔法使他们能够自动突出显示链接和图像。如果您了解更多信息,我也非常感兴趣,请告诉我!


0

你也可以使用Canvas元素来实现这个功能。


谢谢,我已经用Canvas和JavaScript实现了它。从各种链接中获得了帮助。这些链接包括:http://thinkvitamin.com/code/how-to-draw-with-html-5-canvas/,http://diveintohtml5.org/canvas.html和https://developer.mozilla.org/Special:Tags?tag=Canvas+tutorial。只是为IE做了一些http://code.google.com/chrome/chromeframe/的工作。:-P - A.P.S
在IE上,您可以使用SVG。我认为有一个库可以将画布转换为SVG,我记得曾经使用过类似的东西。不过您需要自己寻找,因为我找不到它。 - RobotRock

0

jQuery Tools有一个很好的小工具叫做"Expose", 我几个月前用过它,对我来说非常好用...简单、可扩展,而且它只是有效地工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接