如何在旋转后的父元素中使用draggable拖动元素?-灵析社区

CO_co

下面的例子在 Chrome118 和 FireFox118 中运行良好,复制到一个新的 html 文件再用浏览器打开就可以体验: Drag in rotated .stage { position: absolute; width: 800px; height: 800px; outline: solid 1px #2f89ff; transform-origin: center; } .dancer { position: absolute; width: 16px; height: 16px; cursor: move; background-color: red; border-radius: 8px; } .inputs { position: relative; z-index: 10; } 旋转: 缩小: const metaMatrix = [1, 0, 0, 1, 0, 0]; let actualAngle = 0; let actualScale = 1; function applyMatrixToStage() { const matrix = new DOMMatrixReadOnly(metaMatrix) .rotate(actualAngle) .scale(actualScale) .toString(); stage.style.transform = matrix; } function toNormalMatrix({ a, b, c, d, e, f }) { return { _value: new Float32Array([a, c, e, b, d, f]), point([x, y]) { const [m11, m12, m13, m21, m22, m23] = this._value; return [m11 * x + m12 * y + m13, m21 * x + m22 * y + m23]; }, }; } angle.addEventListener("change", ({ target: { value } }) => { actualAngle = +value; applyMatrixToStage(); }); scale.addEventListener("change", ({ target: { value } }) => { actualScale = +value; applyMatrixToStage(); }); stage.addEventListener("mousedown", ({ target, clientX, clientY }) => { if (target === dancer) { const { style } = dancer; const matrix = new DOMMatrixReadOnly(metaMatrix) .rotate(actualAngle) .scale(actualScale); const startAt = [parseFloat(style.left), parseFloat(style.top)]; const dragCallback = ({ target, clientX: _clientX, clientY: _clientY, }) => { // 把逆变换应用到拖动的差量即可 const offset = toNormalMatrix(matrix.inverse().toJSON()).point([ _clientX - clientX, _clientY - clientY, ]); style.left = startAt[0] + offset[0] + "px"; style.top = startAt[1] + offset[1] + "px"; }; const cancelDrag = () => { stage.removeEventListener("mousemove", dragCallback); }; stage.addEventListener("mousemove", dragCallback); stage.addEventListener("mouseup", cancelDrag); stage.addEventListener("mouseleave", cancelDrag); } });

阅读量:1

点赞量:0

问AI