Drag Constrain template

There are already a few examples in this forum for drag constrainment. But these do not work when you’re document has to support scalability. That’s why I started to work on a template that does support this and uses only the build-in javascript API’s.

This template has three examples: constrain a draggable in a box, horizontal- and vertical-constrainment.

drag-constrain.hypetemplate.zip (48.2 KB)

8 Likes

I was just wondering if using this type of constraint would work when using the Physic options.

One of the problems with physics is setting boundaries to stop the object falling out of the scene.
Another is when you have drag set on the object also. You can drag it out of the scene.

So all we need to do is listen for any changes to the element and run the constraining code; for example.

We have a container set up and a drag object.
We change the constraint/boundary function to :

var element =  hypeDocument.getElementById('drag')
		var vContainer = hypeDocument.getElementById('container');
	//use this line for left constrain
		if (hypeDocument.getElementProperty(element, 'left') < hypeDocument.getElementProperty(vContainer, 'left')) {
			hypeDocument.setElementProperty(element, 'left', hypeDocument.getElementProperty(vContainer, 'left'), 0, 'linear');
		};
		//use this line for right constrain
		if((hypeDocument.getElementProperty(element, 'left') + hypeDocument.getElementProperty(element, 'width')) > (hypeDocument.getElementProperty(vContainer, 'left') + hypeDocument.getElementProperty(vContainer, 'width'))){
			hypeDocument.setElementProperty(element, 'left', (hypeDocument.getElementProperty(vContainer, 'left')+hypeDocument.getElementProperty(vContainer, 'width')-hypeDocument.getElementProperty(element, 'width')), 0, 'linear');
		};
		//use this line for top constrain
		if(hypeDocument.getElementProperty(element, 'top') < hypeDocument.getElementProperty(vContainer, 'top')){
			hypeDocument.setElementProperty(element, 'top', hypeDocument.getElementProperty(vContainer, 'top'), 0, 'linear');
		};
		//use this line for bottom constrain
		if((hypeDocument.getElementProperty(element, 'top') + hypeDocument.getElementProperty(element, 'height')) > (hypeDocument.getElementProperty(vContainer, 'top') + hypeDocument.getElementProperty(vContainer, 'height'))){
			hypeDocument.setElementProperty(element, 'top', (hypeDocument.getElementProperty(vContainer, 'top')+hypeDocument.getElementProperty(vContainer, 'height')-hypeDocument.getElementProperty(element, 'height')), 0, 'linear');
		};	

And do not call it on the ondrag action. The on drag action is only set to Control the elements position

Now we set the drag element to have full Physic dynamics.

We then add a new function that runs on scene load.

The function sets up an Mutation Observer , MutationObserver will watch for changes in the drag elements ‘style’ ( we can limit to only detect changes to style in the observer )

	// create an observer instance
var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
     hypeDocument.functions().constrain(hypeDocument, element, event)	
  });    
});
 
// configuration of the observer:
var config = { attributes: true, childList: true, characterData: true ,attributeFilter:['style'] };
 
// pass in the target node, as well as the observer options
observer.observe(drag, config);

 
 
// later, you can stop observing
//observer.disconnect();	

We do not need to know what the change is. The MutationObserver will run a callback on any change.

So all we do is get it to run the constraints function.

The effect is you will have a boundary that the element with Physic cannot break out of and you cannot drag out of, even with physics.


I have not had a massive play with this but in my own brief observations the are some caveats that would need to be addressed. Like bounce. This gets broken I think since we are making the element adhere
to the boundary when it tries to go past it.

Drag_&_Physics_constrains.hypetemplate.zip (16.4 KB)

3 Likes

If you add a wall where it can bounce to and let it be dragged just 1 pixel out of the container, bouncing is working again :slight_smile:

Drag_&_Physics_Bounce_constrains.hypetemplate.zip (15.6 KB)

3 Likes

Yep that works,

Here is an example showing the above coded boundary with a high bounce and an example of a normal static walled boundary with a high bounce.

You should see the normal ones ball fly out of the scene as the physics cannot handle the extreme bouncing.
The code boundary with static wall just 1 pixel in width and just within the boundary controls the bounce.

This is really great.

Drag_&_Physics_Bounce_constrains_v2.hypetemplate.zip (24.6 KB)

4 Likes

Very cool solution.

Hype implementation note: if you use the setter API or animation for position/rotation, then the physical properties of the body will be reset - for example it will lose its velocity or rotational velocity and start as if it were a new dynamic body. This is why it doesn’t quite bounce correctly.