PDA

View Full Version : Dragging along a circle



Greendrake
27 Mar 2010, 3:28 AM
I'm going to implement an image rotating control, so I need to drag a handle along a circle.
Below is my attempt. It seems to be working well, though I'd be pleased to hear any possible suggestions/improvements B). Thanks!

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Round Dragging</title>
<style type="text/css">
#box {
background-color: green;
left: 90px;
top: 190px;
position: absolute;
cursor: pointer;
}
</style>
<script type="text/javascript" src="../ExtJs/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="../ExtJs/ext-all.js"></script>
<script type="text/javascript">
var center = [200, 200],
handleSize = 20,
radius = 100,
solveSquare = function (a, b, c) {
var s = Math.sqrt(b*b - 4*a*c);
return [(-b+s)/(2*a), (-b-s)/(2*a)];
},
nearest = function(a, b, c){
return Math.abs(a - c) < Math.abs(b - c) ? a : b
},
getPointOnTheCircle = function(R, cx, cy, mx, my){
if (cx == mx) { // We need to handle this special case manually, because IE doesn't handle it properly using the code below
return [cx, nearest(cy + R, cy - R, my)];
}
var d = (cy - my) / (cx - mx),
rx = solveSquare(1 + d*d, 2*(d*my - cx - cy*d - d*d*mx), cx*cx + cy*cy + 2*cy*d*mx - 2*cy*my + d*d*mx*mx - 2*d*mx*my + my*my - R*R);
rx = nearest(rx[0], rx[1], mx);
return [Math.round(rx), Math.round(d*(rx - mx) + my)];
},
rd = function(){
rd.superclass.constructor.apply(this, arguments);
};

Ext.extend(rd, Ext.dd.DD, {
getTargetCoord: function(x, y){
var coords = getPointOnTheCircle(radius, center[0], center[1], x, y);
return {
x: coords[0] - Math.round(handleSize/2),
y: coords[1] - Math.round(handleSize/2)
};
}
});

Ext.onReady(function(){
var box = Ext.get('box');
box.setSize(handleSize, handleSize);
new rd(box);
});
</script>
</head>
<body>
<div id="box"></div>
</body>
</html>

Animal
27 Mar 2010, 6:30 AM
Neat! Trig can be fun can't it? (I'm working on a geolocation app, calculating points, bearings, distances etc)

Perhaps instead of embedding functions in there like that, you could extend the Ext.lib.Point/Region class to make your code more reusable?

The Ext.lib Region and Point classes are useful for adding trig functions for manipulating the screen. Here's my examples: http://www.extjs.com/forum/showthread.php?t=69295