Controlling onDrag position after releasing

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

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 ?

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

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 ?

Safari only, have not tried it in other browsers

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!!

Can you post the script you are using?

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);		}	
	}

Here's how gesture cancel works: How can we use HypeGesturePhaseCancel - #5 by Daniel .

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

1 Like

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.

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:

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?

I haven't tried a test using the script you posted, but when I run the "Spelling.app" I do not see the tiles with the letters in them snap back.

Okay Greg, thank you :smile:

@Stephen is there really no way to reset the gesture API, or change the current value of it ? Timelines seem to have the same problem. The down side leaving it as it is, is that you can have many wrong letters all over the place and thus making it difficult for a child to spell.

Running a timeline that moves the element will update its position in Hype. This means if you play a timeline and then drag the element it will correctly drag from its current position. So you can have a drag end play a Relative Timeline which will move the element from its current position to the final position. Then the next drag should work correctly.

Let me know if you are seeing something different.

1 Like

I did try that, as I said above, it does not seem to update the gesture move position. The element it self is updated, but the second you drag it, it goes to its last position on drag.

Using relative timelines did not, from my understanding, change the position stored in gesture move. The timeline played, but nothing happened, as it was moving, as far as it was concerned, from top 0px, left 0px to top 0px left 0px.

It is not the element, Hype seems to know the element is at 0px top and left, but gesture move, it does not. And I did a number of tests to using logical statements in gesture move, start and end to demonstrate this.

It is very odd, as would needing to have 26 timelines, one for each letter.

Could you send me your Hype Document so I can take a look?

I agree it isn’t ideal, we definitely would like to add a real Javascript API which would allow you to set values, making this situation a lot easier to deal with. For your situation it may be easier to write javascript to handle the drag instead of using the Hype drag handler.

Hi Stephen, thanks for taking a look. I PM’ed you the file.

If I have to use my own javascript to create a drag event, it would mean I would have to take it out of Hype. I do not want load to consist of unused code, and this would be the case.

I tend to build in Hype when, pretty much, all of its ability is used. If I do not use much of it, I tend to build it from scratch.

Is this on your roadmap for a future update, and if so, can you hint at time frames?

It is definitely on our road map, but unfortunately I can’t promise a date yet. Thanks for letting us know this feature is important, it helps us plan our future updates.