如何使用 class javascript 使线条跟随鼠标事件反正切
How to make a line follow mouse event arctanget with class javascript
大家好,我正在尝试按照鼠标移动事件制作一行。我可以使用 ctx.save 执行此操作并恢复,但如果我想使用 class 并绘制其他对象,我不知道该怎么做。事实上,使用保存和恢复它是有效的,但如果我想得到相同的结果 class,我不知道该怎么做,非常感谢
window.onload = function() {
var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight,
arrowX = width / 2,
arrowY = height / 2,
dx, dy,
angle = 0,
a = 0;
render();
function render() {
arrowX = width / 2 + Math.cos(a) * height * .4;
arrowY = height / 2 + Math.sin(a) * height * .4;
context.clearRect(0, 0, width, height);
context.save();
context.translate(arrowX, arrowY);
context.rotate(angle);
context.beginPath();
context.moveTo(20, 0);
context.lineTo(-20, 0);
context.moveTo(20, 0);
context.lineTo(10, -10);
context.moveTo(20, 0);
context.lineTo(10, 10);
context.stroke();
context.restore();
requestAnimationFrame(render);
}
document.body.addEventListener("mousemove", function(event) {
dx = event.clientX - arrowX;
dy = event.clientY - arrowY;
angle = Math.atan2(dy, dx);
});
};
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="height: 100vh;">
<Canvas id="canvas"></Canvas>
<script src="main.js"></script>
</body>
</html>
如果我想使用 class,我会像下面的代码一样开始
var canvas = document.getElementById("canvas");
var c = canvas.getContext("2d");
var width = canvas.width = window.innerWidth;
var height = canvas.height = window.innerHeight;
var arrowX = width / 2;
var arrowY = height -20;
var dx;
var dy;
var angle = 0;
class Player{
constructor(x,y,radius,color)
{
this.x=x;
this.y=y;
this.radius=radius;
this.color=color;
}
draw(){
c.beginPath();
c.arc(this.x,this.y,this.radius, 0, Math.PI *2,false );
c.fillStyle=this.color;
c.fill();
}
}
class Shooter{
constructor(x,y,xEnd,yEnd,color){
this.x=x;
this.y=y;
this.xEnd=xEnd;
this.yEnd=yEnd;
this.color=color;
}
draw(){
c.beginPath();
c.moveTo(this.x, this.y);
c.lineTo(this.xEnd, this.yEnd);
c.strokeStyle=this.color;
c.stroke();
}
}
// const player= new Player(arrowX,arrowY,20,'white');
const shooter= new Shooter(arrowX,500,arrowX,arrowY,'white');
let animationId;
function animate(){
animationId=requestAnimationFrame(animate)
c.fillStyle='rgba(0, 0, 0, 0.5)';
c.fillRect(0,0,canvas.width,canvas.height);
//player.draw();
shooter.draw();
}
requestAnimationFrame(animate);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="height: 100vh;">
<Canvas id="canvas"></Canvas>
<script src="main.js"></script>
</body>
</html>
我可以为此提供两种方法。第一种是简单地让矢量的末端与鼠标位置具有相同的坐标。这当然会改变向量的大小。
此方法不旋转或平移上下文。
var canvas = document.getElementById("canvas");
var c = canvas.getContext("2d");
var width = (canvas.width = window.innerWidth);
var height = (canvas.height = window.innerHeight);
let canvasBounds = canvas.getBoundingClientRect()
let mouse = {x: 0, y: 0}
class Shooter {
constructor(x, y, color) {
this.x = x;
this.y = y;
this.xEnd = mouse.x;
this.yEnd = mouse.y;
this.color = color;
}
draw() {
c.beginPath();
c.moveTo(this.x, this.y);
c.lineTo(this.xEnd, this.yEnd);
c.strokeStyle = this.color;
c.stroke();
}
update() {
this.xEnd = mouse.x;
this.yEnd = mouse.y;
}
}
const shooter = new Shooter(width/2, height/2, "white");
canvas.addEventListener("mousemove", e => {
mouse.x = e.x - canvasBounds.x;
mouse.y = e.y - canvasBounds.y;
});
function animate() {
animationId = requestAnimationFrame(animate);
c.fillStyle = "rgba(0, 0, 0, 0.5)";
c.fillRect(0, 0, canvas.width, canvas.height);
//player.draw();
shooter.draw();
shooter.update();
}
requestAnimationFrame(animate);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="height: 100vh;">
<Canvas id="canvas"></Canvas>
<script src="main.js"></script>
</body>
</html>
第二种方法在 (0, 0) 处绘制起点,但您可以使用 translate 将其定位在任何您想要的位置。这也会旋转上下文,但允许您保持大小不变。
var canvas = document.getElementById("canvas");
var c = canvas.getContext("2d");
var width = (canvas.width = window.innerWidth);
var height = (canvas.height = window.innerHeight);
let canvasBounds = canvas.getBoundingClientRect()
let mouse = {x: 0, y: 0}
class Shooter {
constructor(x, y, color) {
this.x = 0;
this.y = 0;
this.xEnd = this.x + 50;
this.yEnd = this.y;
this.translate = {x: x, y: y}
this.color = color;
this.angle = 0;
}
draw() {
this.angle = Math.atan2(mouse.y - this.translate.y, mouse.x - this.translate.x)
c.save();
c.translate(this.translate.x, this.translate.y);
c.rotate(this.angle);
c.beginPath();
c.moveTo(this.x, this.y);
c.lineTo(this.xEnd, this.yEnd);
c.strokeStyle = this.color;
c.stroke();
c.restore()
}
update() {
}
}
const shooter = new Shooter(width/2, height/2, "white");
canvas.addEventListener("mousemove", e => {
mouse.x = e.x - canvasBounds.x;
mouse.y = e.y - canvasBounds.y;
});
function animate() {
requestAnimationFrame(animate);
c.fillStyle = "rgba(0, 0, 0, 0.5)";
c.fillRect(0, 0, canvas.width, canvas.height);
//player.draw();
shooter.draw();
}
requestAnimationFrame(animate);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="height: 100vh;">
<Canvas id="canvas"></Canvas>
<script src="main.js"></script>
</body>
</html>
大家好,我正在尝试按照鼠标移动事件制作一行。我可以使用 ctx.save 执行此操作并恢复,但如果我想使用 class 并绘制其他对象,我不知道该怎么做。事实上,使用保存和恢复它是有效的,但如果我想得到相同的结果 class,我不知道该怎么做,非常感谢
window.onload = function() {
var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight,
arrowX = width / 2,
arrowY = height / 2,
dx, dy,
angle = 0,
a = 0;
render();
function render() {
arrowX = width / 2 + Math.cos(a) * height * .4;
arrowY = height / 2 + Math.sin(a) * height * .4;
context.clearRect(0, 0, width, height);
context.save();
context.translate(arrowX, arrowY);
context.rotate(angle);
context.beginPath();
context.moveTo(20, 0);
context.lineTo(-20, 0);
context.moveTo(20, 0);
context.lineTo(10, -10);
context.moveTo(20, 0);
context.lineTo(10, 10);
context.stroke();
context.restore();
requestAnimationFrame(render);
}
document.body.addEventListener("mousemove", function(event) {
dx = event.clientX - arrowX;
dy = event.clientY - arrowY;
angle = Math.atan2(dy, dx);
});
};
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="height: 100vh;">
<Canvas id="canvas"></Canvas>
<script src="main.js"></script>
</body>
</html>
如果我想使用 class,我会像下面的代码一样开始
var canvas = document.getElementById("canvas");
var c = canvas.getContext("2d");
var width = canvas.width = window.innerWidth;
var height = canvas.height = window.innerHeight;
var arrowX = width / 2;
var arrowY = height -20;
var dx;
var dy;
var angle = 0;
class Player{
constructor(x,y,radius,color)
{
this.x=x;
this.y=y;
this.radius=radius;
this.color=color;
}
draw(){
c.beginPath();
c.arc(this.x,this.y,this.radius, 0, Math.PI *2,false );
c.fillStyle=this.color;
c.fill();
}
}
class Shooter{
constructor(x,y,xEnd,yEnd,color){
this.x=x;
this.y=y;
this.xEnd=xEnd;
this.yEnd=yEnd;
this.color=color;
}
draw(){
c.beginPath();
c.moveTo(this.x, this.y);
c.lineTo(this.xEnd, this.yEnd);
c.strokeStyle=this.color;
c.stroke();
}
}
// const player= new Player(arrowX,arrowY,20,'white');
const shooter= new Shooter(arrowX,500,arrowX,arrowY,'white');
let animationId;
function animate(){
animationId=requestAnimationFrame(animate)
c.fillStyle='rgba(0, 0, 0, 0.5)';
c.fillRect(0,0,canvas.width,canvas.height);
//player.draw();
shooter.draw();
}
requestAnimationFrame(animate);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="height: 100vh;">
<Canvas id="canvas"></Canvas>
<script src="main.js"></script>
</body>
</html>
我可以为此提供两种方法。第一种是简单地让矢量的末端与鼠标位置具有相同的坐标。这当然会改变向量的大小。
此方法不旋转或平移上下文。
var canvas = document.getElementById("canvas");
var c = canvas.getContext("2d");
var width = (canvas.width = window.innerWidth);
var height = (canvas.height = window.innerHeight);
let canvasBounds = canvas.getBoundingClientRect()
let mouse = {x: 0, y: 0}
class Shooter {
constructor(x, y, color) {
this.x = x;
this.y = y;
this.xEnd = mouse.x;
this.yEnd = mouse.y;
this.color = color;
}
draw() {
c.beginPath();
c.moveTo(this.x, this.y);
c.lineTo(this.xEnd, this.yEnd);
c.strokeStyle = this.color;
c.stroke();
}
update() {
this.xEnd = mouse.x;
this.yEnd = mouse.y;
}
}
const shooter = new Shooter(width/2, height/2, "white");
canvas.addEventListener("mousemove", e => {
mouse.x = e.x - canvasBounds.x;
mouse.y = e.y - canvasBounds.y;
});
function animate() {
animationId = requestAnimationFrame(animate);
c.fillStyle = "rgba(0, 0, 0, 0.5)";
c.fillRect(0, 0, canvas.width, canvas.height);
//player.draw();
shooter.draw();
shooter.update();
}
requestAnimationFrame(animate);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="height: 100vh;">
<Canvas id="canvas"></Canvas>
<script src="main.js"></script>
</body>
</html>
第二种方法在 (0, 0) 处绘制起点,但您可以使用 translate 将其定位在任何您想要的位置。这也会旋转上下文,但允许您保持大小不变。
var canvas = document.getElementById("canvas");
var c = canvas.getContext("2d");
var width = (canvas.width = window.innerWidth);
var height = (canvas.height = window.innerHeight);
let canvasBounds = canvas.getBoundingClientRect()
let mouse = {x: 0, y: 0}
class Shooter {
constructor(x, y, color) {
this.x = 0;
this.y = 0;
this.xEnd = this.x + 50;
this.yEnd = this.y;
this.translate = {x: x, y: y}
this.color = color;
this.angle = 0;
}
draw() {
this.angle = Math.atan2(mouse.y - this.translate.y, mouse.x - this.translate.x)
c.save();
c.translate(this.translate.x, this.translate.y);
c.rotate(this.angle);
c.beginPath();
c.moveTo(this.x, this.y);
c.lineTo(this.xEnd, this.yEnd);
c.strokeStyle = this.color;
c.stroke();
c.restore()
}
update() {
}
}
const shooter = new Shooter(width/2, height/2, "white");
canvas.addEventListener("mousemove", e => {
mouse.x = e.x - canvasBounds.x;
mouse.y = e.y - canvasBounds.y;
});
function animate() {
requestAnimationFrame(animate);
c.fillStyle = "rgba(0, 0, 0, 0.5)";
c.fillRect(0, 0, canvas.width, canvas.height);
//player.draw();
shooter.draw();
}
requestAnimationFrame(animate);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="height: 100vh;">
<Canvas id="canvas"></Canvas>
<script src="main.js"></script>
</body>
</html>