如何在绘制画布组件中添加鼠标事件
How to add mouse event in drawn canvas compoent
我想在画布上画200个或更多(高度流畅)的对象。
并添加鼠标悬停,鼠标点击事件。
源代码如下:
'
…
…对于(k = 0;k & lt;200;k + +) {Start = Start [k];
End = End [k];
y1 = centerY-radius*Math.cos(-arg*start)*0.9;
*Math.sin(-arg*start)*0.95;*Math.cos(-arg*start)*0.95;
= centerX-radius*Math.sin(-arg*end)*0.95;*Math.cos(-arg*end)*0.95;
*Math.sin(-arg*end)*0.9;
y = centerY-radius*Math.cos(-arg*end)*0.9;
Shape(ctx, x1,y1,x2,y2,x3,y3,x4,y4,k);
}
function Shape(ctx, x1,y1,x2,y2,x3,y3,x4,y4, k){
ctx.strokeStyle = "black";
ctx.fillStyle = "red";
ctx.globalAlpha = 1.0;
ctx.moveTo(x1,y1);
ctx.lineTo(x2,y2);
ctx.lineTo(x3,y3);
ctx.lineTo(x4,y4);
ctx.lineTo(x1,y1);
ctx.lineWidth = 0.5;
ctx.fill();
ctx.stroke();
ctx.fillText(k,(x2+x3)/2,(y2+y3)/2);
}
....
....
我希望……
如果鼠标停留在形状上,显示值k
如果鼠标点击shape,转到其他有k参数的url
但是,我不想使用image.
请帮帮我。
谢谢。
如果将形状的坐标保存在数组中,则可以循环遍历它们并检查是否与鼠标的坐标发生冲突。
画布像位图一样绘制。所有的更改都是对像素进行的,并且不会保留任何线或路径的痕迹。如果你想知道点击是在某个路径上还是在某个路径内,你就需要执行自己的命中测试。如果你画的形状可以相互重叠,你需要自己处理顺序。这是可行的,但你得靠自己。
另一种方法是使用SVG。因为SVG是对象,所以浏览器会为您跟踪它们。您可以像添加HTML元素一样将onclick
添加到SVG元素中。
最简单的解决方案就是使用像d3这样的库:http://d3js.org/
因为你的形状是不规则的,所以很难用数学方法进行命中测试。
幸运的是,上下文有isPointInPath
方法,该方法将测试提供的mouseX/mouseY是否在最后定义的路径内。
来测试你的不规则形状:
- 保留足够的信息来重新定义对象中的每个路径。
- 将每个形状对象添加到数组中。 在鼠标移动事件处理程序中…
- 遍历数组
- 重新定义每个形状(一次1个)。注:重定义是没有描边/填充的绘图。
- 使用
context.isPointInPath(mouseX,mouseY)
击中测试,如果鼠标是在最后定义的形状。
下面是示例代码和演示:http://jsfiddle.net/m1erickson/o5xp21t2/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var $canvas=$("#canvas");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
ctx.strokeStyle = "black";
ctx.fillStyle = "red";
ctx.globalAlpha = 1.0;
ctx.lineWidth = 0.5;
ctx.font="14px verdana";
var centerX=150;
var centerY=150;
var radius=120;
var arg=1;
var start=0;
var end=Math.PI/8;
var shapes=[];
for(var k=0;k<10;k++){
start+=Math.PI/8;
end+=Math.PI/8;
x1 = centerX-radius*Math.sin(-arg*start)*0.9;
y1 = centerY-radius*Math.cos(-arg*start)*0.9;
x2 = centerX-radius*Math.sin(-arg*start)*0.95;
y2 = centerY-radius*Math.cos(-arg*start)*0.95;
x3 = centerX-radius*Math.sin(-arg*end)*0.95;
y3 = centerY-radius*Math.cos(-arg*end)*0.95;
x4 = centerX-radius*Math.sin(-arg*end)*0.9;
y4 = centerY-radius*Math.cos(-arg*end)*0.9;
var s={x1:x1,y1:y1,x2:x2,y2:y2,x3:x3,y3:y3,x4:x4,y4:y4,k:k};
shapes.push(s);
Shape(s,k,true);
}
$results=$("#results");
$("#canvas").mousemove(function(e){handleMouseMove(e);});
function handleMouseMove(e){
e.preventDefault();
e.stopPropagation();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
for(var k=0;k<shapes.length;k++){
Shape(shapes[k],k,false);
if(ctx.isPointInPath(mouseX,mouseY)){
$results.text("Last mouseover: "+k);
}
}
}
function Shape(s, k, draw){
ctx.fillStyle="red";
ctx.beginPath();
ctx.moveTo(s.x1,s.y1);
ctx.lineTo(s.x2,s.y2);
ctx.lineTo(s.x3,s.y3);
ctx.lineTo(s.x4,s.y4);
ctx.lineTo(s.x1,s.y1);
if(draw){
ctx.fill();
ctx.stroke();
ctx.fillStyle="blue";
ctx.fillText(k,(s.x2+s.x3)/2,(s.y2+s.y3)/2);
}
}
}); // end $(function(){});
</script>
</head>
<body>
<p id=results>Hover mouse over shapes.</p>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
- 如何定义组件添加到DataItem的顺序
- React:向现有组件添加道具
- 向React中的高阶组件添加方法
- 在 React 中向组件添加新输入并跟踪状态
- Angular2 - 尝试将组件从父组件添加到子组件中
- extjs4 - 将自定义组件添加到容器
- 将react组件添加到contenteditable或innerhtml
- 反应多个组件添加项目
- 如何向 ReactJS 组件添加多个类
- 可以't将组件添加到dojox/layout/GridContainer
- KnockoutJs组件-添加默认类
- 如何使用React.js而不是JQuery.js克隆React组件(添加到其他地方)
- 向动态创建的组件添加事件绑定
- 如何在rteplugins下为richtext组件添加图像插件
- 为每个reactJS组件添加组件
- 如何向父窗口的组件添加字符
- React:如何给库中的组件添加一个props
- Highcharts提示?如何向hiccharts DOM组件添加类或id ?
- 用于向组件添加多个订阅的React mixin
- 如何在vue.js中为动态组件添加道具