Html5 canvas 层旋转后KineticJS鼠标位置错误
我的演示在这里Html5 canvas 层旋转后KineticJS鼠标位置错误,html5-canvas,kineticjs,Html5 Canvas,Kineticjs,我的演示在这里 首先,在蓝色的盒子里画一些东西 然后,单击“旋转”按钮一次 旋转长方体后,再次绘制某物 最后,抽签结果是错误的 我怎样才能解决这个问题,谢谢 代码: 即使在旋转后,Kinetic仍会为您提供未旋转的鼠标坐标 这是因为您正在请求stage.getMousePosition,而stage没有旋转 没有像layer.getMousePosition这样的方法,所以您必须创建一个 如果将图层旋转90度,还必须将舞台的鼠标坐标旋转90度 以下是旋转舞台鼠标位置以匹配图层旋转的方式:
即使在旋转后,Kinetic仍会为您提供未旋转的鼠标坐标 这是因为您正在请求stage.getMousePosition,而stage没有旋转 没有像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);
下面是代码和小提琴:
原型
#容器{
边框:实心1px#ccc;
边缘顶部:10px;
宽度:400px;
高度:400px;
}
$(函数(){
var阶段=新的动力学阶段({
容器:'容器',
宽度:500,
身高:500
});
var层=新的动力学层({宽度:400,高度:400});
阶段。添加(层);
//保存当前旋转信息的变量
旋转向量;
变量旋转;
无功旋转;
var旋转;
设置旋转(0);
var rect=新的动能.rect({
x:0,,
y:0,
宽度:400,
身高:300,
填写:“#00D2FF”,
笔画:“黑色”,
冲程宽度:5
});
层。添加(rect);
阶段。添加(层);
$(文档)。在('click','#rotateBtn',函数(){
var w=layer.getWidth(),
h=layer.getHeight();
层设置偏移量(w/2,h/2);
层设置位置(w/2,h/2);
层旋转(90);
layer.draw();
//设置取消旋转鼠标位置所需的信息
setRotation(layer.getRotationDeg())
});
var points=[],
图纸=假;
stage.on('mousedown',函数(){
绘图=真;
//获取旋转的鼠标位置
pos=getPos();
点推送([x位置,y位置]);
var线=新的动能线({
id:'行',
要点:[
[位置x,位置y],
[位置x+1,位置y+1]
],
笔画:“白色”,
冲程宽度:5,
线头:“圆形”,
lineJoin:'圆形'
});
图层。添加(行);
layer.drawsecene();
});
stage.on('mousemove',函数(){
如果(!图纸){
返回;
}
//删除上一行
layer.get('#line').remove();
//获取旋转的鼠标位置
var pos=getPos();
点推送([x位置,y位置]);
//重画线
var线=新的动能线({
id:'行',
点:点,,
笔画:“白色”,
冲程宽度:5,
线头:“圆形”,
lineJoin:'圆形'
});
图层。添加(行);
layer.drawsecene();
});
stage.on('mouseup',function(){
图纸=假;
点数=[];
});
//重置为当前旋转信息
功能设置旋转(度){
var弧度=layer.getRotation();
rotationX=layer.getOffsetX();
rotationY=layer.getOffsetY();
旋转cos=数学cos(弧度);
旋转sin=数学sin(弧度);
}
//旋转舞台鼠标位置
//以匹配图层旋转
函数getPos(x,y){
//正常空间,无需调整
如果(rotationCos==0){return;}
var pos=stage.getMousePosition();
var x1=旋转X
+(位置x-旋转x)*旋转COS
+(位置y-旋转y)*旋转IN;
变量y1=旋转Y
+(位置y-旋转y)*旋转COS
-(位置x-旋转x)*旋转IN;
返回({x:x1,y:y1});
}
}); // end$(函数(){});
旋转
谢谢!这个效果很好。我以前使用过line.setPoints(点),但它会使绘图有点延迟。我不知道为什么。
// set the points property of the line to your updated points array
line.setPoints(points);
<!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>