Controlling onDrag position after releasing


(Andrew) #1

Has anyone had an issue where the element you have just dragged to a position, let go, and then try and pick it up again, where the mouse/touch area is, the element jumps to the last position. But if you try and drag the element itself, at this point, nothing happens.

What needs to be reset, or refreshed to prevent this from happening ?


(Andrew) #2

The DOM is back to left: 0px, top: 0px but the second you click and drag, the DOM jumps to the last know cords, and i cannot see where these would be stored ?


(Andrew) #3

Below is an image that shows the DOM using getBoundingClientRect()

You can see the DOM jumps position from the last known top, left as soon as the drag takes place.

As we are unable to set the BoundingClientRect() I am at a loss as to why it’s doing it, and where it’s getting the last cords from?


(Andrew) #4

Guess I am the only one then :stuck_out_tongue:


(Greg) #5

I’m not seeing this, are you using a plugin (jQuery maybe)???


(Andrew) #6

no plugin. You can see it happening I think by trying the spelling app I did. It has the same issue

Scroll down to Spelling App ?


(Greg) #7

Still not seeing the issue in the spelling app, can you make a movie of what is happening, maybe I’m misunderstanding. Are the elements snapping back to the last position? Is there a javascript involved?


(Andrew) #8

positionIssue.mov (695.3 KB)

This shows it. And there is script involved, and it could be the issue, but I cannot see how, or where, it is storing the DOM’s last position for it to jump to it as soon as the dragging starts. You can see this in the vid above.

Very odd.


(Greg) #9

Try disabling the script to see if that fixes the drag issue


(Andrew) #10

It does not do it if the script is disabled, but again, the script does not touch the DOM, it only reads the getBoundingClientRect() which cannot be set. So I don’t understand why it’s doing it.

But can you see it doing it now ?


(Greg) #11

I can see it in your movie, but not on any local tests I have tried.


(Andrew) #12

Thats interesting, are you using Chrome or Safari ?

I know why it’s doing it, but not how.

If I attach gesture event == move, and then console.log the css top, it does not cancel out once you end the drag, is saves the last cords. When I pick up the element again and move it, it jumps to its last cords.

@Daniel What does gesture Cancel mean, and how do I reset the drag ?


(Greg) #13

Safari only, have not tried it in other browsers


(Andrew) #14

I am using Safari and I am getting this issue. How odd and very frustrating :frowning:

It jumps the second I move the element, so it knows the DOM is at 0px as the animate takes it back, but the move event still thinks its at the last point I let go.

I have no idea how to fix it yet!!


(Greg) #15

Can you post the script you are using?


(Andrew) #16

I can see why it is doing it. Because the element pings back to its original position, or animates in this case, the gesture is not being caught, and so remains as it was, when I let go.

For example:

  1. The element top was at 0px
  2. I move it, via drag, to 100px and let go,
  3. The element animates back to 0px,

But the gesture ‘move’ does not see it go back. So thinks it is at the last place I let go. The second I move it again, it jumps the element to where it was.

So I need to be able to reset the gesture event ?

//*********************************  LETTER PICKED UP ***********************************//	
	var home;
	var homeid;
	//var letter  = $(element).attr('class').substr(20, 1);
	var letterC = null;

	if(event['hypeGesturePhase'] == "start") {
		letter_left = $(element).css('left');
		letter_top = $(element).css('top');
	}
	
	$.each($(element).closest('.HYPE_scene').find('.home_' + element.innerHTML +':not(.used)'), function(ind, homes) {
		
		var homeLeft = $(homes).offset().left;	
		var elementLeft = $(element).offset().left;
		var farHome = Math.max(elementLeft, homeLeft)
		var closeHome =  Math.min(elementLeft, homeLeft);	
		
		if(closeHome < farHome) {
			home = homes;		
			homeid = homes.id;
		}
	});
	
	home = document.getElementById(homeid);
	letter = element.innerHTML;		
	letterC = element.getBoundingClientRect();

	try {	
		var homeC = home.getBoundingClientRect();
	}
	catch(err) {
		var homeC = 0;
		//There was an error - Likely Letter not needed
		//console.log(err);
	}
	
//*********************************  LETTER MOVING ***********************************//
	if(event['hypeGesturePhase'] == "move") {
		console.log($(element).css('top'));
	}


	
//*********************************  LETTER LET GO ***********************************//
	
	// ***** Letter is dropped ********** //
	if(event['hypeGesturePhase'] == 'end') {
		// Count moves	
		var attemptsBox = $(element).closest('.HYPE_scene').find('.attempts');
		var atts = parseInt(attemptsBox.text());	
		atts++;			
		attemptsBox.text(atts);
	
		// Check distance from letter too unused home
		
		if(Math.abs(letterC.left - homeC.left) <= 30 && Math.abs(letterC.top - homeC.top ) <= 30) {
		
			// Close enough
			home.style.backgroundColor  = 'green';
			element.style.display = 'none';
			$(home).addClass('used');
		
		} else {
			
			// Send letter back to starting point
			$(element).animate({ 
        		top: letter_top,
        		left: letter_left,
     		 }, 800, function() {
    			// Animation complete.
    			$(element).css('top', 0);
				$(element).css('left', 0);		
				window.restCords = 'A';			
  			});
		}
	
		// Check word is completed	
		var ccount = 0; var letterCount = $(element).closest('.HYPE_scene').find('.letter').length;

		$.each($(element).closest($('.HYPE_scene')).find('.used'), function(ti, va) {
			if(va.style.backgroundColor == 'green') {
				ccount++;
			}		
		});
				
		if(ccount == letterCount) {
			hypeDocument.startTimelineNamed('buttonShow', hypeDocument.kDirectionForward);
			var thumb = hypeDocument.getSymbolInstancesByName("hollie_2_thumbs");
			thumb.startTimelineNamed("Main Timeline", hypeDocument.kDirectionForward);		}	
	}

#17

Here’s how gesture cancel works: How can we use HypeGesturePhaseCancel .

@stephen can help out with the finer points of the Drag events. I’m not sure why this is happening.


(stephen) #18

Unfortunately there isn’t currently a way to prevent this. We haven’t yet exposed an API to update the position of an element. You will either need to use your own dragging code or update the position of the element using timelines. For some cases, if the set of final positions is finite, you can use relative timelines to move the element to the proper place after a drag.

Adding a javascript API to get and set element properties is definitely something we would like to add at some point.


(Andrew) #19

Just to confirm. I would need a time line for each letter, which is a lot of timelines, or can a timeline be used based on the last DOM used?

Which also then adds to the question, would a timeline do it? The DOM knows its at a top 0px left 0px when the animate finishes. The issue only kicks in when the DOM is dragged again.

Would the timeline update the gesture API? Based on the huge amount of testing, and using different methods of returning the DOM after the dragging ends, I see the same issue. It looks like the gesture == move is encased and so no available to be manipulated by anything ?

Lots of questions, but I have spent a few days on this bug now, and if it just will not work, ill need to think of something else :frowning:


(Andrew) #20

Same issue with a timeline too. As there are no properties for the drag event move to manipulate.

This is a massive down side to dragging in Hype, but what is confusing more is @gasspence does not have the same issue?