Mr *_*SVG 11 javascript canvas onclick onmouseover
我想补充的onclick,onmouseover以及onmouseout在canvas元素事件单个形状.
我尝试过以不同的方式使用SVG,并发现没有一种方法可以在所有主流浏览器中使用.
也许,有没有一种简单的方法可以onclick为画布形状添加一个可能的其他事件?
有人可以告诉我如何添加onclick?
这是我的代码:
canvas
{
background:gainsboro;
border:10px ridge green;
}
Run Code Online (Sandbox Code Playgroud)
<canvas id="Canvas1"></canvas>
Run Code Online (Sandbox Code Playgroud)
var c=document.getElementById("Canvas1");
var ctx=c.getContext("2d");
ctx.fillStyle="blue";
ctx.fillRect(10,10,60,60);
var ctx=c.getContext("2d");
ctx.fillStyle="red";
ctx.fillRect(80,60,60,60);
// these need an onclick to fire them up. How do I add the onclick
function blue()
{
alert("hello from blue square")
}
function red()
{
alert("hello from red square")
}
Run Code Online (Sandbox Code Playgroud)
mar*_*rkE 21
这是一个用于向各个画布形状添加事件的准系统框架
这是一个预览:http: //jsfiddle.net/m1erickson/sAFku/
与SVG不同,在将形状绘制到画布后,无法识别该形状.
在画布上,没有单独的形状,只有一个装满像素的画布.
为了能够识别和"使用"任何单个画布形状,您需要记住该形状的所有基本属性.
以下是标识矩形所需的属性:
您还需要记住矩形的一些基本样式属性:
所以这里是如何创建一个矩形"类"对象,它记住它自己的所有基本属性.
如果您不熟悉术语"类",请将其视为我们可以用来定义形状的"千篇一律".
然后我们可以使用"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;
}
Run Code Online (Sandbox Code Playgroud)
我们可以重用这个类来创建我们需要的新矩形......我们可以为新的矩形分配不同的属性,以满足我们对变化的需求.
当您创建一个实际的矩形(通过填写它的属性)时,我们类的每个"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);
Run Code Online (Sandbox Code Playgroud)
现在让我们的类通过添加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();
}
Run Code Online (Sandbox Code Playgroud)
以下是如何使用draw()函数在画布上绘制矩形.请注意,我们有2个矩形对象,我们必须在它们两个上执行.draw(),以便在画布上显示2个rects.
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();
Run Code Online (Sandbox Code Playgroud)
现在让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);
}
Run Code Online (Sandbox Code Playgroud)
最后,我们可以将rect类绑定到普通的浏览器鼠标事件系统中.
我们要求jQuery在画布上监听鼠标点击.然后我们将该鼠标位置提供给rect对象.我们使用rect的isPointInside()来报告单击是否在rect内.
// listen for click events and trigger handleMouseDown
$("#canvas").click(handleMouseDown);
// calc the mouseclick position and test if it's inside the rect
function handleMouseDown(e){
// calculate the mouse click position
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// test myRedRect to see if the click was inside
if(myRedRect.isPointInside(mouseX,mouseY)){
// we (finally!) get to execute your code!
alert("Hello from the "+myRedRect.id);
}
}
// These are the canvas offsets used in handleMouseDown (or any mouseevent handler)
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
Run Code Online (Sandbox Code Playgroud)
嗯......这就是你如何"记住"画布形状以及如何在你的问题中执行代码!
alert("hello from blue square")
Run Code Online (Sandbox Code Playgroud)
这是一个准确创建各种矩形并报告鼠标点击的准系统"类".
您可以使用此模板作为起点来侦听各种画布形状上的所有鼠标事件.
几乎所有的帆布形状都是矩形或圆形.
矩形画布元素
圆形画布元素
不规则的画布元素
isPointInside()对于圆圈看起来像这样:
// 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 );
}
Run Code Online (Sandbox Code Playgroud)
即使形状不规则的画布元素也可以有isPointInside,但这通常会变得复杂!
而已!
这是稍微增强的代码和小提琴:http: //jsfiddle.net/m1erickson/sAFku/
<!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>
Run Code Online (Sandbox Code Playgroud)
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();
}
}
Run Code Online (Sandbox Code Playgroud)
如果您想使用此方法跟踪具有相同颜色的多个对象的点击,则需要稍微更改每个形状的颜色以使其可跟踪。
当您从不同的主机添加图像时,此方法将不起作用,因为在这种情况下,同源策略将阻止 getImageData。
| 归档时间: |
|
| 查看次数: |
21498 次 |
| 最近记录: |