将onclick和onmouseover添加到canvas元素 [英] Add onclick and onmouseover to canvas element

查看:1042
本文介绍了将onclick和onmouseover添加到canvas元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想添加 onclick onmouseover onmouseout 事件到canvas元素中的各个形状。



我已经尝试用不同的方式这样做与SVG,并发现没有一个方法将在所有主要的浏览器。



也许,有一个简单的方法可以将 onclick 和其他事件添加到画布形状?



有人可以告诉我如何添加 onclick



这是我的代码:

 canvas 
{
background:gainsboro;
border:10px ridge green;
}



  < canvas id =Canvas1>< / canvas> 



  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);

//这些需要一个onclick来激活它们。如何添加onclick
函数blue()
{
alert(hello from blue square)
}

function red b $ b {
alert(hello from red square)
}


>



这里是一个预览:

a href =http://jsfiddle.net/m1erickson/sAFku/> http://jsfiddle.net/m1erickson/sAFku/



与SVG,你画一个形状到画布后,没有办法识别这个形状。



在画布上,没有单独的形状,只有一个充满像素的画布。



能够识别和使用任何单独的画布形状,你需要记住那个形状的所有基本属性。



以下是识别矩形所需的属性:




  • x-position ,

  • y位置,

  • 宽度,



您还要记住矩形的一些基本样式属性:




  • fillcolor,




这里是如何创建一个矩形类对象,它记住了它自己的基本属性。



如果你不熟悉术语类 ,认为它是一个cookie-cutter,我们可以用它来定义一个形状。



然后我们可以使用cookie-cutter类创建多个副本的形状。



更好 ...类非常灵活,可以让我们修改每个副本的基本属性。



对于矩形,我们可以使用我们的一个类来制作许多不同宽度,高度,颜色和位置的矩形。



这里的关键是我们创建类,因为类非常灵活,可重用!



这里是我们的rect类,记住任何自定义矩形的所有基本信息。

  // rect类

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 ||grey;
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()函数在画布上绘制自己的能力。这是我们放置canvas上下文绘制命令和样式命令的地方。

  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类能够让我们知道一个点。当用户生成鼠标事件时,我们将使用此isPointInside()函数来测试鼠标当前是否在我们的rect内。

  //接受点(mouseposition)并报告它是否在rect内

rect.prototype .isPointInside = function(x,y){
return(x> = this.x
&& x< = this.x + this.width
& y> = this.y
&& y< = this.y + this.height);
}



最后,我们可以将rect类绑定到正常的浏览器鼠标事件系统中。



我们要求jQuery在画布上监听鼠标点击。然后我们把鼠标位置喂给rect对象。

  //监听点击事件和触发器handleMouseDown 
$(#canvas)。click(handleMouseDown);

//计算mouseclick位置并测试它是否在rect内
函数handleMouseDown(e){

//计算鼠标点击位置
mouseX = parseInt(e.clientX-offsetX);
mouseY = parseInt(e.clientY-offsetY);

//测试myRedRect以查看点击是否在
内if(myRedRect.isPointInside(mouseX,mouseY)){

// we(finally!)让你执行你的代码!
alert(Hello from the+ myRedRect.id);
}
}

//这些是用于handleMouseDown(或任何mouseevent处理程序)的画布偏移
var canvasOffset = $(#canvas)。offset ();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;

好吧,这就是你记住帆布形状&如何执行您的问题中的代码!

  alert(hello from blue square)

这是一个准系统类,创建各种矩形和报告mouseclicks。



您可以使用此模板作为起点,监听所有类型画布形状的所有鼠标事件。



几乎所有的画布形状都是矩形或圆形。



矩形画布元素




  • 矩形

  • 图片

  • 文字

  • Line(yes!)



圆形画布元素




  • 圈子


  • 正多边形(是!)



不规则帆布元素




  • 曲线(Cubic& Quad Beziers)

  • Path



isPointInside()看起来像一个圆形:

  //检查圆形内的点
circle.prototype.isPointInside = function(x,y){
var dx = circleCenterX-x;
var dy = circleCenterY-y;
return(dx * dx + dy * dy <= circleRadius * circleRadius);
}

即使不规则形状的画布元素也可以有isPointInside, / p>

就是这样!



这里是略微增强的代码和小提琴: http://jsfiddle.net / m1erickson / sAFku /

 <!doctype html& 
< html>
< head>
< link rel =stylesheettype =text / cssmedia =allhref =css / reset.css/> <! - reset css - >
< script type =text / javascriptsrc =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 ||grey;
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);

//把你的mousedown东西放在这里
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 =canvaswidth = 300 height = 300>< / canvas>
< / body>
< / html>


I want to add an onclick, onmouseover and an onmouseout events to individual shapes in a canvas element.

I have tried doing this with SVG in different ways and found no single method will work in all the major browsers.

Maybe, is there a simple way to add an onclick and probably other events to canvas shapes?

Can someone please show me how to add an onclick?

Here is my code:

canvas
{
  background:gainsboro;
  border:10px ridge green;
}

<canvas id="Canvas1"></canvas>

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")
}

