IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

React Discussion :

drag and drop: faire un rendu fluide pour des blocs de différentes hauteur


Sujet :

React

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2020
    Messages
    280
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2020
    Messages : 280
    Par défaut drag and drop: faire un rendu fluide pour des blocs de différentes hauteur
    Bonjour, et bonne année à toutes et tous...

    Comme indiqué dans le titre, je m'essaye au drag and drop avec React ( sans librairie: pour apprendre ! )

    Je déplace donc des blocs ( éléments <li>) dans une liste de repas (contenant des ingrédients)
    De base, mes éléments ont tous la même hauteur (même nombre d'ingrédients), donc le drag and drop est fluide entre ces éléments.

    Mais si je rajoute un repas, celui-ci ne contenant pas d'ingrédients, sa hauteur est plus petite ! Du coup,
    le déplacement est moins fluide lorsque que l'on passe sur un autre élément.

    Je partage mon code simplifié ici
    J'ai enlevé du code et des fonctionnalités pour me concentrer sur le problème du moment.

    Donc ajoutez un repas et faites glisser ce repas où vous voulez: "tremblements" logiques pendant le glissé sur un autre élément à cause de la taille différente

    Je n'ai pas vraiment de pistes: j'avais essayé d'enregistrer la hauteur du (petit) repas puis de lui donner la taille de l'élément sur lequel il glissait
    et enfin de lui redonner sa taille lors du dragEnd. Mais je ne sui pas satisfait du résultat.
    Peut-être n'est-ce pas la bonne solution, ou alors je ne l'ai pas fait correctement.

    Si vous avez des pistes, je vous remercie par avance.
    Et si vous voyez également un moyen de faire le drag and drop plus simple ou plus dans les règles de l'art...
    Je remarque aussi que si je sors de la zone (<ul>) pendant le glissement, le rendu n'est pas propre:
    l'ombre retourne au point de départ, alors que l'élément s'affichera à la place où on l'a déposé...

    Laurent.

    P.S: désolé pour le css, ce n'est pas mon souci du moment et j'avoue ne pas vraiment être un artiste à ce niveau.

  2. #2
    Membre chevronné
    Homme Profil pro
    Urbaniste
    Inscrit en
    Août 2023
    Messages
    387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Urbaniste

    Informations forums :
    Inscription : Août 2023
    Messages : 387
    Par défaut
    Bonjour,

    Il faut sauvegarder les coordonnées des cibles au drag start
    puis utiliser ces dernières pour détecter le swap lors d'un hover.

    Cela permet d'éviter d'avoir des zones cibles dont les positions
    changent en permanence, et donc l'effet de scintillement disparaît.

    Bonne journée.

  3. #3
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 212
    Par défaut
    Bonjour,
    Donc ajoutez un repas et faites glisser ce repas où vous voulez: "tremblements" logiques pendant le glissé sur un autre élément à cause de la taille différente
    ...
    Si vous avez des pistes, je vous remercie par avance.
    un moyen simple est d'ajouter une hauteur minimale à tes éléments name
    Code css : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    .name {
      width: 150px;
      border: 1px solid black;
      background-color: rgb(58, 52, 52);
      margin: 10px;
      padding: 3px;
      color: white;
      min-height: 12em;   /* par exemple */
    }

  4. #4
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2020
    Messages
    280
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2020
    Messages : 280
    Par défaut
    Ce serait pratique de définir une hauteur minimale !
    Mais le bouton ajouter un aliment ( qui est fonctionnel sur mon ordi ) permet d'ajouter autant d'aliments que l'on souhaite.
    J'ai donc essayé d'améliorer nom code

    Nouvelle variable:
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    const [mealsList, setMealsList] = useState(null)

    Initialisée dans le dragStart:
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    setMealsList(document.querySelectorAll(".name"))

    Utilisée dans le dragOver:
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    mealsList[draggedIndex].style.height = `${mealsList[index].offsetHeight}px`

    Puis dans le dragEnd:
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    Array.from(mealsList).map(element => element.removeAttribute('style'))

    Dans le sens "glisser vers le haut" un repas vide d'aliments, le rendu est fluide.
    Mais lorsqu'il faut redescendre, la taille de l'élément augmente d'abord ( d'où un effet de pousser vers le bas de la cible ) et ensuite on va pouvoir glisser.

    Ce serait mieux dans l'ordre inverse, mais je ne vois pas comment m'y prendre.

  5. #5
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 212
    Par défaut
    Une autre approche peut-être.

    Décaler via un translate de l'élément survolé de la hauteur de l'élément en déplacement.

    Je te livre la fonction handleDragOver qui semble fonctionner, pas testé en plein, il faudrait sûrement voir les conditions pour le décalage.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
      const handleDragOver = (e, index) => {
        e.preventDefault();
     
        const mealList = document.querySelectorAll(".name");
     
        if (index !== draggedIndex) {
          mealsList[draggedIndex].style.translate = "0";      
     
          mealList[draggedIndex].classList.remove("dragging");
          mealList[index].classList.add("dragging");
     
          const updatedMealList = [...meals];
          const temp = updatedMealList[index];
          // décalage de l'élément survolé
          let sens = 1;
          const top1 = mealsList[index].offsetTop;
          const top2 = mealsList[draggedIndex].offsetTop;
          if(top1 > top2) sens *= -1;
          const decalage = mealsList[draggedIndex].offsetHeight * sens;
     
          mealsList[index].style.translate = `0 ${decalage}px`;
     
          updatedMealList[index] = updatedMealList[draggedIndex];
          updatedMealList[draggedIndex] = temp;
     
          //mealsList[draggedIndex].style.height = `${mealsList[index].offsetHeight}px`
     
          setMeals(updatedMealList);
          setDraggedIndex(index);
        }
      };

  6. #6
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 212
    Par défaut
    En relisant la réponse je me rend compte que tu gères l'essentiel sur le onDragOver, événement répété en boucle tant que l'on est sur un élément cible, il serait plus judicieux de faire cette gestion sur le onDragEnter.

Discussions similaires

  1. Réponses: 6
    Dernier message: 18/12/2007, 09h16
  2. Faire bouger un clip (simple drag and drop)
    Par yoyot dans le forum ActionScript 3
    Réponses: 3
    Dernier message: 15/12/2007, 20h13
  3. Meilleur méthode pour du drag and drop ASP.NET
    Par sspizer dans le forum ASP.NET
    Réponses: 1
    Dernier message: 20/07/2007, 14h10
  4. Drag and drop pour control en VBA
    Par cbleas dans le forum VBA Access
    Réponses: 2
    Dernier message: 10/03/2007, 10h30
  5. Faire un drag and drop depuis IE vers un TListView
    Par ALEX77 dans le forum Composants VCL
    Réponses: 8
    Dernier message: 11/11/2004, 15h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo