图层旋转后KineticJS鼠标位置错误
Posted
技术标签:
【中文标题】图层旋转后KineticJS鼠标位置错误【英文标题】:KineticJS mouse position wrong after layer rotated 【发布时间】:2013-08-11 00:29:54 【问题描述】:我的演示在这里http://jsfiddle.net/akuma/7NmXw/1/
-
首先,在蓝色框中画一些东西。
然后,单击一次旋转按钮。
框旋转后,再次绘制一些东西。
最后draw poisitoin 错了。
如何解决这个问题,谢谢!
代码:
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 = [];
);
【问题讨论】:
【参考方案1】:即使在旋转之后,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>
【讨论】:
谢谢!这很好用。我之前使用过 line.setPoints(points) ,但它使绘图有点延迟。我不知道为什么。以上是关于图层旋转后KineticJS鼠标位置错误的主要内容,如果未能解决你的问题,请参考以下文章