Как сделать элемент canvas лицом к указателю мыши - PullRequest
0 голосов
/ 21 февраля 2020

В настоящее время я изучаю холст html5, и я делал программу, которая поворачивает треугольник лицом к лицу, где находится мышь. это частично работает, но пропускает половину, и мне было интересно, есть ли лучший способ сделать это, а также что не так с моим текущим кодом

спасибо!

const ctx = document.getElementById("canvas").getContext("2d")
ctx.canvas.style.backgroundColor = "#303030"

ctx.canvas.width = 500
ctx.canvas.height = 500

const w = ctx.canvas.width
const h = ctx.canvas.height

let x = 0;
let y = 0;

let degrees = 0;

triAngle = 60

ctx.canvas.addEventListener("mousemove", mouseMove, false)

function mouseMove(evt) {
    x = evt.clientX
    y = evt.clientY

    let diffX = x - w / 2;
    let diffY = y - h / 2;

    console.log(diffX, diffY)

    degrees = Math.floor(Math.atan(diffY / diffX) * 57.2958);

    //Math.atan(diffY/ diffX)
    console.log(degrees)
}

function draw() {
    debugger ;
    ctx.clearRect(0, 0, w, h)

    ctx.fillStyle = "#fff";

    ctx.save()
    ctx.translate(w / 2, h / 2)
    ctx.rotate(degree(degrees + triAngle / 2))
    ctx.beginPath()
    ctx.moveTo(0, 0)
    ctx.lineTo(0, 100)
    ctx.rotate(degree(triAngle))
    ctx.lineTo(0, 100)
    ctx.closePath()
    ctx.fill()
    ctx.restore()

    requestAnimationFrame(draw)
}

function degree(input) {
    return Math.PI / 180 * input
}

draw()

https://jsfiddle.net/tus5nxpb/

1 Ответ

1 голос
/ 21 февраля 2020

Math.atan2

Причина, по которой Math.atan пропускает половину направлений, связана с знаком дроби. Круг имеет 4 квадранта, строки от {x: 0, y: 0} до {x: 1, y: 1}, {x: -1, y: 1}, {x: -1, y: -1} и {x: 1, y: -1} дают только два значения (1 и -1), если вы разделите y на x например, 1/1 === 1, 1/-1 === -1, -1/1 === -1 и -1/-1 === 1, таким образом, нет способа узнать, в каком из двух квадрантов присутствует каждое значение 1 и -1.

Вы можете используйте Math.atan2, чтобы получить угол от точки к другой точке в радианах. В диапазоне от -Math.PI до Math.PI (от -180 до 180 градусов)

Кстати, нет необходимости преобразовывать радианы в градусы, поскольку все математические функции в JavaScript используют радианы

requestAnimationFrame(mainLoop);
const ctx = canvas.getContext("2d")
canvas.height = canvas.width = 300;
canvas.style.backgroundColor = "#303030";

const mouse = {x: 0, y: 0};
canvas.addEventListener("mousemove", e => {
    mouse.x = e.clientX;
    mouse.y = e.clientY;
});

const shape = {
    color: "lime",
    x: 150,
    y: 150,
    size: 50,
    path: [1, 0, -0.5, 0.7, -0.5, -0.7],
};
function draw(shape) {
    var i = 0;
    const s = shape.size, p = shape.path;
    ctx.fillStyle = shape.color;
    const rot = Math.atan2(mouse.y - shape.y, mouse.x - shape.x);
    const xa = Math.cos(rot);
    const ya = Math.sin(rot);
    ctx.setTransform(xa, ya, -ya, xa, shape.x, shape.y);
    ctx.beginPath();
    while (i < p.length) { ctx.lineTo(p[i++] * s, p[i++] * s) }
    ctx.fill();
} 
function mainLoop() {
    ctx.setTransform(1, 0, 0, 1, 0, 0); // set default transform
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    draw(shape);
    requestAnimationFrame(mainLoop);
}
body { margin: 0px; }
canvas { position: absolute; top: 0px; left: 0px; }
<canvas id="canvas"></canvas>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...