Html5 canvas 层旋转后KineticJS鼠标位置错误

Html5 canvas 层旋转后KineticJS鼠标位置错误,html5-canvas,kineticjs,Html5 Canvas,Kineticjs,我的演示在这里 首先,在蓝色的盒子里画一些东西 然后,单击“旋转”按钮一次 旋转长方体后,再次绘制某物 最后,抽签结果是错误的 我怎样才能解决这个问题,谢谢 代码: 即使在旋转后,Kinetic仍会为您提供未旋转的鼠标坐标 这是因为您正在请求stage.getMousePosition,而stage没有旋转 没有像layer.getMousePosition这样的方法,所以您必须创建一个 如果将图层旋转90度,还必须将舞台的鼠标坐标旋转90度 以下是旋转舞台鼠标位置以匹配图层旋转的方式:

我的演示在这里

  • 首先,在蓝色的盒子里画一些东西
  • 然后,单击“旋转”按钮一次
  • 旋转长方体后,再次绘制某物
  • 最后,抽签结果是错误的
  • 我怎样才能解决这个问题,谢谢

    代码:
    即使在旋转后,Kinetic仍会为您提供未旋转的鼠标坐标

    这是因为您正在请求stage.getMousePosition,而stage没有旋转

    没有像layer.getMousePosition这样的方法,所以您必须创建一个

    如果将图层旋转90度,还必须将舞台的鼠标坐标旋转90度

    以下是旋转舞台鼠标位置以匹配图层旋转的方式:

        // get the unrotated mouse position from Kinetic
    
        var pos=stage.getMousePosition();
    
        // rotate that point to match the layer rotation
    
        var x1 = rotationX 
                  + (pos.x-rotationX)*rotationCos 
                  + (pos.y-rotationY)*rotationSin;
    
        var y1 = rotationY 
                  + (pos.y-rotationY)*rotationCos 
                  - (pos.x-rotationX)*rotationSin;
    
    由于您将对每个鼠标移动进行此计算,因此应预先计算旋转值以最大限度地提高性能:

        // reset the current rotation information
    
        function setRotation(degrees){
            var radians=layer.getRotation();
            rotationX=layer.getOffsetX();
            rotationY=layer.getOffsetY();
            rotationCos=Math.cos(radians);
            rotationSin=Math.sin(radians);
        }
    
    还有,你的问题有点离题,但是

    您可以“回收”现有行,而不是在每个鼠标移动中删除/重新创建新行:

      // set the points property of the line to your updated points array
    
      line.setPoints(points);
    
    下面是代码和小提琴:

    
    原型
    #容器{
    边框:实心1px#ccc;
    边缘顶部:10px;
    宽度:400px;
    高度:400px;
    }
    $(函数(){
    var阶段=新的动力学阶段({
    容器:'容器',
    宽度:500,
    身高:500
    });
    var层=新的动力学层({宽度:400,高度:400});
    阶段。添加(层);
    //保存当前旋转信息的变量
    旋转向量;
    变量旋转;
    无功旋转;
    var旋转;
    设置旋转(0);
    var rect=新的动能.rect({
    x:0,,
    y:0,
    宽度:400,
    身高:300,
    填写:“#00D2FF”,
    笔画:“黑色”,
    冲程宽度:5
    });
    层。添加(rect);
    阶段。添加(层);
    $(文档)。在('click','#rotateBtn',函数(){
    var w=layer.getWidth(),
    h=layer.getHeight();
    层设置偏移量(w/2,h/2);
    层设置位置(w/2,h/2);
    层旋转(90);
    layer.draw();
    //设置取消旋转鼠标位置所需的信息
    setRotation(layer.getRotationDeg())
    });
    var points=[],
    图纸=假;
    stage.on('mousedown',函数(){
    绘图=真;
    //获取旋转的鼠标位置
    pos=getPos();
    点推送([x位置,y位置]);
    var线=新的动能线({
    id:'行',
    要点:[
    [位置x,位置y],
    [位置x+1,位置y+1]
    ],
    笔画:“白色”,
    冲程宽度:5,
    线头:“圆形”,
    lineJoin:'圆形'
    });
    图层。添加(行);
    layer.drawsecene();
    });
    stage.on('mousemove',函数(){
    如果(!图纸){
    返回;
    }
    //删除上一行
    layer.get('#line').remove();
    //获取旋转的鼠标位置
    var pos=getPos();
    点推送([x位置,y位置]);
    //重画线
    var线=新的动能线({
    id:'行',
    点:点,,
    笔画:“白色”,
    冲程宽度:5,
    线头:“圆形”,
    lineJoin:'圆形'
    });
    图层。添加(行);
    layer.drawsecene();
    });
    stage.on('mouseup',function(){
    图纸=假;
    点数=[];
    });
    //重置为当前旋转信息
    功能设置旋转(度){
    var弧度=layer.getRotation();
    rotationX=layer.getOffsetX();
    rotationY=layer.getOffsetY();
    旋转cos=数学cos(弧度);
    旋转sin=数学sin(弧度);
    }
    //旋转舞台鼠标位置
    //以匹配图层旋转
    函数getPos(x,y){
    //正常空间,无需调整
    如果(rotationCos==0){return;}
    var pos=stage.getMousePosition();
    var x1=旋转X
    +(位置x-旋转x)*旋转COS
    +(位置y-旋转y)*旋转IN;
    变量y1=旋转Y
    +(位置y-旋转y)*旋转COS
    -(位置x-旋转x)*旋转IN;
    返回({x:x1,y:y1});
    }
    }); // end$(函数(){});
    旋转
    
    谢谢!这个效果很好。我以前使用过line.setPoints(点),但它会使绘图有点延迟。我不知道为什么。
      // set the points property of the line to your updated points array
    
      line.setPoints(points);
    
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>Prototype</title>
        <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
        <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.5.min.js"></script>
    
    <style>
    #container{
      border:solid 1px #ccc;
      margin-top: 10px;
      width:400px;
      height:400px;
    }
    </style>        
    <script>
    $(function(){
    
        var stage = new Kinetic.Stage({
            container: 'container',
            width: 500,
            height: 500
        });
        var layer = new Kinetic.Layer({width:400,height:400});
        stage.add(layer);
    
    
        // vars to save the current rotation information
        var rotationX;
        var rotationY;
        var rotationCos;
        var rotationSin;
        setRotation(0);
    
    
        var rect = new Kinetic.Rect({
            x: 0,
            y: 0,
            width: 400,
            height: 300,
            fill: '#00D2FF',
            stroke: 'black',
            strokeWidth: 5
        });
    
        layer.add(rect);
        stage.add(layer);
    
        $(document).on('click', '#rotateBtn', function () {
            var w = layer.getWidth(),
                h = layer.getHeight();
    
            layer.setOffset(w / 2, h / 2);
            layer.setPosition(w / 2, h / 2);
            layer.rotateDeg(90);
            layer.draw();
    
            // set the info necessary to un-rotate the mouse position
            setRotation(layer.getRotationDeg())
    
        });
    
        var points = [],
            drawing = false;
    
        stage.on('mousedown', function () {
            drawing = true;
    
            // get the rotated mouse position
            pos=getPos();
            points.push([pos.x, pos.y]);
    
            var line = new Kinetic.Line({
                id: 'line',
                points: [
                    [pos.x, pos.y],
                    [pos.x + 1, pos.y + 1]
                ],
                stroke: 'white',
                strokeWidth: 5,
                lineCap: 'round',
                lineJoin: 'round'
            });
    
            layer.add(line);
            layer.drawScene();
        });
    
        stage.on('mousemove', function () {
            if (!drawing) {
                return;
            }
    
            // Remove previous line
            layer.get('#line').remove();
    
            // get the rotated mouse position
            var pos = getPos();
            points.push([pos.x, pos.y]);
    
            // Redraw line
            var line = new Kinetic.Line({
                id: 'line',
                points: points,
                stroke: 'white',
                strokeWidth: 5,
                lineCap: 'round',
                lineJoin: 'round'
            });
            layer.add(line);
            layer.drawScene();
    
        });
    
        stage.on('mouseup', function () {
            drawing = false;
            points = [];
        });
    
    
        // reset to the current rotation information
        function setRotation(degrees){
            var radians=layer.getRotation();
            rotationX=layer.getOffsetX();
            rotationY=layer.getOffsetY();
            rotationCos=Math.cos(radians);
            rotationSin=Math.sin(radians);
        }
    
    
        // rotate the stage mouse position
        // to match the layer rotation
        function getPos(x,y){
    
            // normal space, no adjustment necessary
            if(rotationCos==0){return;} 
    
            var pos=stage.getMousePosition();
    
            var x1 = rotationX 
                      + (pos.x-rotationX)*rotationCos 
                      + (pos.y-rotationY)*rotationSin;
    
            var y1 = rotationY 
                      + (pos.y-rotationY)*rotationCos 
                      - (pos.x-rotationX)*rotationSin;
    
            return({x:x1,y:y1});
        }
    
    
    }); // end $(function(){});
    
    </script>       
    </head>
    
    <body>
        <button id="rotateBtn">rotate</button>
        <div id="container"></div>
    </body>
    </html>