views:

379

answers:

3

Are there any examples of a drag-and-drop solution in which the elements being dragged can only move along a slanted line? For example, constrain an element's draggability so that it can only be moved along a 30º line, or 10º, etc.

Most examples I've been able to find only constrain the dragged element's area to either a vertical or horizontal line, or to within a larger parent div.

Possibly related: Drag along a diagonal line no further than 100px, or along a curve.

+1  A: 

It would seem the only way to really do that, without really annoying the user, is to keep track of the angle from the starting location, and if they are in an invalid angle then don't set the droptarget.

This way, if they let go it reverts back to the original position, and the only valid places to drop meet your requirements.

James Black
But then that would assume that any mouse position not directly overtop of the line is invalid (i.e. it forms an "invalid angle" as you put it). I would say this constraint is actually *detrimental* to the UX as it requires precise control of the mouse. A more helpful UX would be to extrapolate the "correct" drop point from wherever the mouse is (within a certain buffer area of course), to aid those (most of us?) who don't control the mouse very well.
Crescent Fresh
No, my suggestion is with the idea that you can move the object being dragged wherever you want, but, the only highlighted objects would be those in the correct angle, any other place will not be a droptarget. So, it gives guidance as to where is valid, based on outlining or letting a user know by some feedback that this is valid, and if they move elsewhere, then then another valid spot will eventually be highlighted (outlined).
James Black
A: 

This seems easy to do if you've written your own DnD handler. Basically, DnD movement that is constrained to either vertical or horizontal axises work by only changing the left or top CSS attributes when dynamically position the draggable element.

You can use this same idea to customize this restrained behavior. Instead just translating the (X,Y) of the current mouse position for the element's CSS left/right, you can use the X for the left and derive the right by passing it through a linear function like y = mx + b.

Justin Johnson
+1  A: 

complete example (FF only)

<div id="drag" style="position:absolute;width:20px;height:20px;background:red"></div>
<script>
var angle = 10;
window.onload = function() 
{
 var d = document.getElementById("drag");
 d.onmousedown = function() {
  document.onmouseup = function() {
   document.onmousemove = null;
  }
  document.onmousemove = function(e) {
   d.style.left = e.clientX;
   d.style.top = e.clientX * Math.tan(angle * Math.PI / 180);
  }
 }
}
</script>
stereofrog
Add some units (`"px"`) to your `left` and `top` assignments and this is good to go in all browsers (as long as there is no scroll bar on the page).
Crescent Fresh