如何选择HTML5画布形状?

时间:2012-01-18 04:36:59

标签: javascript html5 canvas html5-canvas

我有一个HTML5画布,我在其上绘制了几个形状。

我想要发生的是,当点击任何形状的鼠标时,应该选择形状(至少可以判断选择了哪种形状)。

谢谢。

3 个答案:

答案 0 :(得分:4)

尝试使用现有的画布库(或创建自己的)在选择形状时具有事件。

以下示例使用Kinetic JS library,以下示例来自HTML5 Canvas Region Events Example

var triangle = new Kinetic.Shape(function(){
    var context = this.getContext();
    context.beginPath();
    context.lineWidth = 4;
    context.strokeStyle = "black";
    context.fillStyle = "#00D2FF";
    context.moveTo(120, 50);
    context.lineTo(250, 80);
    context.lineTo(150, 170);
    context.closePath();
    context.fill();
    context.stroke();
});

triangle.on("mouseout", function(){
    writeMessage(messageLayer, "Mouseout triangle");
});

triangle.on("mousemove", function(){
    var mousePos = stage.getMousePosition();
    var x = mousePos.x - 120;
    var y = mousePos.y - 50;
    writeMessage(messageLayer, "x: " + x + ", y: " + y);
});

shapesLayer.add(triangle);

var circle = new Kinetic.Shape(function(){
    var canvas = this.getCanvas();
    var context = this.getContext();
    context.beginPath();
    context.arc(380, canvas.height / 2, 70, 0, Math.PI * 2, true);
    context.fillStyle = "red";
    context.fill();
    context.lineWidth = 4;
    context.stroke();
});

circle.on("mouseover", function(){
    writeMessage(messageLayer, "Mouseover circle");
});
circle.on("mouseout", function(){
    writeMessage(messageLayer, "Mouseout circle");
});
circle.on("mousedown", function(){
    writeMessage(messageLayer, "Mousedown circle");
});
circle.on("mouseup", function(){
    writeMessage(messageLayer, "Mouseup circle");
});

shapesLayer.add(circle);

stage.add(shapesLayer);
stage.add(messageLayer);


另外,如果光标在形状内,我已经包含了一些鼠标检测功能,而不使用任何javascript库。

基于矩形的鼠标检测:

function isCursorWithinRectangle(x, y, width, height, mouseX, mouseY) {
    if(mouseX > x && mouseX < x + width && mouseY > y && mouseY < y + height) {
        return true;
    }
    return false;
}


基于圆圈的鼠标检测:

function isCursorWithinCircle(x, y, r, mouseX, mouseY) {
    var distSqr = Math.pow(x - mouseX, 2) + Math.pow(y - mouseY, 2);

    if(distSqr < r * r) {
        return true;
    }
    return false;
}

答案 1 :(得分:2)

Canvas上没有元素的接口,就像DOM一样。它仅用于绘图。

您需要将资源创建为对象,并使用绘图循环来绘制它们。然后,您会忘记canvas元素,使用对象,偏移等等。

答案 2 :(得分:0)

选择具有像素精度的复杂形状非常简单,不涉及边界矩形或数学计算。

您的想法是将所有形状复制到隐藏的辅助画布上,在其中为每个形状指定唯一的颜色。在原始画布上执行鼠标悬停或单击事件时,将鼠标的(x,y)坐标相对于可见画布保存,然后使用相同的方法在隐藏的画布上查找像素颜色坐标。由于每个形状在隐藏画布上都具有唯一的颜色,因此该颜色对应于用户选择的确切形状。

请注意,这仅支持大约1670万个形状,因为RGB只有24位颜色,但这应该足够了。

这是一个使用D3和Canvas的简单示例:http://bl.ocks.org/syntagmatic/6645345