3

我的演示在这里http://jsfiddle.net/akuma/7NmXw/1/

  1. 首先,在蓝色框中画一些东西。
  2. 然后,单击一次旋转按钮。
  3. 旋转框后,再次绘制一些东西。
  4. 最后,平局是错误的。

我该如何解决这个问题,谢谢!

代码:

var stage = new Kinetic.Stage({
    container: 'container',
    width: 500,
    height: 500
});

var layer = new Kinetic.Layer({
    width: 400,
    height: 400
});

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();
});

var points = [],
    drawing = false;

stage.on('mousedown', function () {
    drawing = true;

    var pos = stage.getMousePosition();
    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();

    var pos = stage.getMousePosition();
    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 = [];
});
4

1 回答 1

5

即使在旋转之后,Kinetic 仍然会给你未旋转的鼠标坐标

那是因为您要求 stage.getMousePosition 并且舞台没有旋转。

没有像 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);

这是代码和小提琴:http: //jsfiddle.net/m1erickson/cQATv/

<!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>
于 2013-08-10T20:12:52.107 回答