0

我正在尝试根据在该图像上单击的鼠标以及鼠标与对象中心的角度来使图像对象旋转。

考虑一个单位圆,并根据鼠标在该圆上的位置使图像围绕该圆旋转。

我目前有

var stage = new Kinetic.Stage({
container: "container",
width: 800,
height: 500,
id: "myCanvas",
name: "myCanvas"
});
var layer = new Kinetic.Layer();
//gets the canvas context
var canvas = stage.getContainer();
var mousePosX;
var mousePosY;
var mouseStartAngle;
var selectedImage;
var mouseAngle;
var mouseStartAngle;
console.log(canvas)

var shiftPressed
window.addEventListener('keydown', function (e) {
if (e.keyCode == "16") {
    shiftPressed = true;
}
console.log(shiftPressed)
}, true);

window.addEventListener('keyup', function (e) {
if (e.keyCode == "16") {
    shiftPressed = false;
}
console.log(shiftPressed)
}, true);

function drawImage(imageObj) {

var dynamicImg = new Kinetic.Image({
    image: imageObj,
    x: stage.getWidth() / 2 - 200 / 2,
    y: stage.getHeight() / 2 - 137 / 2,
    width: 100, //imageObj.width,
    height: 100, // imageObj.height,
    draggable: true,
    offset: [50,50] //[(imageObj.width/2), (imageObj.height/2)]

});

dynamicImg.on('mousedown', function () {


    selectedImage = this;
    console.log("x: " + this.getX())
    console.log("y: " + this.getY())

    var mouseStartXFromCenter = mousePosX - (this.getX() + (this.getWidth() / 2));
    var mouseStartYFromCenter = mousePosY - (this.getY() + (this.getHeight() / 2));
    mouseStartAngle = Math.atan2(mouseStartYFromCenter, mouseStartXFromCenter);

    if (shiftPressed) {
        //console.log("trying to switch draggable to false");
        //console.log(this)
        this.setDraggable(false);
    }
});

dynamicImg.on('mouseup mouseout', function () {
    //console.log('mouseup mouseout')
    this.setDraggable(true);
});


dynamicImg.on('mouseover', function () {
    document.body.style.cursor = 'pointer';
});
dynamicImg.on('mouseout', function () {
    document.body.style.cursor = 'default';
});

imageArray.push(dynamicImg);
layer.add(dynamicImg);
stage.add(layer);
}
var imageObj = new Image();
imageObj.onload = function () {
drawImage(this);

};
imageObj.src = 'http://localhost:60145/Images/orderedList8.png';

function getMousePos(evt) {

var rect = canvas.getBoundingClientRect();
return {
    x: evt.clientX - rect.left,
    y: evt.clientY - rect.top
};
}


canvas.addEventListener('mouseup', function () {
selectedImage = undefined;
});

canvas.addEventListener('mousemove', function (evt) {
mousePos = getMousePos(evt);
//console.log('Mouse position: ' + mousePos.x + ',' + mousePos.y)
mousePosX = mousePos.x;
mousePosY = mousePos.y;

if (selectedImage != undefined) {

    mouseXFromCenter = mousePosX - selectedImage.getX();
    mouseYFromCenter = mousePosY - selectedImage.getY();
    mouseAngle = Math.atan2(mouseYFromCenter, mouseXFromCenter);

    var rotateAngle = mouseAngle - mouseStartAngle;

    selectedImage.setRotation(rotateAngle);

}
}, false);

代码有几件事。- 如果按下“shift”并且在图像上发生 mousedown 事件,它应该只允许旋转。

- 它需要维护动态图像绘制,因为它们将在页面的整个生命周期内动态填充画布。

这是我想要发生的类似事情的一个很好的例子,但只是无法让它在 canvas/kineticjs 中工作。 http://jsfiddle.net/22Feh/5/

4

3 回答 3

1

我会使用dragBoundFunc 更简单的方法。http://jsfiddle.net/bighostkim/vqGmL/

