javascript 如何选择 HTML5 画布形状?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8905247/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to select HTML5 canvas shapes?
提问by me_digvijay
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.
谢谢你。
回答by auroranil
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 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);
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;
}
回答by alex
Canvas does not have an interface for the elementson it like the DOM. It is solely used for drawing.
Canvas 没有像 DOM 那样的元素接口。它仅用于绘图。
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
元素,你使用你的对象,使用它们的偏移量等。
回答by geofflee
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. Because each shape has a unique color on the hidden canvas, that color corresponds to the exact shape that the user selected.
这个想法是你将所有的形状复制到一个隐藏的辅助画布上,在那里你为每个形状分配一个独特的颜色。当您在原始画布上执行鼠标悬停或单击事件时,您会保存鼠标相对于可见画布的 (x, y) 坐标,然后使用这些相同的坐标在隐藏的画布上查找像素颜色。因为每个形状在隐藏画布上都有独特的颜色,所以该颜色对应于用户选择的确切形状。
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