How do you make an element draggable?


#1

Hello!

Can anyone explain how I can make an element draggable with the mouse?

Thanks!


#2

@d13

Make sure the element You wish to make draggable is selected.

In the “Actions Inspector” select “Control Element Position” in the “On Drag” event menu.


#3

There are plenty of topics about this.

I have this saved because it’s a good reference, do not credit me :slight_smile:

drag.hype.zip (214.3 KB)


#4

Thanks so much, that’s what I was looking for :slight_smile:


#5

@PappaSmalls Thank you, that reference file is really interesting!
It’s way, way more informative than the other drag examples I’ve seen posted, and the code is much cleaner and more understandable.
It’s very interesting that the code bypasses Hype’s onDrag handler’s and just uses jQuery UI - nice and simple :grinning:

As a completely new Hype user (but an experienced JS programmer) I have two more follow-up questions:

  1. Is it generally a good idea to use the Scene’s onLoad event to add scripts that control or target the elements in that scene.

  2. Can anyone point me to any equally succinct example of a drag-and-drop system using drop targets - or should any jQuery UI system work out-of-the box?

Thank-you!


(Hans-Gerd Claßen) #6

jquery methods using any kind of positioning equals in reducing hypes animationframerate.

what about this¿


#7

Hi Everyone,

I managed to solve my own problem:

dragAndDropHype.hype.zip (120.5 KB)

It’s a simple drag-drop prototype using using jQuery UI.
I’ll easily be able to extend this to handle multiple drag elements and drop targets.

UPDATE:

Just for posterity, here’s a more advanced version with multiple drop targets:

dragAndDropMany.hype.zip (128.3 KB)


(Hans-Gerd Claßen) #8

Hello d13,

there are a few disadvantages using third party js-libraries for element positioning:

  • hypes framerate will be reduced by factor 2
  • increased loading time
  • possible incompatibilities with hypes runtime

in your example you load jquery -> 80kb, jqueryui -> 240kb and you’ll additionally need the js touchpunch (hack) to make it work on mobiles. turn off css-positioning and your setup will fail. turn on responsiveness and your setup will fail.

this example will work with a completely hypesetup. theres only 2kb of code instead of 320kb++. you can use hypes own capabilities for anymating stuff. as long as you don’t need third party libraries i would always rely on hype! YouMayNotNeedJQuery :wink:

this’ll be the js-setup for ondrag of all elements to achieve the same:

//create a global object within hypes scope and append the result counter
    if(typeof hypeDocument[hypeDocument.documentId()] === 'undefined'){
    hypeDocument[hypeDocument.documentId()] = new Object(); 
    hypeDocument[hypeDocument.documentId()]['resCount'] = 0;
    };
    
    //HTMLCollection to check against
    var droppables = hypeDocument.currentSceneElement().getElementsByClassName(element.id);
    
    /*
    initialize and call the hittest. arguments: sourceElement and HTMLCollection
    returns
    HTMLElementObject, its id, its classList
    */
    var hitCheck = hypeDocument.checkOverlapping(element, droppables);
    
    
    //on dragstart store the hypeproperties of the sourcElement
    if(event['hypeGesturePhase'] === hypeDocument.kHypeGesturePhaseStart)
    {
    //store the properties to reset draggable on no drop occured
    hypeDocument.storeProperties(element);
    }
    
    
    // on move reset the opacity of all droppables, call hitCheck
    if(event['hypeGesturePhase'] === hypeDocument.kHypeGesturePhaseMove)
    {
    resetDroppables();
    if(hitCheck)hypeDocument.setElementProperty(hitCheck.element, 'opacity', 0.5);  
    }

    // on end of the drag call hitCheck ... do sthg.
    if(event['hypeGesturePhase'] === hypeDocument.kHypeGesturePhaseEnd)
    {
    if(hitCheck){
    hypeDocument.setElementProperty(element, 'left', hypeDocument.getElementProperty(hitCheck.element, 'left'), 0.3, 'easeinout');
    hypeDocument.setElementProperty(element, 'top', hypeDocument.getElementProperty(hitCheck.element, 'top'), 0.3, 'easeinout');
    hypeDocument[hypeDocument.documentId()]['resCount']++;
    if(hypeDocument[hypeDocument.documentId()]['resCount'] === 3){hypeDocument.getElementById('message').innerHTML = "You may not need JQuery ;-)"}
    }else{
    hypeDocument.resetProperties(element);
    }
    }
    
