Canvas事件处理教程,掌握鼠标、触摸、键盘等交互事件的处理方法。事件处理是Canvas交互的核心,通过监听和响应各种用户输入事件,实现丰富的交互体验。
事件处理是指监听用户的输入操作(鼠标、触摸、键盘等),并做出相应响应的过程。
| 特点 | 说明 |
|---|---|
| 单一元素 | Canvas本身是一个DOM元素 |
| 内部检测 | 需要自己检测点击了哪个图形 |
| 无内置事件 | 图形没有内置的事件系统 |
| 手动管理 | 需要手动管理交互状态 |
canvas.addEventListener('click', (e) => {
console.log('点击位置:', e.offsetX, e.offsetY)
})
canvas.addEventListener('mousemove', (e) => {
console.log('鼠标移动:', e.offsetX, e.offsetY)
})
canvas.addEventListener('mousedown', (e) => {
console.log('鼠标按下, 按钮:', e.button)
})
canvas.addEventListener('mouseup', (e) => {
console.log('鼠标释放')
})
canvas.addEventListener('touchstart', (e) => {
e.preventDefault()
const touch = e.touches[0]
const rect = canvas.getBoundingClientRect()
console.log('触摸开始:', touch.clientX - rect.left, touch.clientY - rect.top)
})
canvas.addEventListener('touchmove', (e) => {
e.preventDefault()
const touch = e.touches[0]
console.log('触摸移动')
})
canvas.addEventListener('touchend', (e) => {
console.log('触摸结束')
})
document.addEventListener('keydown', (e) => {
console.log('按键:', e.key, 'keyCode:', e.keyCode)
})
document.addEventListener('keyup', (e) => {
console.log('按键释放:', e.key)
})
class EventHandler {
constructor(canvas) {
this.canvas = canvas
this.shapes = []
this.hoveredShape = null
this.draggingShape = null
this.bindEvents()
}
bindEvents() {
this.canvas.addEventListener('mousemove', this.onMouseMove.bind(this))
this.canvas.addEventListener('mousedown', this.onMouseDown.bind(this))
this.canvas.addEventListener('mouseup', this.onMouseUp.bind(this))
this.canvas.addEventListener('click', this.onClick.bind(this))
}
getMousePos(e) {
const rect = this.canvas.getBoundingClientRect()
return {
x: e.clientX - rect.left,
y: e.clientY - rect.top
}
}
findShapeAt(x, y) {
for (let i = this.shapes.length - 1; i >= 0; i--) {
if (this.shapes[i].containsPoint(x, y)) {
return this.shapes[i]
}
}
return null
}
onMouseMove(e) {
const pos = this.getMousePos(e)
const shape = this.findShapeAt(pos.x, pos.y)
if (shape !== this.hoveredShape) {
if (this.hoveredShape) {
this.hoveredShape.onMouseLeave()
}
this.hoveredShape = shape
if (shape) {
shape.onMouseEnter()
}
}
if (this.draggingShape) {
this.draggingShape.onDrag(pos.x, pos.y)
}
}
onMouseDown(e) {
const pos = this.getMousePos(e)
const shape = this.findShapeAt(pos.x, pos.y)
if (shape) {
this.draggingShape = shape
shape.onMouseDown(pos.x, pos.y)
}
}
onMouseUp(e) {
if (this.draggingShape) {
const pos = this.getMousePos(e)
this.draggingShape.onMouseUp(pos.x, pos.y)
this.draggingShape = null
}
}
onClick(e) {
const pos = this.getMousePos(e)
const shape = this.findShapeAt(pos.x, pos.y)
if (shape) {
shape.onClick(pos.x, pos.y)
}
}
}
本章节包含以下内容:
理解事件模型
了解DOM事件模型和Canvas的事件处理特点。
坐标转换
掌握屏幕坐标到Canvas坐标的转换方法。
性能考虑
事件处理要高效,避免不必要的重绘。
兼容性
考虑不同设备的输入方式(鼠标、触摸、手柄等)。