我已经建立了一个分析性数据可视化的动画布,已要求增加工具提样悬停在数据元素显示的详细指标的数据点在光标。

为简单的条&Gaant图表,树形图和节点的地图有简单的方形的区域或具体问题的兴趣,我能够实现这个复盖绝对位于Div有:移的属性,但也有一些更复杂的形象化比如饼图和业务流程绘其中有数以百计的独立的区域定义bezeir曲线。

是是有可能以某种方式将复盖,或触发事件时的用户鼠在一个特定的关闭道路?

每个区域对其悬停,需要指定被定义如下:

context.beginPath();
context.moveTo(segmentRight, prevTop);
context.bezierCurveTo(segmentRight, prevTop, segmentLeft, thisTop, segmentLeft, thisTop);
context.lineTo(segmentLeft, thisBottom);
context.bezierCurveTo(segmentLeft, thisBottom, segmentRight, prevBottom, segmentRight, prevBottom);
/*
 * ...define additional segments...
 */
// <dream> Ideally I would like to attach to events on each path:
context.setMouseover(function(){/*Show hover content*/});
// </dream>
context.closePath();

结合到一个象这样的,几乎是琐碎的实施闪据,因为,但目前画布上的执行具有的优点的直接使用我们现有的Javascript API并将与其他阿贾克斯素,我们都希望避免把闪光成的混合。

任何想法?

有帮助吗?

解决方案

您可以处理mousemove事件,并获得X,Y从事件坐标。那么你可能不得不遍历所有的路径,以测试点是在路径。我有一个类似的问题可能有一些代码,你可以使用。

以这种方式循环执行的东西可能会很慢,特别是在IE。一种方法你可能加速这一过程 - 这是一个黑客,但它是非常有效 - 是改变每个路径绘制的颜色,使其不被人察觉,但让每个路径绘制不同的颜色。有一个表到颜色查找到路径和只是仰望的像素的颜色鼠标下。

其他提示

阴影的画布

最好的方法我已经看到其他地方的鼠标检测是要重复的一部分,你的绘画,你想要检测到一个隐藏的,清除了画布上。然后储存。对象。然后你可以检查。列素的兴趣,并回归真实的,如果阿尔法的价值大于0。

// slow part
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.fillRect(100,100,canvas.width-100,canvas.height-100);
var pixels = ctx.getImageData(0,0,canvas.width,canvas.height).data;

// fast part
var idx = 4 * (mouse_x + mouse_y * canvas.width) + 3;
if (pixels[idx]) { // alpha > 0
  ...
}

优点

  • 你可以检测任何你想要的因为你只是重复方面的方法。这适用PNG阿尔法,疯狂的化合物的形状、文本等。
  • 如果你的形象是相当静态的,然后你只需要做这一个次区域的利益。
  • "面具"是缓慢的,但看起来像素是便宜。因此,"快速的一部分"是伟大鼠标检测。

缺点

  • 这是一个存储器猪。每个掩W*H*4的价值观。如果你有一个小的画布区域或少数几个领域以掩盖,它不是那么糟糕。使用的铬的任务经理的监测存储器的使用。
  • 目前已知的问题则getimagedata在铬和Firefox。结果不是垃圾回收的时候了,如果你抵消的可变的,所以,如果你这样做太过频繁,你会看到存迅速上升。它并最终得到垃圾收集和它不应该崩溃的浏览器,但它可以征税的计算机上的小额RAM。

一个黑客保存记忆

而不是储存的整体。阵,我们只是可以记住这素有阿尔法的价值。它可以节省大量的存储器,但增加了一个循环的掩过程。

var mask = {};
var len = pixels.length;
for (var i=3;i<len;i+=4) if ( pixels[i] ) mask[i] = 1;

// this works the same way as the other method
var idx = 4 * (mouse_x + mouse_y * canvas.width) + 3;
if (mask[idx]) {
  ...
}

此可以使用该方法ctx.isPointInPath进行,但它不是在ExCanvas用于IE实现。 但另一种解决方案是使用HTML地图,像我一样为这个小库: HTTP ://phenxdesign.net/projects/phenx-web/graphics/example.htm 你可以从它那里得到灵感,但它仍然是一个小马车

我建议用叠加的区域设置为匹配您的画布绘制的项目适当的坐标图像映射。这样一来,你会得到提示和很多其他DOM /浏览器的功能是免费的。

我需要做的检测鼠标点击用于正方形格子(像Excel电子表格的细胞)。以加快其速度,我划分网格成区域递归减半,直到细胞的小数量保持,例如用于一个100×100的网格,所述第一4个区域可以是包括四个象限的50×50网格。 然后这些可分为另一个4各自(因此给出的每个25×25 16个区域)。 这需要一个小数目的比较和最后的25×25网格可以为每个小区(在本例中625个比较)进行测试。

有一本书由埃里克·罗威尔命名为“HTML5画布菜谱”。在那本书中有一个名为“与画布交互:连接事件监听器形状和地区”一章。鼠标按下,鼠标松开,鼠标悬停,鼠标移开,鼠标移动,touchstart,touchend和touchmove事件可以实现。我强烈建议你看的。

此不能做(好,至少不是容易),因为对象你画布(路径)上绘制不表示为画布中的相同对象。我的意思是,这只是一个简单的2D背景的,一旦你在上面画的东西,它完全忘记它是如何绘制。这仅仅是一组像素它。

为了观看鼠标悬停和它喜欢,你需要某种形式的矢量图形的画布,即SVG或实现自己的现有的(这是萨姆·哈斯勒建议)的顶部

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top