代码之家  ›  专栏  ›  技术社区  ›  Axel

在Javascript中使用矩阵创建可调整大小的视图

  •  0
  • Axel  · 技术社区  · 4 年前

    我有一个追随者 implementation

    const ANGLE = 45 * (Math.PI / 180)
    const box = document.getElementById("box")
    const rotate = document.getElementById("rotate")
    const resizerBr = document.getElementById("resizer-br")
    
    function getMatrix() {
        return box.style.transform
            .replace("matrix3d(", "")
            .replace(")", "")
            .split(", ")
            .map((x) => Number(x))
    }
    
    box.style.transform = `matrix3d(
        ${Math.cos(ANGLE)}, ${Math.sin(ANGLE)}, 0, 0,
        -${Math.sin(ANGLE)}, ${Math.cos(ANGLE)}, 0, 0,
        0, 0, 1, 0,
        150, 150, 0, 1
    )`
    
    box.addEventListener("mousedown", (e) => {
        if (e.target !== box) return
        const boxRect = box.getBoundingClientRect()
        const initX = e.clientX
        const initY = e.clientY
        const mt = getMatrix()
    
        function drag(event) {
            const dx = event.clientX - initX
            const dy = event.clientY - initY
    
            // prettier-ignore
            const matrix = [
               mt[0], mt[1], 0, 0,
                mt[4], mt[5], 0, 0,
                0, 0, 1, 0,
                mt[12] + dx, mt[13] + dy, 0, 1
            ]
    
            box.style.transform = `matrix3d(${matrix})`
        }
    
        function clearListeners() {
            window.removeEventListener("mousemove", drag)
            window.removeEventListener("mouseup", clearListeners)
        }
    
        window.addEventListener("mousemove", drag)
        window.addEventListener("mouseup", clearListeners)
    })
    
    rotate.addEventListener("mousedown", (e) => {
        const boxRect = box.getBoundingClientRect()
        const initX = boxRect.left + boxRect.width / 2
        const initY = boxRect.top + boxRect.height / 2
        const mt = getMatrix()
    
        function rotate(event) {
            const dx = event.clientX - initX
            const dy = event.clientY - initY
            const angle = Math.atan2(dy, dx) + Math.PI / 2
    
            // prettier-ignore
            const rotationMatrix = [
                Math.cos(angle), Math.sin(angle), 0, 0,
                -Math.sin(angle), Math.cos(angle), 0, 0,
                0, 0, 1, 0,
                mt[12], mt[13], 0, 1
            ]
    
            box.style.transform = `matrix3d(${rotationMatrix})`
        }
    
        function clearListeners() {
            window.removeEventListener("mousemove", rotate)
            window.removeEventListener("mouseup", clearListeners)
        }
    
        window.addEventListener("mousemove", rotate)
        window.addEventListener("mouseup", clearListeners)
    })
    
    resizerBr.addEventListener("mousedown", (e) => {
        const boxRect = box.getBoundingClientRect()
        const initX = e.clientX
        const initY = e.clientY
        const width = boxRect.width
        const height = boxRect.height
        const mt = getMatrix()
    
        function resize(event) {
            const dx = event.clientX - initX
            const dy = event.clientY - initY
    
            const newWidth = width + dx
            const newHeight = height + dy
    
            box.style.width = `${newWidth}px`
            box.style.height = `${newHeight}px`
        }
    
        function clearListeners() {
            window.removeEventListener("mousemove", resize)
            window.removeEventListener("mouseup", clearListeners)
        }
    
        window.addEventListener("mousemove", resize)
        window.addEventListener("mouseup", clearListeners)
    })
    .box-wrapper {
        position: relative;
    }
    
    .box {
        height: 200px;
        width: 300px;
        background-color: red;
        position: relative;
    }
    
    .rotate {
        position: absolute;
        height: 50px;
        width: 10px;
        top: -50px;
        left: 146px;
        background-color: blue;
    }
    
    .resizer.br {
        width: 50px;
        height: 50px;
        background-color: aqua;
        position: absolute;
        top: calc(100% - 50px);
        left: calc(100% - 50px);
    }
    <div id="box" class="box">
        <div id="rotate" class="rotate"></div>
        <div id="resizer-br" class="resizer br"></div>
    </div>

    现在,我要做的是从右下角调整大小,这样左上角就可以使用matrix3d保持不变

    enter image description here

    如何使用matrix3d实现这一点?任何帮助都将不胜感激。

    0 回复  |  直到 4 年前