Javascript 将onclick和onmouseover添加到canvas元素
我想向画布元素中的各个形状添加Javascript 将onclick和onmouseover添加到canvas元素,javascript,canvas,onclick,onmouseover,Javascript,Canvas,Onclick,Onmouseover,我想向画布元素中的各个形状添加onclick、onmouseover和onmouseout事件 我尝试过用不同的方式使用SVG,发现没有一种方法可以在所有主流浏览器中使用 也许,有没有一种简单的方法可以将onclick和其他事件添加到画布形状 有人能告诉我如何在单击时添加吗 这是我的代码: 画布 { 背景:gainsboro; 边框:10px脊绿色; } var c=document.getElementById(“Canvas1”); var ctx=c.getContext(“2d”)
onclick
、onmouseover
和onmouseout
事件
我尝试过用不同的方式使用SVG,发现没有一种方法可以在所有主流浏览器中使用
也许,有没有一种简单的方法可以将onclick
和其他事件添加到画布形状
有人能告诉我如何在单击时添加吗
这是我的代码:
画布
{
背景:gainsboro;
边框:10px脊绿色;
}
var c=document.getElementById(“Canvas1”);
var ctx=c.getContext(“2d”);
ctx.fillStyle=“蓝色”;
ctx.fillRect(10,10,60,60);
var ctx=c.getContext(“2d”);
ctx.fillStyle=“红色”;
ctx.fillRect(80,60,60,60);
//这些需要一次点击来激发它们。如何添加onclick
函数蓝()
{
警报(“蓝色广场你好”)
}
函数red()
{
警报(“红场你好”)
}
Canvas和SVG之间的主要区别在于,Canvas不保留绘制的形状的信息,只保留像素数组中的结果更改
因此,一个选项是通过鼠标单击处理程序中相应的像素颜色值来识别形状:
function onClick(event) {
var data = ctx.getImageData(event.x, event.y, 1, 1);
var red = data[0];
var green = data[1];
var blue = data[2];
var color = red << 16 | green << 8 | blue;
if (color == 0x0000ff) {
blue();
} else if (color == 0x0ff0000) {
red();
}
}
函数onClick(事件){
var data=ctx.getImageData(event.x,event.y,1,1);
var red=数据[0];
绿色变量=数据[1];
var blue=数据[2];
var color=red简而言之,您无法将侦听器添加到画布中的形状,因为形状没有作为对象公开。实现这一点最简单的方法是在画布上使用单个侦听器,并循环遍历画布中绘制的所有对象,以找到正确的侦听器
answer解释了如何使用Raphael库实现这一点,它还为您提供了许多其他好处
如果您不想使用库,这是一个非常简短的示例
rects = [{ color : "blue", origin : { x : 10, y : 10 }, size : { width : 60, height: 60}},
{ color : "red", origin : { x : 80, y : 60 }, size : { width : 60, height: 60}}]
function onClick(event) {
var length = rects.length;
for (var i = 0; i < length; ++i) {
var obj = rects[i];
if (event.x > obj.x && event.x < obj.origin.x + obj.size.width &&
event.y > obj.y && event.y < obj.origin.y + obj.size.height) {
console.log("Object clicked: " + obj);
}
}
rects=[{color:“blue”,原点:{x:10,y:10},大小:{width:60,height:60},
{颜色:“红色”,原点:{x:80,y:60},大小:{宽度:60,高度:60}]
函数onClick(事件){
var length=rects.length;
对于(变量i=0;iobj.x&&event.xobj.y&&event.y
注意:如果你有很多对象,这种方法可能会有点慢。这可以通过使用2D空间数据结构来解决。这里是一个用于向单个画布形状添加事件的基本框架
以下是预览:
与SVG不同,在画布上绘制形状后,无法识别该形状
在画布上,没有单独的形状,只有一个充满像素的画布
为了能够识别和“使用”任何单个画布形状,您需要记住该形状的所有基本属性
以下是标识矩形所需的属性:
- x位置
- y位置
- 宽度
- 高度
您还需要记住矩形的一些基本样式属性:
- fillcolor
- strokecolor
- 冲程宽度
因此,这里是如何创建一个矩形“类”对象,它可以记住它自己的所有基本属性
如果您不熟悉术语“类”,请将其视为我们可以用来定义形状的“饼干切割器”
然后我们可以使用“cookie cutter”类创建该形状的多个副本
更好的是…类足够灵活,可以让我们修改我们制作的每个副本的基本属性
对于矩形,我们可以使用我们的一个类来制作许多不同宽度、高度、颜色和位置的矩形
这里的关键是我们创建类,因为类非常灵活且可重用
下面是我们的rect类,它“记住”任何自定义矩形的所有基本信息
// the rect class
function rect(id,x,y,width,height,fill,stroke,strokewidth) {
this.x=x;
this.y=y;
this.id=id;
this.width=width;
this.height=height;
this.fill=fill||"gray";
this.stroke=stroke||"skyblue";
this.strokewidth=strokewidth||2;
}
我们可以重用这个类来创建我们需要的任意多的新矩形…我们可以为我们的新矩形指定不同的属性,以满足我们对多样性的需求
当您创建一个实际的矩形(通过填充它的属性)时,我们类的每个“cookie cutter”副本都有自己的私有属性集
当我们使用“cookie cutter”类创建1+个实际矩形以在画布上绘制时,生成的实际矩形称为“对象”
在这里,我们从1类中创建了3个真实的矩形对象。我们为每个真实对象指定了不同的宽度、高度和颜色
var myRedRect = new rect("Red-Rectangle",15,35,65,60,"red","black",3);
var myGreenRect = new rect("Green-Rectangle",115,55,50,50,"green","black",3);
var myBlueRect = new rect("Blue-Rectangle",215,95,25,20,"blue","black",3);
现在,让我们通过添加draw()函数使类能够在画布上绘制自身。这就是我们放置画布上下文绘制命令和样式命令的地方
rect.prototype.draw(){
ctx.save();
ctx.beginPath();
ctx.fillStyle=this.fill;
ctx.strokeStyle=this.stroke;
ctx.lineWidth=this.strokewidth;
ctx.rect(x,y,this.width,this.height);
ctx.stroke();
ctx.fill();
ctx.restore();
}
下面介绍如何使用draw()函数在画布上绘制矩形。请注意,我们有两个矩形对象,必须在这两个对象上执行.draw(),以便在画布上显示两个矩形
var myRedRect = new rect("Red-Rectangle",15,35,65,60,"red","black",3);
myRedRect.draw();
var myBlueRect = new rect("Blue-Rectangle",125,85,100,100,"blue","orange",3);
myBlueRect.draw();
现在让rect类能够让我们知道某个点(鼠标)是否在该rect内。当用户生成鼠标事件时,我们将使用isPointInside()函数测试鼠标当前是否在该rect内
// accept a point (mouseposition) and report if it’s inside the rect
rect.prototype.isPointInside = function(x,y){
return( x>=this.x
&& x<=this.x+this.width
&& y>=this.y
&& y<=this.y+this.height);
}
嗯……这就是你“记住”画布形状的方式&你是如何执行问题中的代码的
alert("hello from blue square")
这是一个简单的“类”,可以创建各种矩形和报告鼠标点击
您可以使用此模板作为起点来侦听各种画布形状上的所有鼠标事件
几乎所有画布形状都是矩形或圆形
矩形画布元素
- 长方形
- 形象
- 正文
- 行(是!)
圆形画布元素
- 圈
- 弧
- 正多边形(是!)
<
alert("hello from blue square")
// check for point inside a circlular shape
circle.prototype.isPointInside = function(x,y){
var dx = circleCenterX-x;
var dy = circleCenterY-y;
return( dx*dx+dy*dy <= circleRadius*circleRadius );
}
<!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 canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
//
var rect = (function () {
// constructor
function rect(id,x,y,width,height,fill,stroke,strokewidth) {
this.x=x;
this.y=y;
this.id=id;
this.width=width;
this.height=height;
this.fill=fill||"gray";
this.stroke=stroke||"skyblue";
this.strokewidth=strokewidth||2;
this.redraw(this.x,this.y);
return(this);
}
//
rect.prototype.redraw = function(x,y){
this.x=x;
this.y=y;
ctx.save();
ctx.beginPath();
ctx.fillStyle=this.fill;
ctx.strokeStyle=this.stroke;
ctx.lineWidth=this.strokewidth;
ctx.rect(x,y,this.width,this.height);
ctx.stroke();
ctx.fill();
ctx.restore();
return(this);
}
//
rect.prototype.isPointInside = function(x,y){
return( x>=this.x
&& x<=this.x+this.width
&& y>=this.y
&& y<=this.y+this.height);
}
return rect;
})();
//
function handleMouseDown(e){
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// Put your mousedown stuff here
var clicked="";
for(var i=0;i<rects.length;i++){
if(rects[i].isPointInside(mouseX,mouseY)){
clicked+=rects[i].id+" "
}
}
if(clicked.length>0){ alert("Clicked rectangles: "+clicked); }
}
//
var rects=[];
//
rects.push(new rect("Red-Rectangle",15,35,65,60,"red","black",3));
rects.push(new rect("Green-Rectangle",60,80,70,50,"green","black",6));
rects.push(new rect("Blue-Rectangle",125,25,10,10,"blue","black",3));
//
$("#canvas").click(handleMouseDown);
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
var path1 = new Path2D();
path1.rect(x1, y1, w, h); // add sub-path to Path2D object
var path2 = new Path2D();
path2.rect(x2, y2, w, h); // add sub-path to Path2D object
// now we can iterate through the objects to check which path we
// clicked without the need to rebuild each path as we did in the past
if (ctx.isPointInPath(path1, x, y)) { ... }
// define a region using path
ctx.beginPath();
ctx.rect(x, y, w, h);
ctx.addHitRegion({id: "test"});
// now we can check in the event if the region was hit by doing:
canvas.addEventListener("mousemove", function(event){
if(event.region) {
// a region was hit, id can be used (see specs for options)
}
});