1. 鼠标事件
鼠标事件分为3种:鼠标按下
mousedown
、鼠标松开mouseup
、鼠标移动mousemove
获取鼠标指针位置
我们可以通过 pageX与pageY这两个属性来确定鼠标指针当前位置,然后再结合画布相对于文档的偏移距离,我们就可以确定鼠标在画布中的相对坐标。
<canvas id="myCanvas" width="500" height="200"></canvas>
<div id="text"></div>
<div id="text1"></div>
<div id="text2"></div>
//获取鼠标指针位置
getMouse(element) {
let mouse = { x: 0, y: 0 } // 存储鼠标位置信息
element.addEventListener('mousemove', e => {
let x = e.pageX
let y = e.pageY
// 计算鼠标在canvas画布中的相对位置
mouse.x = x - element.offsetLeft
mouse.y = y - element.offsetTop
})
return mouse
},
//绘制
init() {
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
var isDragging = false
var startX, startY, offsetX, offsetY
var rect = { x: 50, y: 50, width: 100, height: 100 }
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.fillRect(rect.x, rect.y, rect.width, rect.height)
}
// 鼠标移动 mousemove
var mouse = this.getMouse(canvas)
canvas.addEventListener('mousemove', event => {
document.getElementById('text').innerHTML = `鼠标坐标为:${mouse.x}, ${mouse.y}`
if (isDragging) {
var x = event.offsetX
var y = event.offsetY
rect.x = x + offsetX
rect.y = y + offsetY
draw()
}
})
// 鼠标按下 mousedown
canvas.addEventListener('mousedown', event => {
document.getElementById('text1').innerHTML = `鼠标坐标为:${mouse.x}, ${mouse.y}`
var x = event.offsetX
var y = event.offsetY
if (x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y + rect.height) {
isDragging = true
startX = x
startY = y
offsetX = rect.x - startX
offsetY = rect.y - startY
}
})
// 鼠标松开 mouseup
canvas.addEventListener('mouseup', () => {
document.getElementById('text2').innerHTML = `鼠标坐标为:${mouse.x}, ${mouse.y}`
isDragging = false
})
},
2. 键盘事件
在Canvas开发中,常用的键盘事件有两个:
- 键盘按下 keydown
- 键盘松开 keyup
因为Canvas本身无法绑定键盘事件,所以实际开发中我们是监听window键盘事件来实现的。
//type为字符串类型,指的是事件类型。
window.addEventListener(type, fn, false)
在javaScript中,我们使用keyCode来判断用户按下了哪个键,在这里我们只列出Canvas开发中常用的几个keyCode。
按键 | keyCode | ||
---|---|---|---|
W | 87 | ↑ | 38 |
S | 83 | ↓ | 40 |
A | 65 | ← | 37 |
D | 68 | → | 39 |
// 键盘事件
getKey() {
//封装键盘事件方法
// window.addEventListener(type, fn, false)
let key = {}
window.addEventListener(
'keydown',
e => {
if (e.keyCode === 38 || e.keyCode === 87) {
key['direction'] = 'up'
} else if (e.keyCode === 39 || e.keyCode === 68) {
key['direction'] = 'right'
} else if (e.keyCode === 40 || e.keyCode === 83) {
key['direction'] = 'down'
} else if (e.keyCode === 37 || e.keyCode === 65) {
key['direction'] = 'left'
} else {
key['direction'] = null
}
},
false
)
return key
},
// 键盘按下 keydown // 键盘松开 keyup
init1() {
var canvas = document.getElementById('myCanvas1')
var ctx = canvas.getContext('2d')
// 绘制小球
const drawBall = (x, y, ctx) => {
ctx.beginPath()
ctx.arc(x, y, 20, 0, (360 * Math.PI) / 180, true)
ctx.closePath()
ctx.fillStyle = 'blue'
ctx.fill()
}
// 初始化小球
let x = 20
let y = 20
drawBall(x, y, ctx)
// 获取按键方向
const key = this.getKey()
window.addEventListener(
'keydown',
e => {
// 每次绘制前清空画布
ctx.clearRect(0, 0, canvas.width, canvas.height)
// 根据事件重绘小球
switch (key['direction']) {
case 'up':
y -= 2
break
case 'down':
y += 2
break
case 'left':
x -= 2
break
case 'right':
x += 2
break
default:
break
}
drawBall(x, y, ctx)
},
false
)
},
3. 循环事件
在Canvas中,我们使用
requestAnimationFrame()
来实现循环, 确保绘制帧率。
盯着看一会,会出现一个正五边形哦
// 循环事件
init2() {
var canvas = document.getElementById('myCanvas2')
var ctx = canvas.getContext('2d')
let angle = 0
const amplitude = 50 // 振幅,控制曲线的弯曲程度
const frequency = 0.02 // 频率,控制曲线的周期
const speed = 10 // 速度,控制矩形移动的快慢
;(function frame() {
window.requestAnimationFrame(frame)
// 清除整个画布
ctx.clearRect(0, 0, canvas.width, canvas.height)
// 计算新位置
const x = canvas.width / 2 + Math.sin(angle) * amplitude
const y = canvas.height / 2 + Math.cos(angle) * amplitude
// 绘制矩形
ctx.beginPath()
ctx.arc(x - 25, y, 25, 25, (360 * Math.PI) / 180, true)
ctx.fill()
// 更新角度以改变矩形的位置
angle += speed
// 当矩形到达边界时,改变方向
if (x <= 0 || x >= canvas.width) {
speed = -speed
}
})()
}
到此canvas进阶事件及动画学习结束,道阻且长,行则将至。与诸君共勉。 ⭐️