这个案例展示了如何利用HTML5的Canvas和JavaScript实现一个动态效果:在画布上绘制一个箭头,并让它实时跟随鼠标移动。
这个小项目不仅有趣,还能帮助你理解编程和基本数学观点的实际运用。

项目需求

我们的目标是在一个画布上绘制一个箭头,并让这个箭头随着鼠标的移动自动旋转,始终指向鼠标的位置。

数学根本知识:atan2函数

在这个项目中,最关键的数学观点是atan2函数,它帮助我们打算箭头该当如何旋转才能指向鼠标的位置。

html5鼠标跟随特效Canvas 动画 atan2 三角函数与鼠标追随后果 CSS
(图片来自网络侵删)
dx和dy:这些是鼠标位置和箭头位置之间的水平和垂直间隔。
dx是x方向上的差值,dy是y方向上的差值。
atan2(dy, dx)是什么?:它是一个分外的数学函数,用来打算给定的dx和dy所对应的角度。
这个角度表示从箭头到鼠标的方向。
我们之以是利用atan2,是由于它能够处理所有可能的方向(高下旁边斜角),并且它比普通的atan函数更为精确和稳定。

技能要点

让我们来逐步理解项目中涉及的技能要点。

Canvas绘图:Canvas是HTML5供应的一个绘图环境。
我们利用<canvas>标签来创建一个画布,之后在这个画布上绘制箭头。
canvas.getcontext('2d')供应了一个2D绘图高下文,通过这个高下文可以绘制图形、设置颜色、处理旋转等操作。
事宜监听:我们利用JavaScript的mousemove事宜监听器,实时捕捉鼠标在画布上的位置。
每次鼠标移动时,事宜监听器都会记录鼠标的x和y坐标,这样我们就知道鼠标在哪里了。
图形旋转:当我们知道鼠标的位置后,接下来要做的便是打算箭头该当朝向哪个方向。
通过Math.atan2(dy, dx)打算出箭头的旋转角度,然后利用Canvas的rotate方法,让箭头旋转到精确的角度,指向鼠标。
代码展示