dragBoundFunc: function (pos, evt) {
    if (evt.shiftKey) {
        var x = this.getX() - pos.x;
        var y = this.getY() - pos.y;
        var radian = Math.PI + Math.atan(y/x);
        this.setRotation(radian);
        return {
            x: this.getX(),
            y: this.getY()
        }
     } else {
        return pos;
     }
}
于 2013-02-19T06:22:51.177 回答
0

我的错误,我看错了你的问题。你基本上错过了一行:

    layer.draw();

按住 shift 并移动鼠标,您会看到它很好地旋转。 http://jsfiddle.net/WXHe6/2/

    canvas.addEventListener('mousemove', function (evt) {
            mousePos = getMousePos(evt);
            //console.log('Mouse position: ' + mousePos.x + ',' + mousePos.y)
            mousePosX = mousePos.x;
            mousePosY = mousePos.y;

            if (selectedImage != undefined) {

            mouseXFromCenter = mousePosX - selectedImage.getX();
            mouseYFromCenter = mousePosY - selectedImage.getY();
            mouseAngle = Math.atan2(mouseYFromCenter, mouseXFromCenter);

            var rotateAngle = mouseAngle - mouseStartAngle;

            selectedImage.setRotation(rotateAngle);
            layer.draw(); // <--------------- right here
  }
  }, false);
于 2013-02-18T21:40:07.030 回答
0

您应该更清楚 .on() 事件的作用。在您的代码中,除了计算 mouseStartAngle 之外,形状上的 mousedown 不执行任何操作,但不执行任何操作。而且你在 shape 事件上的 mouseUp 也没有多大作用。完成所有工作的是您的浏览器/客户端 mousedown/mouseup,这就是为什么它在某些点击而不是其他点击时正确旋转的原因。

要设置旋转,您有很多选项,这里有两个:

选项一:在 mousedown 上手动设置弧度

  dynamicImg.on('mousedown', function () {   
    dynamicImg.setRotation(mouseStartAngle); //set the rotation degree
    layer.draw(); // redraw the layer
  }

选项二:让 kineticJS 为您设置旋转动画

  dynamicImg.on('mousedown', function () { 
    dynamicImg.transitionTo({  
        duration: 1,       // length of animation in seconds
        rotation: mouseStartAngle   // your angle, in radians
    });
  }

您更新的 jsfiddle:http: //jsfiddle.net/WXHe6/1/

以下是一些附加说明:

您遇到问题的原因是因为您的代码结构有点混乱,很抱歉。您正在将浏览器事件与画布混合并向画布添加侦听器,而不是使用内置的 kineticJS 功能,例如,您可以使用 stage.getUserPosition() 来获取鼠标坐标。除非您迫切需要以这种方式构建项目,否则请尽量避免使用它。

我喜欢的是您创建了分解代码的函数,但不利的一面是,您有多个函数在做同样的事情,比如计算和更新旋转角度。为什么不只做一个函数来获得角度?

一些技巧:

  1. 尝试主要使用 KineticJS 来实现功能(我知道您需要像 SHIFT 这样的按钮的事件侦听器)。我的意思是,使用类似 stage.getUserPosition(); 要获取鼠标/触摸坐标,而不是 evt.clientX,它更干净,并且已经为您完成了工作,无需重新发明轮子。

  2. 制作一个用于设置/获取形状旋转的功能。然后,您可以随时调用它。(使用较少重复的代码)

  3. 如果您不希望在单击 shift 时可以拖动形状,则应在单击项目之前进行设置。您有按钮侦听器,因此您可以在按下 shift 时禁用所有形状的旋转,或者只禁用光标下方的形状。

  4. imageArray.push(dynamicImg); 不确定你是否真的需要这个,如果你需要以数组的形式访问所有元素,你总是可以做 layer.getChildren(); 获取图层中的所有图像,或者像 layer.getChildren()[0] 一样以数字方式访问它们;(按创建顺序)

于 2013-02-18T21:36:23.000 回答