【问题标题】:After the element is rotated or scaled by transformer, the element cannot be rotated around the center manually元素通过变压器旋转或缩放后,无法手动围绕中心旋转元素
【发布时间】:2022-10-17 10:18:02
【问题描述】:

画布中有一个元素。每次单击按钮时,我都希望它围绕其中心点旋转 90 度。所以当我判断这个元素的原点不在中心点时,我会手动指定它的原点到中心点。当我不使用变压器旋转或缩放它时,它工作得很好,可以围绕中心点旋转。但是,当我通过变压器旋转或缩放这个元素,然后单击按钮旋转它时,它的位置是偏移的,如果我继续单击它,它可以围绕中心点旋转。 我希望它始终围绕中心点旋转 90 度,但我不知道如何解决它。 代码如下

<button @click="rotate">rotate</button>

let stage = new Konva.Stage({
    container: container,
    width: 800,
    height: 800,
});

let layer = new Konva.Layer();
stage.add(layer);

let rect = new Konva.Rect({
    x:50,
    y:50,
    width: 200,
    height: 150
});
layer.add(rect);

let transformer = new Konva.Transformer({
    rotationSnaps: [0, 90, 180, 270],
    nodes:[rect]
});
layer.add(transformer);

function rotate(){
    if(!rect.attrs.offsetX){
        rect.setAttrs({
            offsetX:rect.attrs.width/2,
            offsetY:rect.attrs.height/2,
            x:rect.attrs.x + rect.attrs.width/2,
            y:rect.attrs.y + rect.attrs.height/2
        })
    }
    rect.rotate(90);
}

【问题讨论】:

  • 当你在一个节点上有所有的偏移、缩放和旋转时做数学是非常困难的。相反,您可以避免使用偏移量,它使用数学围绕中心旋转。请参阅此处的示例konvajs.org/docs/posts/Position_vs_Offset.html。只需要在 rotateAroundCenter 示例中应用比例

标签: canvas konvajs konva


【解决方案1】:

            let stage = new Konva.Stage({
                container: container,
                width: 400,
                height: 400,
            })

            let layer = new Konva.Layer()
            stage.add(layer)

            let rect = new Konva.Rect({
                x: 150,
                y: 150,
                width: 200,
                height: 150,
                fill: "red",

                //set offset
                offsetX: 200 / 2,
                offsetY: 150 / 2,
                
            })

            layer.add(rect)

            let transformer = new Konva.Transformer({
                rotationSnaps: [0, 90, 180, 270],
                nodes: [rect],
            })
            layer.add(transformer)

            function rotate() {
                rect.rotate(10)
            }
<script src="https://unpkg.com/konva@8.3.10/konva.min.js"></script>
<button onclick="rotate()">rotate</button>
<div id="container"></div>

【讨论】:

    【解决方案2】:

    let $w = 500,
                    $h = 500
                let grid = 50
                let stage = new Konva.Stage({
                    container: canvas,
                    width: $w,
                    height: $h,
                })
    
                let layer = new Konva.Layer()
                stage.add(layer)
                let origin = { x: 100, y: 100 }
                const box = { w: 100, h: 200 }
    
                let xLine = new Konva.Line({
                    points: [0, grid, $w, 50],
                    stroke: "#333",
                    strokeWidth: 0.2,
                    dash: [20, 5],
                })
                xLine.cache()
                let yLine = new Konva.Line({
                    points: [grid, 0, grid, $h],
                    stroke: "#333",
                    strokeWidth: 0.2,
                    dash: [20, 5],
                })
                yLine.cache()
                let rect = new Konva.Rect({
                    fill: "red",
                    x: origin.x,
                    y: origin.y,
                    width: box.w,
                    height: box.h,
                })
                let rect2 = new Konva.Rect({
                    fill: "green",
                    x: origin.x * 3,
                    y: origin.y * 2,
                    width: box.w,
                    height: box.h,
    
                    //set offset
                    offsetX: box.w / 2,
                    offsetY: box.h / 2,
                })
                layer.add(rect, rect2)
    
                var xLineClone, yLineClone
                for (let n = 0; n < $h / grid; n++) {
                    xLineClone = xLine.clone({
                        x: 0,
                        y: n * grid,
                        dashEnabled: (n + 1) % 2 != 0,
                    })
                    xLineClone.cache()
                    layer.add(xLineClone)
    
                    yLineClone = yLine.clone({
                        x: n * grid,
                        y: 0,
                        dashEnabled: (n + 1) % 2 != 0,
                    })
                    yLineClone.cache()
                    layer.add(yLineClone)
                }
    
                function print(e, id) {
                    if (e.target) e = e.target
                    //$(id).text(JSON.stringify(e.attrs))
                    $(id).html(`<p>x:${e.x().toFixed(2)}</p><p>y:${e.y().toFixed(2)}</p>`)
                }
                let transformer = new Konva.Transformer({
                    rotationSnaps: [0, 90, 180, 270],
                    nodes: [rect],
                    anchorStroke: "#4aadfb",
                    anchorFill: "yellow",
                    anchorSize: 8,
                    borderDash: [5, 5],
                    borderStroke: "#00d9e1",
                    centeredScaling: true,
                    keepRatio: true,
                    flipEnabled: true,
                }).on("transform", function (e) {
                    print(e, "#tips1")
                })
    
                let transformer2 = new Konva.Transformer({
                    rotationSnaps: [0, 90, 180, 270],
                    nodes: [rect2],
    
                    centeredScaling: true,
                    keepRatio: true,
                    flipEnabled: true,
                }).on("transform", function (e) {
                    print(e, "#tips2")
                })
                layer.add(transformer, transformer2)
    
                function rotatePoint({ x, y }, rad) {
                    const rcos = Math.cos(rad)
                    const rsin = Math.sin(rad)
                    return { x: x * rcos - y * rsin, y: y * rcos + x * rsin }
                }
    
                function rotateAroundCenter(node, rotation) {
                    const topLeft = { x: -node.width() / 2, y: -node.height() / 2 }
                    const current = rotatePoint(topLeft, Konva.getAngle(node.rotation()))
                    const rotated = rotatePoint(topLeft, Konva.getAngle(rotation))
                    const dx = rotated.x - current.x,
                        dy = rotated.y - current.y
    
                    node.rotation(rotation)
                    node.x(node.x() + dx)
                    node.y(node.y() + dy)
    
                    return node
                }
                function rotate() {
                    rotateAroundCenter(rect, rect.rotation() + 45)
                    print(rect, "#tips1")
                }
                function rotate2() {
                    rect2.rotate(45)
                    print(rect2, "#tips2")
                }
    button {
                    margin: 10px;
                    padding: 10px;
                }
                #container {
                    position: relative;
                }
                .konvajs-content {
                    background-color: #c5d3f9;
                }
                .tips {
                    width: 150px;
                }
                #tips1 {
                    position: absolute;
                    top: 10px;
                    left: 10px;
                }
                #tips2 {
                    position: absolute;
                    bottom: 10px;
                    left: 300px;
                }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
    <script src="https://unpkg.com/konva@8.3.10/konva.min.js"></script>
            <div id="container">
                <div id="canvas"></div>
                <div id="tips1" class="tips"></div>
                <div id="tips2" class="tips"></div>
            </div>
            <button onclick="rotate()">[rect1]rotate</button>
            <button onclick="rotate2()">[rect2]rotate</button>

    【讨论】:

      猜你喜欢
      • 2018-08-26
      • 1970-01-01
      • 2019-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-22
      • 2021-02-01
      相关资源
      最近更新 更多