<!doctype html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>跟随鼠标移动的箭头</title> <style> body { font-family: Arial, sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; margin: 0; background-color: #f0f0f0; } canvas { border: 1px solid #000; } header { margin-bottom: 20px; } aside { margin-top: 10px; font-size: 14px; } </style></head><body> <header> Example from <a href="https://qianduandaren.com"><em>前端达人</em></a> </header> <canvas id="canvas" width="400" height="400"></canvas> <aside>请移动鼠标</aside> <script> class Utils { static captureMouse(element) { const mouse = { x: 0, y: 0, event: null }; element.addEventListener('mousemove', event => { const rect = element.getBoundingClientRect(); mouse.x = event.clientX - rect.left; mouse.y = event.clientY - rect.top; mouse.event = event; }); return mouse; } } class Arrow { constructor() { this.x = 0; this.y = 0; this.color = "#ffff00"; this.rotation = 0; } draw(context) { context.save(); context.translate(this.x, this.y); context.rotate(this.rotation); context.lineWidth = 2; context.fillStyle = this.color; context.beginPath(); context.moveTo(-50, -25); context.lineTo(0, -25); context.lineTo(0, -50); context.lineTo(50, 0); context.lineTo(0, 50); context.lineTo(0, 25); context.lineTo(-50, 25); context.lineTo(-50, -25); context.closePath(); context.fill(); context.stroke(); context.restore(); } } window.onload = () => { const canvas = document.getElementById('canvas'); const context = canvas.getContext('2d'); const mouse = Utils.captureMouse(canvas); const arrow = new Arrow(); arrow.x = canvas.width / 2; arrow.y = canvas.height / 2; const drawFrame = () => { requestAnimationFrame(drawFrame); context.clearRect(0, 0, canvas.width, canvas.height); const dx = mouse.x - arrow.x; const dy = mouse.y - arrow.y; arrow.rotation = Math.atan2(dy, dx); arrow.draw(context); }; drawFrame(); }; </script></body></html>分步阐明

1. Canvas设置与初始化

const canvas = document.getElementById('canvas');const context = canvas.getContext('2d');

获取Canvas元素和高下文:首先,在onload函数中,我们通过getElementById获取HTML中的canvas元素,并通过getContext('2d')获取2D绘图高下文,这个高下文是我们用来绘制图形的根本。

2. 工具类Utils:捕捉鼠标位置

class Utils { static captureMouse(element) { const mouse = { x: 0, y: 0, event: null }; element.addEventListener('mousemove', event => { const rect = element.getBoundingClientRect(); mouse.x = event.clientX - rect.left; mouse.y = event.clientY - rect.top; mouse.event = event; }); return mouse; }}

Utils类简介:

Utils类供应了一个静态方法captureMouse,这个方法的浸染是帮助我们实时捕捉鼠标在画布中的位置。

捕捉鼠标位置:

getBoundingClientRect():用于获取画布相对付浏览器窗口的位置和大小。
监听mousemove事宜:每次鼠标在画布上移动时,都会触发mousemove事宜,这时我们打算鼠标相对付画布的x、y坐标,并存储在mouse工具中。
末了返回这个mouse工具,以便我们在后续的代码中随时获取鼠标的位置。

3、定义箭头类Arrow

class Arrow { constructor() { this.x = 0; this.y = 0; this.color = "#ffff00"; this.rotation = 0; } draw(context) { context.save(); context.translate(this.x, this.y); context.rotate(this.rotation); context.lineWidth = 2; context.fillStyle = this.color; context.beginPath(); context.moveTo(-50, -25); context.lineTo(0, -25); context.lineTo(0, -50); context.lineTo(50, 0); context.lineTo(0, 50); context.lineTo(0, 25); context.lineTo(-50, 25); context.lineTo(-50, -25); context.closePath(); context.fill(); context.stroke(); context.restore(); }}Arrow类用于定义箭头的初始属性,包括位置(x、y)、颜色和旋转角度。
draw方法:用于在画布上绘制箭头。
这个方法利用了Canvas的绘图API,首先保存当前绘图状态(context.save()),然后移动并旋转画布(translate和rotate),根据预定的路径绘制出一个箭头形状,末了添补颜色和描边(fill和stroke),并规复画布状态(context.restore())。

4.绘制与旋转箭头

const drawFrame = () => { requestAnimationFrame(drawFrame); context.clearRect(0, 0, canvas.width, canvas.height); const dx = mouse.x - arrow.x; const dy = mouse.y - arrow.y; arrow.rotation = Math.atan2(dy, dx); arrow.draw(context); }; drawFrame();动画帧更新:利用requestAnimationFrame(drawFrame)来实现平滑的动画效果。
这个方法让浏览器在每次重绘时调用drawFrame,从而以高效的办法不断更新箭头的位置和方向。
打消画布:每一帧开始时,我们利用context.clearRect(0, 0, canvas.width, canvas.height)清空画布,这样就不会看到之前绘制的内容残留。
这样做可以确保每次重绘都是干净的。
打算方向:dx和dy:打算鼠标相对付箭头的水平和垂直间隔。
旋转角度:通过Math.atan2(dy, dx)打算出箭头须要旋转的角度。
atan2函数根据这两个差值返回一个介于-π到π之间的角度值,表示从箭头位置到鼠标位置的方向。
绘制箭头:在打算完旋转角度后,我们调用arrow.draw(context),根据新的角度在画布上绘制箭头。
这使得箭头能够实时指向鼠标的位置。
结束

这个项目演示了如何利用HTML5的Canvas和JavaScript来创建一个动态的跟随鼠标移动的箭头效果。
我们通过atan2函数打算出箭头旋转的角度,并利用Canvas的绘图功能将其实时显示在网页上。
通过这个案例,您不仅学会了如何利用Canvas绘图和JavaScript事宜监听,还节制了如何将数学函数运用于实际的编程问题中。

希望这个案例能帮助您更好地理解这些技能,并引发您进一步学习和探索的兴趣!