2013-02-18 238 views
0

我想要使图像对象旋转根据鼠标点击该图像和鼠标到对象的中心的角度。kineticjs旋转鼠标角度

单位圆的思考和具有该图像被旋转大约基于其中鼠标在该圆的圆。

我现在有

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事件,它应该只允许旋转。

- 它需要保持动态的图像画面,因为他们会在页面的生活动态填充画布。

这里是类似我希望发生的事情一个很好的例子,但只是简单的不能让它在画布/ kineticjs工作。 http://jsfiddle.net/22Feh/5/

+0

你可以把你当前的代码放入jsfiddle吗? – SoluableNonagon 2013-02-18 17:11:59

+0

我把它放在一个方形的图像上,它似乎可以在一些点击上正确旋转,但从来没有mousedown计算或'setRotation'。我不确定它是哪一个。 http://jsfiddle.net/WXHe6/ – kevindstanley 2013-02-18 18:21:49

+0

我发布了两个答案,第二个我认为是你正在寻找的。对不起,第一个冗长的啰嗦,我分析了它。 – SoluableNonagon 2013-02-18 21:41:10

回答

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

谢谢......我不敢相信我错过了,忽略了它。 – kevindstanley 2013-02-18 21:42:53

0

你应该更清楚你的。对()的事件做。在你的代码中,形状上的mousedown除了计算mouseStartAngle之外没有其他任何操作,但是什么都不做。而你在形状事件上的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()可以获取鼠标坐标。除非你有这种需求来构建你的项目,尽量避免它。

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

一些提示:使用主要用于KineticJS功能(我知道你会需要像SHIFT按键事件侦听器)

  1. 尝试。我的意思是,使用像stage.getUserPosition();获得鼠标/触摸坐标,而不是evt.clientX,它更清洁,工作已经完成,无需重新发明轮子。

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

  3. 如果您不希望形状在单击shift时可拖动,则应在单击某个项之前设置该形状。您有按钮侦听器,因此您可以在按下Shift时禁用所有形状的旋转,也可以仅在光标下的形状上使用该旋钮。

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

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