只是为了好玩,我试图在3D变换的画布上绘制。我写了一些代码,它的工作原理
const m4 = twgl.m4;
[...document.querySelectorAll('canvas')].forEach((canvas) => {
const ctx = canvas.getContext('2d');
let count = 0;
canvas.addEventListener('mousemove', (e) => {
const pos = getElementRelativeMousePosition(e, canvas);
ctx.fillStyle = hsl((count++ % 10) / 10, 1, 0.5);
ctx.fillRect(pos.x - 1, pos.y - 1, 3, 3);
});
});
function getElementRelativeMousePosition(e, elem) {
const pos = convertPointFromPageToNode(elem, e.pageX, e.pageY);
return {
x: pos[0],
y: pos[1],
};
}
function hsl(h, s, l) {
return `hsl(${h * 360 | 0},${s * 100 | 0}%,${l * 100 | 0}%)`;
}
function convertPointFromPageToNode(elem, pageX, pageY) {
const mat = m4.inverse(getTransformationMatrix(elem));
return m4.transformPoint(mat, [pageX, pageY, 0]);
};
function getTransformationMatrix(elem) {
let matrix = m4.identity();
let currentElem = elem;
while (currentElem !== undefined &&
currentElem !== currentElem.ownerDocument.documentElement) {
const style = window.getComputedStyle(currentElem);
const localMatrix = parseMatrix(style.transform);
matrix = m4.multiply(localMatrix, matrix);
currentElem = currentElem.parentElement;
}
const w = elem.offsetWidth;
const h = elem.offsetHeight;
let i = 4;
let left = +Infinity;
let top = +Infinity;
for (let i = 0; i < 4; ++i) {
const p = m4.transformPoint(matrix, [w * (i & 1), h * ((i & 2) >> 1), 0]);
left = Math.min(p[0], left);
top = Math.min(p[1], top);
}
const rect = elem.getBoundingClientRect()
document.querySelector('p').textContent =
`${w}x${h}`;
matrix = m4.multiply(m4.translation([
window.pageXOffset + rect.left - left,
window.pageYOffset + rect.top - top,
0]), matrix);
return matrix;
}
上面的代码有效。将鼠标移到两个黄色画布元素上,您会看到它正确绘制了。
但是,一旦我添加了一些3D变换,它就会失败。
将“#c6”的CSS更改为
#c6 {
background: pink;
transform: rotate(45deg) rotateX(45deg); /* changed */
display: inline-block;
}
现在当我在右边的黄色画布上绘制时,一切都关闭了。
有什么想法我做错了吗?
慕哥6287543
相关分类