需要一个布尔值,而不是一些绑定到 rect.on('mouseup') 的函数,非常感谢
问问题
259 次
1 回答
0
如何在 KineticJS 中对旋转的矩形进行命中测试
演示小提琴:http: //jsfiddle.net/m1erickson/wTYac/
方法:
- 将 mouseXY 坐标反向旋转矩形的旋转量。
- 针对未旋转版本的 rect 对未旋转的 mouseXY 进行命中测试。
细节:
首先,获取有关 rect 的当前信息
// get current info about this rect
var cx=this.getX();
var cy=this.getY();
var offX=this.getOffsetX();
var offY=this.getOffsetY();
var w=this.getWidth();
var h=this.getHeight();
然后计算 mouseXY 的当前角度与 rect 的旋转点。
注意:假设的旋转点是矩形的中心点。
// calc the xy's angle versus the rect's centerpoint
var dx=x-cx;
var dy=y-cy;
var rotatedRadians=Math.atan2(dy,dx);
然后通过矩形的旋转量“取消旋转”mouseXY:
// un-rotate the x,y by the amount of the rect's rotation
var lengthToXY=Math.sqrt(dx*dx+dy*dy);
var unrotatedRadians=rotatedRadians-this.getRotation();
var unX=cx+lengthToXY*Math.cos(unrotatedRadians);
var unY=cy+lengthToXY*Math.sin(unrotatedRadians);
最后,对未旋转的 mouseXY 与矩形的旋转点进行命中测试:
// unX/unY are now in unrotated space
// so just hittest against the unrotated rect
var xx=this.getX()-offX;
var yy=this.getY()-offY;
var hit=(unX>=xx && unX<=xx+w && unY>=yy && unY<=yy+h);
return(hit);
下面的代码将布尔rect.hit
属性添加到 Kinetic.Rect
这是代码和小提琴:http: //jsfiddle.net/m1erickson/wTYac/
<!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:300px;
height:300px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 300,
height: 300
});
var layer = new Kinetic.Layer();
stage.add(layer);
enableStageClick();
function enableStageClick(){
$(stage.getContent()).on('click', function (event) {
var pos=stage.getMousePosition();
var mouseX=parseInt(pos.x);
var mouseY=parseInt(pos.y);
var hit=rect1.hit(mouseX,mouseY)?"Clicked in rect":"Clicked outside rect";
$("#hit").text(hit);
});
}
var rect1=makeRect(150,150,100,50,"skyblue","lightgray",3);
function makeRect(x,y,w,h,fill,stroke,linewidth){
var rect = new Kinetic.Rect({
x: x,
y: y,
width: w,
height: h,
offset:[w/2,h/2], // rotate from rect centerpoint
fill: fill,
stroke: stroke,
strokeWidth: linewidth,
draggable:true
});
// return true if x,y is in this rotated rect
rect.hit=function(x,y){
// get current info about this rect
var cx=this.getX();
var cy=this.getY();
var offX=this.getOffsetX();
var offY=this.getOffsetY();
var w=this.getWidth();
var h=this.getHeight();
// un-rotate this x,y
var dx=x-cx;
var dy=y-cy;
var rotatedRadians=Math.atan2(dy,dx);
// un-rotate the x,y by the amount of the rect's rotation
var lengthToXY=Math.sqrt(dx*dx+dy*dy);
var unrotatedRadians=rotatedRadians-this.getRotation();
var unX=cx+lengthToXY*Math.cos(unrotatedRadians);
var unY=cy+lengthToXY*Math.sin(unrotatedRadians);
// unX/unY are now in unrotated space
// so just hittest against the unrotated rect
var xx=this.getX()-offX;
var yy=this.getY()-offY;
var hit=(unX>=xx && unX<=xx+w && unY>=yy && unY<=yy+h);
return(hit);
};
layer.add(rect);
layer.draw();
return(rect);
}
$("#rotateBtn").click(function(){
rect1.rotate(30*Math.PI/180);
layer.draw();
});
}); // end $(function(){});
</script>
</head>
<body>
<p>Click to hit-test the rectangle</p>
<button id="rotateBtn">rotate</button>
<span id="hit"></span>
<div id="container"></div>
</body>
</html>
于 2013-09-07T04:29:55.513 回答