Myszka i obrót
Żeby obrócić obiekt w kierunku, w którym znajduje się kursor myszy, należy obliczyć kąt. Kąt, który znajduje się pomiędzy: dodatnią osią X i linią prostą, którą tworzą dwa punkty: pierwszy punkt to (0, 0), a drugi to: podany (x, y).
W poniższym przykładzie drugi punkt jest obliczany, w następujący sposób:
const y = rect.y - mouse.y + canvasRect.top;
const x = rect.x - mouse.x + canvasRect.left;
gdzie:
rect - To pozycja obracanego obiektu
mouse - To pozycja kursora myszy
canvasRect - To pozycja płótna
Mając już obliczony punkt, można pobrać informacje o kącie, o jaki powinien zostać obrócony obiekt:
angle = Math.atan2(y, x);
Kąt zwracany jest w radianach.
Przykład
Demo znajdziesz tutaj
HTML:
<canvas id="canvas" width="800" height="600"></canvas>
JavaScript
let angle = 0;
const step = 15;
const mouse = { x: 0, y: 0 };
const canvas = document.getElementById('canvas');
const context = canvas.getContext("2d");
const canvasRect = canvas.getBoundingClientRect();
const rect = {
width: 50,
height: 50,
x: context.canvas.width / 2,
y: context.canvas.height / 2
}
document.addEventListener('mousemove', (e) => {
mouse.x = e.clientX;
mouse.y = e.clientY;
const y = rect.y - mouse.y + canvasRect.top;
const x = rect.x - mouse.x + canvasRect.left;
angle = Math.atan2(y, x);
});
document.addEventListener('keydown', (e) => {
rect.x += -step * Math.cos(angle);
rect.y += -step * Math.sin(angle);
});
const render = () => {
context.fillStyle = '#000';
context.fillRect(0, 0, context.canvas.width, context.canvas.height);
context.fillStyle = '#ff0000';
context.save();
context.translate(rect.x, rect.y)
context.rotate(angle);
context.fillRect(-rect.width / 2, -rect.height / 2, rect.width, rect.height);
context.restore();
requestAnimationFrame(render);
}
render();
Jak pobrać współrzędne?
Żeby pobrać pozycję kursora myszy, w obrębie Canvas potrzebujesz dwa rodzaje informacji: pozycję kursora i pozycję płótna.
Pozycja (0, 0) oznacza lewy górny róg płótna.
Przykład działającego przykładu znajdziesz tutaj
Przykład
HTML:
<div>
<strong>X: <span id="x"></span></strong>
<br>
<strong>Y: <span id="y"></span></strong>
</div>
<br>
<canvas id="canvas" width="800" height="600"></canvas>
JavaScript:
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
const x = document.getElementById('x');
const y = document.getElementById('y');
context.fillStyle = '#000';
context.fillRect(0, 0, context.canvas.width, context.canvas.height);
canvas.addEventListener('mousemove', (e) => {
const canvasRect = canvas.getBoundingClientRect();
const posX = Math.round(e.clientX - canvasRect.left);
const posY = Math.round(e.clientY - canvasRect.top);
x.innerHTML = posX;
y.innerHTML = posY;
});
Mając informację o pozycji kursora: e.clientX i e.clientY oraz pozycji płótna: canvasRect.left i canvasRect.top możemy obliczyć pozycję kursora w Canvas. Zmienne: posX i posY.
Jak obrócić obiekt?
Pod tym linkiem znajdziesz demo przykładu opisanego w tym wpisie.
HTML:
<canvas id="canvas" width="800" height="600"></canvas>
JavaScript:
let angle = 0;
const context = document.getElementById("canvas").getContext("2d");
const rect = {
width: 50,
height: 50,
x: context.canvas.width / 2,
y: context.canvas.height / 2
}
const degreesToRadians = (degrees) => {
return degrees * (Math.PI / 180);
};
const render = () => {
context.fillStyle = '#000';
context.fillRect(0, 0, context.canvas.width, context.canvas.height);
context.fillStyle = '#ff0000';
context.save();
context.translate(rect.x, rect.y)
context.rotate(degreesToRadians(angle));
context.fillRect(-rect.width / 2, -rect.height / 2, rect.width, rect.height);
context.restore();
angle += 0.5;
requestAnimationFrame(render);
}
render();
Za obrót obiektu wokół jego środka odpowiadają dwie linijki.
Pierwsza:
context.rotate(rotate);
Jest to kąt, o jaki ma być obrócony obiekt. Podany w radianach. Stopnie obliczane są w radiany za pomocą funkcji: degreesToRadians.
Druga linijka:
context.fillRect(-rect.width / 2, -rect.height / 2, rect.width, rect.height);
Odpowiedzialna jest za ustawienie osi obrotu obiektu. Na jego środku.