简体   繁体   English

如何选择HTML5画布形状?

[英]How to select HTML5 canvas shapes?

I have a HTML5 canvas on which I have drawn several shapes. 我有一个HTML5画布,上面已绘制了几种形状。

What I want to happen, is that when the mouse is clicked on any shape the shape should get selected (at least it can tell what kind of shape is selected). 我想发生的是,当在任何形状上单击鼠标时,都应该选择该形状(至少它可以告诉您选择了哪种形状)。

Thank you. 谢谢。

Try using an existing canvas library (or create your own) that has an event when a shape is being selected. 尝试使用现有的画布库(或创建自己的画布库),该库在选择形状时会发生事件。

The example below uses the Kinetic JS library , and the example below is from HTML5 Canvas Region Events Example : 下面的示例使用Kinetic JS库 ,下面的示例来自HTML5 Canvas Region Events示例

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


In addition, I have included some mouse-in detection if the cursor is within the shape, without using any javascript libraries. 此外,如果光标不在形状内,我还进行了一些鼠标插入检测,没有使用任何JavaScript库。

Rectangular-based mouse-in detection: 基于矩形的鼠标插入检测:

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


Circle-based mouse-in detection: 基于圆的鼠标插入检测:

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

Canvas does not have an interface for the elements on it like the DOM. Canvas没有像DOM这样的元素接口。 It is solely used for drawing. 它仅用于绘图。

You need to create your assets as objects and use a drawing loop to paint them. 您需要将资产创建为对象,并使用绘制循环对其进行绘制。 You then forget about the canvas element, you work with your objects, with their offsets, etc. 然后,您会忘记canvas元素,使用对象,其偏移量等。

There's a very simple way to select complex shapes with pixel precision that doesn't involve bounding rectangles or math calculations. 有一种非常简单的方法来选择像素精度的复杂形状,而不涉及矩形的边界或数学计算。

The idea is that you duplicate all of your shapes onto a hidden secondary canvas, where you assign each shape a unique color. 想法是将所有形状复制到隐藏的辅助画布上,在其中为每个形状分配唯一的颜色。 When you perform a mouseover or click event on the original canvas, you save the mouse's (x, y) coordinates in relation to the visible canvas, and then you look-up the pixel color on your hidden canvas using those same coordinates. 在原始画布上执行鼠标悬停或单击事件时,将鼠标的(x,y)坐标相对于可见画布保存,然后使用相同的坐标在隐藏的画布上查找像素颜色。 Because each shape has a unique color on the hidden canvas, that color corresponds to the exact shape that the user selected. 因为每个形状在隐藏的画布上都有唯一的颜色,所以该颜色与用户选择的确切形状相对应。

Note that this only supports up to roughly 16.7 million shapes because RGB only has 24 bits of color, but that should be more than enough. 请注意,这仅支持大约1670万种形状,因为RGB仅具有24位颜色,但这应该绰绰有余。

Here's a simple example using D3 and Canvas: http://bl.ocks.org/syntagmatic/6645345 这是一个使用D3和Canvas的简单示例: http : //bl.ocks.org/syntagmatic/6645345

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM