Canvas进阶篇:鼠标交互动画
- 前言
- 获取鼠标坐标
- 鼠标事件
- 点击事件监听
- 代码示例
- 效果预览
- 拖动事件监听
- 代码示例
- 效果预览
- 结语
前言
在上一篇文章Canvas进阶篇:基本动画详解 中,我们讲述了在Canvas中实现动画的基本步骤和动画的绘制方法。本文将进一步讲述如何通过鼠标事件增加动画和用户的交互,包括捕获鼠标的点击和拖动事件,获取鼠标在 Canvas 中坐标等。
获取鼠标坐标
在进行鼠标交互时,最主要的是要获取鼠标在Canvas中画布中的坐标。通常我们获取到的鼠标坐标都是相对于浏览器窗口的;如果想要获取相对于 Canvas 画布的坐标,就需要进行坐标转换,可以通过以下方式实现:
function getCanvasCoordinates(event) {
const rect = canvas.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
return { x, y };
}
上述代码中,canvas.getBoundingClientRect()
方法返回 Canvas 在浏览器窗口中的位置和尺寸信息,通过用鼠标相对于窗口的坐标减去 Canvas 左上角相对于窗口的坐标,就得到了鼠标在 Canvas 中的坐标。
鼠标事件
鼠标事件一共分为4类:鼠标点击事件click
、鼠标按下事件mousedown
、鼠标移动事件mousemove
和鼠标松开事件mouseup
。
点击事件监听
利用点击事件,我们可以在鼠标点击的位置绘制各种图形,比如圆形等,示例代码如下:
代码示例
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>鼠标点击画圆</title>
<style>
#canvas {
border: 1px solid #000;
}
</style>
</head>
<body>
<canvas id="canvas" width="600" height="600"></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
function getCanvasCoordinates(event) {
const rect = canvas.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
return { x, y };
}
function handleClick(event) {
const {
x,
y
} = getCanvasCoordinates(event);
ctx.beginPath();
ctx.arc(x, y, 20, 0, 2 * Math.PI);
ctx.fillStyle = 'red';
ctx.fill();
}
// 绑定鼠标点击事件
canvas.addEventListener('click', handleClick);
</script>
</body>
</html>
效果预览
拖动事件监听
实现拖动元素的功能,需要结合mousedown
、mousemove
和mouseup
三个事件,我们以拖动一个矩形为例:
代码示例
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>鼠标拖动矩形</title>
<style>
#canvas {
border: 1px solid #000;
}
</style>
</head>
<body>
<canvas id="canvas" width="600" height="600"></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
function getCanvasCoordinates(event) {
const rect = canvas.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
return {
x,
y
};
}
// 矩形数组
let rectangles = [];
// 拖拽状态
let isDragging = false;
let startX, startY;
let offsetX, offsetY;
let draggedRect = null;
function handleMouseDown(event) {
const {
x,
y
} = getCanvasCoordinates(event);
for (const rect of rectangles) {
if (x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y + rect.height) {
isDragging = true;
draggedRect = rect;
startX = x;
startY = y;
offsetX = x - rect.x;
offsetY = y - rect.y;
break;
}
}
}
function handleMouseMove(event) {
if (isDragging) {
const {
x,
y
} = getCanvasCoordinates(event);
if (draggedRect) {
draggedRect.x = x - offsetX;
draggedRect.y = y - offsetY;
drawCanvas();
}
}
}
function handleMouseUp() {
isDragging = false;
draggedRect = null;
}
function drawCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (const rect of rectangles) {
ctx.beginPath();
ctx.rect(rect.x, rect.y, rect.width, rect.height);
ctx.fillStyle = 'blue';
ctx.fill();
}
}
// 绘制矩形
function addRectangle() {
const rect = {
x: Math.random() * (canvas.width - 100),
y: Math.random() * (canvas.height - 100),
width: 80 + Math.random() * 40,
height: 60 + Math.random() * 40,
color: `hsl(${Math.random() * 360}, 70%, 60%)`
};
rectangles.push(rect);
drawCanvas();
}
// 绑定鼠标按下事件,用于拖动起始
canvas.addEventListener('mousedown', handleMouseDown);
// 绑定鼠标移动事件,用于拖动过程
canvas.addEventListener('mousemove', handleMouseMove);
// 绑定鼠标松开事件,用于拖动结束
canvas.addEventListener('mouseup', handleMouseUp);
addRectangle();
</script>
</body>
</html>
效果预览
结语
本文主要介绍了在 Canvas 中处理鼠标点击和拖动事件的方法,对于文章中错误的地方或者有任何问题,欢迎在评论区留言分享!