【发布时间】:2018-01-16 13:36:40
【问题描述】:
我有一个自定义代码可以在 HTML5 画布上创建和呈现对象。
class Rectangle extends Shape {
constructor(options, canvas, type = 'rectangle') {
super(...); // derived from super class
this._options = options;
this._canvas = canvas;
this._context = canvas.context2D;
this._type = type;
this._hovered = false;
this._dragged = false;
this.init();
this.canvas.canvas.onmousemove = (e) => {
this.onMouseHover(e);
};
this.canvas.canvas.onmousedown = (e) => {
this.onMouseDrag(e);
console.log('dragging');
}
this.canvas.canvas.onmouseup = (e) => {
this.onMouseRelease(e);
console.log('release');
}
}
static draw(options, canvas) {
return new Rectangle(options, canvas);
}
// Getter and setter
init() {
this.drawRectangle(...);
}
onMouseHover(e) {
if( // mouse is above of the shape position
e.clientX >= this.x &&
e.clientX <= this.x + this.width &&
e.clientY >= this.y &&
e.clientY <= this.y + this.height
) {
this.drawRectangle(...) // inverse the border color with background
this.canvas.canvas.style.cursor = 'pointer';
} else {
this.drawRectangle(...) // revert to original
this.canvas.canvas.style.cursor = 'default';
}
}
onMouseDrag(e) {
if( // mouse is above of the shape position
e.clientX >= this.x &&
e.clientX <= this.x + this.width &&
e.clientY >= this.y &&
e.clientY <= this.y + this.height &&
!this.isDragged
) {
this.canvas.canvas.onmousemove = (drag) => { // while dragging
this.eraseRectangle(...); // erase the rectangle
this.drawRectangle(...); // re-draw the rectangle while dragging
this.x = drag.clientX; // set the new x-axis value
this.y = drag.clientY; // set the new y-axis value
}
this.isDragged = true;
}
}
onMouseRelease(e) {
if(this.isDragged) {
this.isDragged = false;
this.canvas.canvas.onmousemove = (e) => { // reset it to the original
this.onMouseHover(e);
}
}
}
drawRectangle(width, height, x, y, fillStyle, strokeStyle) {
this.context.beginPath();
this.context.fillStyle = fillStyle;
this.context.strokeStyle = strokeStyle;
this.context.rect(x, y, width, height);
this.context.fill();
this.context.stroke();
}
eraseRectangle(width, height, x, y) {
this.context.beginPath();
this.context.clearRect(x-1, y-1, width+2, height+2);
}
}
在主类中。
class Main {
static ready() {
// Basic canvas options
const options = {
width: window.innerWidth,
height: window.innerHeight,
background: 'black'
}
// Create the canvas object
const canvas = HTMLCanvas.build('workspace', options);
const context = canvas.context2D;
const rect1 = Rectangle.draw({
width: 200,
height: 100,
x: 100,
y: 200,
border: 'blue',
background: 'white',
label: 'rect1'
}, canvas);
const rect2 = Rectangle.draw({
width: 300,
height: 75,
x: 200,
y: 400,
border: 'green',
background: 'white',
label: 'rect2'
}, canvas);
}
}
// Initialize the object
Main.ready();
使用上面的代码,我可以在画布上渲染一个矩形。但是,问题是一旦对象rect2 被拖动,我就无法再拖动对象rect1。
rect1 丢失其引用
我无法拖动或悬停rect1 对象,但我仍然可以悬停并拖动/释放rect2 对象。此外,当rect2 被拖到rect1 上时,rect2 会擦除rect1。
示例输出
我们如何跟踪每个 HTML5 画布对象的鼠标事件?大多数解决方案最终会迭代所有对象(将在画布中绘制)并将鼠标事件绑定到它。我希望它在对象本身中,而不是在工厂类中。
【问题讨论】:
-
鼠标输入问题的简单解决方案是为上下文本身设置一个处理程序,如果鼠标与其相交,它将手动调用矩形的处理程序之一
标签: javascript html canvas