Я прошу прощения, что этот вопрос задавался раньше
, но, к сожалению, я не смог найти ответ, который мог бы заставить меня работать. Хотя первое место в списке, похоже, содержит решение, после изрядного количества времени, пытаясь приспособить его к моим потребностям, мне пришлось признать свое поражение.
По сути, я пытаюсь сделать ничью. на элементе <canvas>
, который имеет поворот перспективы CSS3. Я думаю, что для этого мне нужно проецировать координаты мыши с экрана через матрицу преобразования, или, скорее, это обратное преобразование.
Интересно (и слегка раздражает) достаточно реализации Firefox event.layerX
и event.layerY
делает именно то, что я ищу
https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/layerX
Однако, будучи нестандартным, он работает только в Firefox. Похоже, что Chrome обрабатывает это так же, как offsetX и offsetY.
const canvas = document.querySelector("canvas");
const context = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// events
const pointermove = (event) => {
const pointX = event.layerX;
const pointY = event.layerY;
context.fillRect(pointX - 1,pointY - 1,3,3);
}
canvas.addEventListener("pointermove",pointermove);
body {
width:100%;
height:100%;
perspective:600px;
background-color:rgb(60,60,60);
}
div {
transform-style:preserve-3d;
transform:translateZ(-400px) rotateX(-20deg) rotateY(-40deg);
}
canvas {
background-color:rgb(230,230,230);
}
<div>
<canvas></canvas>
</div>
В качестве альтернативы этот ответ намекнул на использование DOMMatrix
и DOMPoint
, которые я был бы рад принять в качествеудовлетворительное решение, что, по крайней мере, и Firefox, и Chrome поддерживают
https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrix/DOMMatrix
https://developer.mozilla.org/en-US/docs/Web/API/DOMPoint
Однако, несмотря на все мои усилия, я не могу заставить его работать,Мне жаль говорить. Из того, что я понимаю, мне нужно применить обратную матрицу преобразования холста, чтобы получить экранные координаты положения указателя, и это самое близкое, что я мог бы получить к
const canvas = document.querySelector("canvas");
const context = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// events
const pointermove = (event) => {
const pointX = event.clientX * canvas.width / canvas.clientWidth;
const pointY = event.clientY * canvas.height / canvas.clientHeight;
let point = new DOMPoint(pointX,pointY);
const matrix = new DOMMatrix(window.getComputedStyle(canvas).transform);
matrix.invertSelf();
point = matrix.transformPoint(point);
context.fillRect(pointX - 1,pointY - 1,3,3);
}
canvas.addEventListener("pointermove",pointermove);
body {
width:100%;
height:100%;
perspective:600px;
background-color:rgb(60,60,60);
}
div {
transform-style:preserve-3d;
transform:translateZ(-400px) rotateX(-20deg) rotateY(-40deg);
}
canvas {
background-color:rgb(230,230,230);
}
<div>
<canvas></canvas>
</div>
Обводя края холста, он выглядит так, будто воспроизводит преобразование внутри холста, проецируя координаты экрана на локальные координаты,но я могу ошибатьсяБоюсь, мои математические навыки не соответствуют задаче получения матриц, но я предполагаю, что где-то пропускаю умножение ...
кто-нибудь из вас, добрые, умные людизнаете, где я ошибаюсь, или у вас есть альтернативные (ванильные) решения?
спасибо за ваше время
Редактировать: вот скрипка с использованием offsetX & offsetY, которую я не смогвыяснить, что происходит, надеясь, что это может пролить некоторый свет на то, что я ошибся, пытаясь применить ответ на другие вопросы
const canvas = document.querySelector("canvas");
const context = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// events
const pointermove = (event) => {
const pointX = event.offsetX * canvas.width / canvas.clientWidth;
const pointY = event.offsetY * canvas.height / canvas.clientHeight;
context.fillRect(pointX - 1,pointY - 1,3,3);
}
canvas.addEventListener("pointermove",pointermove);
body {
width:100%;
height:100%;
perspective:600px;
background-color:rgb(60,60,60);
}
div {
transform-style:preserve-3d;
transform:translateZ(-400px) rotateX(-20deg) rotateY(-40deg);
}
canvas {
background-color:rgb(230,230,230);
}
<div>
<canvas></canvas>
</div>
Я также понял, что, обойдя круг, я в итоге почти дословно скопировал пост DOMMatrix
...