получение координат мыши на повернутом холсте CSS 3D - PullRequest
2 голосов
/ 15 октября 2019

Я прошу прощения, что этот вопрос задавался раньше

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

По сути, я пытаюсь сделать ничью. на элементе <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 ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...