Aligning Shapes on a plan, Algoryhtm
I am developing a simple diagram tool with shapes on a plan using flex. First i was using a simple 20*20 grid.
But the real cool stuff out their is auto axe magnet effect, that's how i call it at least to see why i mean by that i made a small video of balsamiq.
http://screenr.com/clB
http://www.balsamiq.com/
As you can see it aligns on the vertical horizontal border and center axes.
- Borders: gray axes
- Horizontal align (height/2) Center: blue axe
- No Vertical align (width/2) axe
- Some intermediary padding space 开发者_开发知识库of 25px: green axes
How do you think such algorithms work: For now i will do with no rotation.
Given a shape S1 selected at position top left x,y of width w and height h.
Look at all shapes intersecting two zone:
from xmin = x, xmax= x+w for y > 0.
from yming = y , ymax= y+h for x > 0.
Once i have the list of shape concerned i check if any conditions matches:
When i use '=' its an approximation + or - 2 pixels will give the wanted 'magnet' effect
- S1 x = S'x => Gray line at x
- S1 x+w = S'x => Gray line at x+w
- S1 y = S'y => Gray line at y
- S1 y+h = S'y => Gray line at y+h
- S1 x = S'x and S1 x+w = S'x+w => Blue line at x + w/2
And Given a padding magnet of 20 px
- S1 x = S'x + PADD => greenline at S1 x
- S1 x = S'x - PADD => greenline at S1 x
- S1 y = S'y + PADD => greenline at S1 y
- S1 y = S'y - PADD => greenline at S1 y
Whats your thought about this ?
I wrote Balsamiq's snapping algorithm. You're pretty close. The one "clever" thing we do (if I may say so myself), is to pre-populate two sparse arrays with snapping coordinates onMouseDown, so that they are easy/fast/cheap to look up onMouseMove. What I do onMouseDown is this:
let's talk about x coordinates (then repeat the same thing for y):
- say GRAVITY is 5
- look at all the shapes
- for each shape, look at the left edge, say it's at 100. Populate the xSnappingPositions object from 100-GRAVITY (95) to 100+GRAVITY (105) with the number 100. Repeat for right edge
Then when you do an onMouseMove, you look at the control you're dragging's x and y. Is there something in xSnappingPositions and ySnappingPosition that matches the left edge now? if so, go to the value saved in the array instead of using the position detected by the mouse (i.e. snap to it). Repeat the check for right edge, center, etc.
I hope this helps!
精彩评论