【问题标题】:kineticjs rotate with mouse anglekineticjs随鼠标角度旋转
【发布时间】:2013-02-19 14:22:51
【问题描述】:

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

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

我现在有

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/

【问题讨论】:

  • 你能把你当前的代码放到一个 jsfiddle 里吗?
  • 我只用一个正方形作为图像,它似乎在某些点击时可以正确旋转,但从来没有鼠标按下计算或“setRotation”。我不确定是哪一个。 jsfiddle.net/WXHe6
  • 我发布了两个答案,我认为第二个答案就是您要找的。对不起,第一个啰嗦了,我分析过度了。
  • 您是否打算在拖动时禁用旋转?

标签: javascript rotation kineticjs mouse-position


【解决方案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;
     }
}

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 谢谢...我不敢相信我错过了这一点并忽略了它。
    【解决方案3】:

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

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

    选项一:鼠标按下时手动设置弧度

      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] 一样以数字方式访问它们; (按创建顺序)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-11
      • 2014-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多