解决方案

Here is a barebones framework for adding events to individual canvas shapes

Here's a preview: http://jsfiddle.net/m1erickson/sAFku/

Unlike SVG, after you draw a shape to canvas, there is no way to identify that shape.

On canvas, there are no individual shapes, there is just a canvas full of pixels.

To be able to identity and "use" any individual canvas shape, you need to remember all basic properties of that shape.

Here are the properties necessary to identify a rectangle:

  • x-position,
  • y-position,
  • width,
  • height.

You will also want to remember some basic styling properties of a rectangle:

  • fillcolor,
  • strokecolor,
  • strokewidth.

So here is how to create a rectangle "class" object that remembers all of it’s own basic properties.

If you're not familiar with the term "class", think of it as a "cookie-cutter" that we can use to define a shape.

Then we can use the "cookie-cutter" class to create multiple copies of that shape.

Even better ... classes are flexible enough to let us modify the basic properties of each copy that we make.

For rectangles, we can use our one class to make many, many rectangles of different widths, heights, colors and locations.

The key here is that we create classes because classes are Very Flexible and Reusable!

Here is our rect class that "remembers" all the basic info about any custom rectangle.

// 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;
}

We can reuse this class to create as many new rectangles as we need...And we can assign different properties to our new rectangles to meet our needs for variety.

When you create an actual rectangle (by filling in it's properties), every "cookie-cutter" copy of our class has its own private set of properties.

When we use a "cookie-cutter" class to create 1+ actual rectangles to draw on the canvas, the resulting real rectangles are called "objects".

Here we create 3 real rectangle objects from our 1 class. We have assigned each real object different width, height and colors.

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);

Now let’s give our class the ability to draw itself on the canvas by adding a draw() function. This is where we put the canvas context drawing commands and styling commands.

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();
}

Here’s how to use the draw() function to draw rectangles on the canvas. Notice that we have 2 rectangle objects and we must execute .draw() on both of them for 2 rects to show on the canvas.

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();

Now give the rect class the ability to let us know if a point (mouse) is inside that rect. When the user generates mouse events, we will use this isPointInside() function to test if the mouse is currently inside our 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);
}

Finally we can tie our rect class into the normal browser mouse event system.

We ask jQuery to listen for mouse clicks on the canvas. Then we feed that mouse position to the rect object. We use the rect's isPointInside() to report back if the click was inside the 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;

Well...that's how you "remember" canvas shapes & how you execute the code in your question!

alert("hello from blue square")

That’s a barebones "class" that creates various rectangles and reports mouseclicks.

You can use this template as a starting point to listen for all mouse-events on all kinds of canvas shapes.

Almost all canvas shapes are either rectangular or circular.

Rectangular Canvas Elements

  • Rectangle
  • Image
  • Text
  • Line (yes!)

Circular Canvas Elements

  • Circle
  • Arc
  • Regular Polygon (yes!)

Irregular Canvas Elements

  • Curves (Cubic & Quad Beziers)
  • Path

The isPointInside() would look like this for a circle:

// 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 );
}

Even irregularly shaped canvas elements can have isPointInside, but that usually gets complicated!

That’s it!

Here is slightly enhanced code and a Fiddle: 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>

这篇关于将onclick和onmouseover添加到canvas元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