首先,需要一个可旋转的对象,该对象包含使用 canvas
上下文在 canvas
上绘制一个箭头的功能。由于该箭头会重复使用,我们将其封装为一个类,将以下代码添加到 arrow.js
文件中,把该文件导入 HTML 主文件中:
function Arrow () {
this.x = 0
this.y = 0
this.color = "#ffff00"
this.rotation = 0
}
Arrow.prototype.draw = function (context) { // 使用原型定义方法
context.save()
context.translate(this.x, this.y) // 转换画布的坐标系,把箭头放在画布中间(画布为html元素)
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()
}
draw(context) 方法根据传入的 canvas 上下文参数使用 canvas 绘图 API 绘制一个箭头。
我们已经定义好了一个箭头类,每当使用一个箭头对象时,只需调用 new Arrow()方法即可。接下来,我们要找到鼠标在画布中所在的坐标
var utils = {}
utils.captureMouse = function (element) {
var mouse = {x: 0, y: 0}
element.addEventListener(‘mousemove‘, function (event){
var x, y
// 每个鼠标有以下两个属性获取鼠标当前位置,但有的浏览器不支持,所以进行以下判断
if ( event.pageX || event.pageY) {
x = event.pageX
y = event.pageY
} else {
x = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft
y = event.clientY + document.body.scrollTop + document.documentElement.scrollTop
}
x -= element.offsetLeft //防止偏移
y -= element.offsetTop
mouse.x = x // 鼠标的x坐标
mouse.y = y // 鼠标的y坐标
}, false )
return mouse // 获得鼠标位置坐标
}
3.当我们获得了箭头中心位置和鼠标位置以后,就可以利用 Math.atan2(dy, dx) 方法获得偏移的角度
dx = mouse.x-arrow.x;
dy = mouse.y-arrow.y;
arrow.rotation = Math.atan2(dy, dx);
通过下图可以更好的理解
当然,需要一个循环才能实现动画,以下是 HTML 中的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script src="utils.js"></script>
<script src="arrow.js"></script>
<script>
window.onload = function () {
var canvas = document.getElementById("canvas"),
context = canvas.getContext(‘2d‘),
mouse = utils.captureMouse(canvas),
arrow = new Arrow()
arrow.x = canvas.width/2
arrow.y = canvas.height/2;
(function drawFrame () {
// window.requestAnimationFrame 接受一个回调函数作为参数
// 可以理解为对下面代码的不断循环调用
window.requestAnimationFrame(drawFrame, canvas)
// 删除上一个箭头的形状,以免覆盖,可以注释掉查看效果
context.clearRect(0, 0, canvas.width, canvas.height)
var dx = mouse.x-arrow.x
var dy = mouse.y-arrow.y
arrow.rotation = Math.atan2(dy,dx)
arrow.draw(context) // 删除旧的箭头后,从新绘制箭头
}())
}
</script>
</body>
</html>
原文:https://www.cnblogs.com/tonedog/p/11705918.html