function resetDroppables()
{
var l = droppables.length
while(l--)
{
hypeDocument.setElementProperty(droppables[l], 'opacity', 1); 
}

dragAndDropHypeStyle.hype.zip (23.8 KB)


Drag and Drop for simple Quiz
Drag and Drop doesn't work on iPad
Change Scene Depending on Element's Location
#9

Thanks for that nice example Hans-Gerd!

I have a question about flexible scaling. I did put everything from your file in a group and made it to scale with windowsize. But the dragging is not synchronising with the mouse or touch (offset). What would be the secret for that?

Thanks!

Olav


(Hans-Gerd Claßen) #10

Hello Olav,

the example uses hypes builtin functionality: element->ondrag->control elementposition.

As of now it’s a known issue that it’s out of sync in responsive environments :frowning:
may be it gets a patch in the next release?!


#11

Thank you Hans Gerd,
so hopefully this will be possible in a new release. Would be great!

Thanks again!

Olav


#12

Thanks for that Hans-Gerd!
I just started using Hype a few days ago so that was very informative.

UPDATE:

Having tested this code in production on our target browsers we haven’t yet noticed any drop in Hype’s animation framerate when using jQuery, jQueryUI and Touch Punch. Also, we are using fix document sizes and scaling to different resolutions, so possible incompatibilities with responsive design has not yet been an issue for us.


(Hans-Gerd Claßen) #13

as soon as ‘css-positioning’ is checked in the documentdefaults the framerate will be reduced … and without css-positioning the jquery-setup will stop working correctly.

so if you don’t use a lot or heavy animations it#ll be no problem … for in deep details: @jonathan :wink:


#14

@h_classen thanks for the heads-up, I’ll definitely keep an eye on it :grinning:


#15

Hi @h_classen!

I have been experimenting with your excellent drag-and-drop code, noticed a bug.
If a user right-clicks one of the drag element, the element sticks to the mouse’s position.
When the left button is then clicked again, the element snaps back to a different start location.
Do you know if there’s a simple way to prevent this?

Thanks!


(Freelancer) #16

:pray: :pray: :pray: :pray: :pray: :pray:


(Hans-Gerd Claßen) #17

Hi @d13,

good shot :slight_smile:

well the brwoserbehaviour on this is inconsitent. in ff it seems to work as is.
i would expect @jonathan may have a look at it as onrightclickandmove hypes dragevent starts firing when the right click ends. this may be after a move … but it’s tricky here …

as a simple workaround you can disable the contextmenu-event for the draggable elements with preventDefault()

like this on sceneload (not tested):

    var x = document.getElementsByClassName('preventRightClick');    var l = x.length;
    while(l--){
    x[l].addEventListener('contextmenu', function(e){e.preventDefault()}, false)
    }

(Jonathan Deutsch) #18

That’s interesting… Hype calls event.preventDefault() which I would have expected to cancel the context menu from showing up in the first place since this happens after the mousedown event for the drag.

I made a fix that checks the event’s button number or if the control key is being pressed, and this will ignore the drag start (or regular mouse down/click) event. I’m assuming if you request a context menu, that’s what the user would want :slight_smile:. It’ll be in the next version; until then I’d go with @h_classen’s workaround.

I took another look at this issue. I was able to fix one case where the positioning would be incorrect when ‘Zoom Contents’ was checked. So in the next version of Hype that will be one option for flexible layout and dragging.

However in the non ‘Zoom contents’ case, the fix is simply too much code for the runtime to be worthwhile. It kills me that there’s a correctness issue where the tradeoff makes it better to not fix, but that’s the reality of the situation :frowning: . I will continue to consider options for this - perhaps the fix would only go into the full runtime, for instance. But for now, no fix is forthcoming. From documents I see, ‘zoom contents’ is very popular, so hopefully my partial fix will help a lot of cases.


#19

Thanks so much @h_classen and @jonathan!
You guys are amazing, thanks for all your help with this!
The work-around should be fine.
We’re doing a lot of drag and drop over the next few weeks, so I’ll keep you posted if I encounter any quirks.


(Hans-Gerd Claßen) #20

Hello @jonathan,

i just realized that the out of sync issue for draggable elements in responsive environments is fixed :slight_smile: in 3.6

:thumbsup: