calimero: draggable elemente auf Website einbinden für ein bissl gamification

Als HTML Neuling möchte ich meinem Shopify Shop eine Gamification Komponente hinzufügen.

Gewünschtes Verhalten: alle Elemente sind draggable und können frei in dem Feld verschoben werden. Das Verhalten soll sich für den User ahnfühlen wie wenn er Dateien auf dem Desktop neu sortiert. Aktuelles Verhalten: die Elemente lassen sich nicht flüssig verschieben und "springen" bei Mausklick irgendwo hin. Die Draggable Funktion funktioniert leider nicht wie gewünscht. Was mache ich falsch?

https://codepen.io/calimero202/pen/KKJQNzV

  1. Hallo,

    ich habe dein Script jetzt nicht wirklich verstanden, aber wir haben da was im Wiki:

    Gruß
    Jürgen

  2. Hallo calimero,

    Drag & Drop kann man auf zwei Arten umsetzen. Zum einen mit Hilfe des draggable-Attributs von HTML5, der verlinkte Wiki-Artikel schreibt einiges darüber.

    Allerdings: dann bekommt man, so wie bei Dir, während des Drag ein "Geisterbild" gezeigt, das teiltransparent und verkleinert ist. Ein "live drag", so wie bei einem Desktop-Fenster, ist das nicht.

    Zum HTML5-Drag&Drop gehört eine entsprechende Eventbehandlung, die ist im Wiki-Artikel beschrieben.

    Das, was Du gemacht hast, ist die andere Art: Drag&Drop "handgemacht". Das bietet die Möglichkeit, HTML Elemente live zu verziehen, statt ein Drag-Image durch die Gegend zu bewegen.

    Bei Dir überlappen sich aber die beiden Techniken. <img>-Elemente sind nämlich von Haus aus HTML5-Draggable und das musst Du erstmal verhindern, damit deine eigene Logik greift. Gib jedem img Element das Attribut draggable="false".

    Nächste Punkt ist: Dein Pen ist kaputt. Was Du im Style und Script-Bereich einträgst, braucht kein <style></style> oder <script></script>. Hast Du den Pen nicht getestet?

    Weiter: Dein transform:rotate funktioniert nicht. Du setzt die Bilder in <div> Elemente. Diese sind zunächst einmal so breit wie ihr Elternelement. Die Bilder stecken aber an ihrem linken Rand. Die Rotation wirkt auf das div, nicht auf das img, und dadurch werden die Bilder an einer langen Stange gedreht, d.h. sie verschieben sich auch. Maßnahmen:

    • nimm von den Bildern das height:auto aus dem Style, das steht schon im CSS. Die width lass dran. Überlege Dir aber ein sinnvolles alt-Attribut. Diese Bilder sind NICHT rein dekorativ.
    • gib den draggable-divs per CSS ein width:fit-content;

    Sodann führst Du einen Positionskrieg. Im CSS steht, dass .draggable-Elemente position:absolute sein sollen. Da bin ich dafür. In den style-Attributen, die Vorrang vor CSS haben, machst Du das mit position:relative wieder kaputt. Wenn Du möchtest, dass diese Elemente verschiebbar sind, sollten sie absolut positioniert sein, nimm das position:relative also aus den styles der draggable-Elemente heraus. Danach musst Du die Positionen der draggable-divs neu bestimmen.

    Du rotierst die draggable-Elemente. Das führt beim Mousemove zu Rechenfehlern. Gib den .draggable divs einen schwachen Hintergrund, dann siehst du, was da passiert. Lösung: Rotiere nur die img Elemente im .draggable, dann ruckelt es beim ersten Move nicht mehr.

    Die @media-Abfrage ist übrigens verwirrend. Auf einem schmalen Viewport verschwinden die draggables komplett.

    Und dein drag-grid ist sinnlos. Die draggables sind keine Kindelemente davon.

    So, ich hoffe, ich habe jetzt alles aufgeschrieben was ich in deinem Pen gefixt habe.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. problematische Seite

      Hallo Rolf,

      wahnsinn, tausend Dank für deine schnelle und ausführliche Antwort! Ich bin ein HTML-neuling und habe versucht alles so umzusetzen wie du es geschildert hast. Alles habe ich aber offenbar nicht hinbekommen :-).

      Gute Nachricht: Der Live-Drag funktioniert, ich bin megahappy! Genau das Verhalten, dass ich haben wollte!!

      Nur eine Sache ist noch nicht ganz rund: Die Elemente verändern ihre Größe, wenn ich sie zum Beispiel in die Ecke oben rechts schiebe. Was muss ich verändern, damit die Größe der Elemente gleich bleibt?

      Und wo kann ich generell die Bildgröße einstellen? Muss ich die Bilder schon in der entsprechenden Größe hochladen?

      Ich hab jetzt ein totales High und bin total glücklich, dass es schonmal soweit funktioniert hat! Richtig cool und vielen Dank für die Unterstützung!!!

      1. problematische Seite

        Hallo calimero,

        Die Elemente verändern ihre Größe, wenn ich sie zum Beispiel in die Ecke oben rechts schiebe. Was muss ich verändern, damit die Größe der Elemente gleich bleibt?

        Ja, hm, der Effekt ist mir auch noch nicht begegnet. Offenbar verkleinert der Browser das Bild, wenn Du es nach rechts und nur nach rechts aus dem Viewport schieben willst. Und der width:fit-content des draggable div macht dann alles kleiner.

        Ich finde im Moment nur eine Umgehungslösung: Verpasse dem style-Attribut des jeweiligen .draggable div die gewünschte width für das Bild, und gib dem Bild im CSS eine Breite von 100%. Dann bleibt die Größe fix.

        Und wo kann ich generell die Bildgröße einstellen? Muss ich die Bilder schon in der entsprechenden Größe hochladen?

        Du solltest die Bilder nicht zu groß hochladen. Der Teller ist gruselig, 3800x3200px bei 600KB Dateigröße. Du kannst grob von 96 Pixel pro Zoll ausgehen, die für die Anzeige gebraucht werden. Soll das Bild auf dem Desktop-Bildschirm ca 10cm breit sein, sind das ca. 4 Zoll oder 400 Pixel. Wenn das Bild dann mit 800 Pixeln Breite hochgeladen wird, ist das das doppelte und ein Retina-Display freut sich. Dafür kannst Du dann eine stärkere Kompression einstellen, damit die Datei nicht so groß wird. Auf einem Handy ist das Bild sicherlich schmaler, da reicht's dann immer. Und deine Gamification willst Du auf kleinen Viewports eh nicht haben.

        Um die angezeigte Breite eines Bildes zu bestimmen, verwendet man NORMALERWEISE das width-Attribut des Bildes oder die CSS-Eigenschaft width. Hier hat das irgendwie mit dem fit-content des div quergeschossen. Dem Bild im CSS ein width:100% zu geben und das div auf die gewünschte Breite zu setzen ist dann der Workaround.

        Aber an der Stelle bin ich auch immer auf Kriegsfuß, vielleicht weiß @Gunnar Bittersmann was besseres (außer dem Hinweis, auf diese Sperenzchen ganz zu verzichten, weil sie in dieser Form nicht bedienbar sind).

        Rolf

        --
        sumpsi - posui - obstruxi
        1. problematische Seite

          Hallo calimero,

          Und wo kann ich generell die Bildgröße einstellen? Muss ich die Bilder schon in der entsprechenden Größe hochladen?

          Du solltest die Bilder nicht zu groß hochladen. Der Teller ist gruselig, 3800x3200px bei 600KB Dateigröße. Du kannst grob von 96 Pixel pro Zoll ausgehen, die für die Anzeige gebraucht werden. Soll das Bild auf dem Desktop-Bildschirm ca 10cm breit sein, sind das ca. 4 Zoll oder 400 Pixel. Wenn das Bild dann mit 800 Pixeln Breite hochgeladen wird, ist das das doppelte und ein Retina-Display freut sich. Dafür kannst Du dann eine stärkere Kompression einstellen, damit die Datei nicht so groß wird.

          Hier ein Grundlagen-Tutorial:

          Bilder im Internet

          Wichtig für's Grundverständnis sind die theoretischen Kapitel Deko vs. Inhalt und und Formate_und_Größen

          Herzliche Grüße

          Matthias Scharwies