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

JavaScript Discussion :

drag & drop et collision


Sujet :

JavaScript

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2018
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2018
    Messages : 46
    Par défaut drag & drop et collision
    Bonjour,

    Je suis en train de développer un site web.

    Cependant, j'aimerais faire quelque chose mais je ne sais pas du tout comment m'y prendre.

    Voici ce que je veux faire :

    En fait, sur ma page web, il y aura une zone (assez grande)

    Dans cette zone, il y a des formes de différentes couleurs qui sont disposées mais celles ci ne se chevauchent pas. Les formes seraient des rectangles de différentes tailles qui s'encastreraient comme dans une puzzle.

    L'utilisateur va configurer la forme qu'il veut et va l'ajouter dans la zone.

    J'aimerais que l'utilisateur, avec un drag and drop, puisse déposer sa forme dans la zone.

    Cependant, (à partir de là, je ne vois pas comment faire) l'utilisateur ne peux pas déposer sa forme sur une forme déjà existante.

    De là, il y a 2 solutions

    La première est de simplement bloquer le drop si la forme est sur une forme déjà présente. (avec une gestion de collision)

    La deuxième, ma préférée, est de faire en sorte de déplacer les formes déjà présentes dans la zone, en les décalant sur les côtés (toujours sans qu'elles ne se chevauchent) afin de toujours laisser une zone libre pour que l'utilisateur puisse déposer sa forme.

    J'espère que je suis assez clair.

    N'hésitez pas à me demander pour plus de précision.

    En sachant, que je préférerais faire la seconde solution.

    J'ai déjà pensé utiliser les librairies javascript déjà présentes :

    https://draggabilly.desandro.com/ (pour le drag and drop)

    https://interactjs.io/ (pour le drag and drop)

    https://konvajs.org/docs/sandbox/Col...Detection.html (pour la gestion de collision pour la solution 1)

    Auriez vous une idée de comment faire la solution 2 ?

    Je vous remercie par avance de votre réponse.

    Cordialement

    Sybess

  2. #2
    Membre expérimenté
    Inscrit en
    Août 2006
    Messages
    191
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 191
    Par défaut
    Salut,

    Y a du boulot mais le projet est sympa.

    Les formes que tu souhaites déplacer sont elle de forme approchante ou complétement différentes ? (genre étoile, rectangle, triangle, ...)

    Sinon tu peux commencer par la solution 1 car la solution 2 n'est qu'une évolution de la solution 1 et dois aussi passer par le contrôle des collisions avant de proposer un alignement sur arrête.

    En gros, dans la solution 1, tu détectes la collision au moment ou tu drop.

    Dans la solution 2, tu testes la collision au moment ou tu bouge ta souris.
    Puis tu appliques une limite de déplacement alignée sur les points de collision.

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2018
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2018
    Messages : 46
    Par défaut
    Bonjour,

    Merci pour votre réponse.
    Les formes que je déplace sont des rectangles aussi.
    Je ne comprend pas votre phrase : "Puis tu appliques une limite de déplacement alignée sur les points de collision." ?
    Comment faire pour gérer toutes les formes présentes dans la zone et les faire déplacer comme il faut ?

    Cordialement
    Sybess

  4. #4
    Membre expérimenté
    Inscrit en
    Août 2006
    Messages
    191
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 191
    Par défaut
    Avec des rectangles c'est super facile.
    Les hits box rectangulaires sont les plus simples à calculer.

    en gros, c'est le fonctionnement des sprites pour un jeu.
    regarde ce tutoriel https://jeux.developpez.com/tutoriel...es-2d-simples/


    dans ton cas tu calcules si il y a collision.
    - Si non mouvement libre
    - Si oui tu cherches en quel point.
    par exemple, la forme A est en place c'est un carré de 100px positionné en x=200px et y=400px.
    tu essaie de mettre la forme B un carré de 50px en position x=175px et y=400px;
    il y a collision en x car la forme B va de 175px à 225px cela dépasse les limites de A.
    tu refuse l affichage de B à cette position mais tu l'affiches aux limites de A.
    X de B = limite en X de A - taille X de B = 200px - 50px = 150px.
    Tu affiche B en position x=150px et y=400px;

    c'est plus clair ?

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2018
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2018
    Messages : 46
    Par défaut
    Oui j'ai bien compris.
    Cependant, c'est pas tout à fait ce que j'aimerais faire.
    J'aimerais plutôt que ce soit A qui se déplace pour laisser la place à B. Et par la suite si A se déplace, il déplacerait aussi les éventuels rectangles d'à côté.
    Est ce que cela est possible ?

  6. #6
    Membre expérimenté
    Inscrit en
    Août 2006
    Messages
    191
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 191
    Par défaut
    Oui c'est possible (en vrai presque tout est possible les limitations sont plus en termes de performance)

    Au moment ou tu détectes la collision tu laisse B se dessiner normalement mais tu dois
    - soit déplacer A aux limites de B
    - soit effacer A puis le redessiner aux limites de B

    Tout dépend de la méthode utiliser.
    Tu travail dans un canvas ?

    La question qui peux se poser c'est de savoir si le mouvement de tous les blocs ne sera pas trop lourd à l affichage mais je pense que jusqu'a 5 blocs ça ne pose aucun problème.

  7. #7
    Expert confirmé
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 100
    Par défaut
    Je crois qu’on va avoir besoin de récursivité. En effet, si un rectangle a besoin de place, et calcule qu’il n’en a pas assez autour de lui, il demande alors aux autres rectangles dans le voisinage de se pousser.
    Mais ces autres rectangles, eux aussi, doivent calculer la place dans leur voisinage. Etc.

    Voici ce que je propose :
    Code pseudocode : 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
    méthode pousseToi(direction, distance) {
        calculer espace disponible
        si (espace disponible):
            se déplacer
            renvoyer "ok"
        sinon:
            si (près d’un bord):
                renvoyer "pas ok"
            sinon:
                déterminer les rectangles voisins devant libérer de l’espace
                pour chaque (voisin):
                    calculer (dir) et (dist) = la direction et la distance sur laquelle le voisin doit se déplacer
                    appeler voisin.pousseToi(dir, dist)
                    si ("pas ok"):
                        renvoyer "pas ok"
                fin pour
                se déplacer dans l’espace libéré
                renvoyer "ok"
            fin si
        fin si
    }
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  8. #8
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2018
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2018
    Messages : 46
    Par défaut
    Bonjour,
    Merci beaucoup pour vos réponse.
    Showie :
    Je travaille avec : draggabilly pour les formes et le drag and drop et konvaJs pour détecter une collision.
    Mais je n'arrive pas encore bien à me décider sur le choix entre draggabilly, interact.js ou avec un canvas.
    Auriez vous un conseil sur la meilleure techno à utiliser ?

    Watilin :
    J'ai compris en gros le principe de votre pseudo code.
    Cependant, je ne comprend pas certaines lignes.
    - calculer espace disponible (C'est calculer l'espace disponible de toute la zone ou seulement à l'emplacement de la forme à placer ?)
    - près d’un bord (c'est près d'un bord de la zone, c'est bien cela ? ou d'un bord d'une forme à côté ?)
    - calculer (dir) et (dist) = la direction et la distance sur laquelle le voisin doit se déplacer (Comment dois-je faire ceci ? parce que pour connaître la
    direction à appliquer à la forme courante, il faut savoir où se trouve un espace vide. Je ne vois pas trop comment faire)
    - A quel moment dois-je appeler pour la première fois la fonction pousseToi() ? A chaque mouvement de drag de la souris ?

    Cordialement

    Sybess

  9. #9
    Expert confirmé
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 100
    Par défaut
    Citation Envoyé par sybess Voir le message
    Watilin :
    J'ai compris en gros le principe de votre pseudo code.
    Cependant, je ne comprend pas certaines lignes.
    Je suis volontairement resté vague sur certains points car ça dépend des choix que tu as faits ou que tu vas faire.

    - calculer espace disponible (C'est calculer l'espace disponible de toute la zone ou seulement à l'emplacement de la forme à placer ?)
    Si je prends l’exemple du rectangle à déposer, il peut par exemple calculer, pour chacun de ses 4 bords, la distance horizontale ou verticale à laquelle se trouve l’objet le plus proche.

    - près d’un bord (c'est près d'un bord de la zone, c'est bien cela ? ou d'un bord d'une forme à côté ?)
    Les bords de la zone, oui, autrement dit les limites qu’aucun des rectangles n’a le droit de franchir.

    - calculer (dir) et (dist) = la direction et la distance sur laquelle le voisin doit se déplacer (Comment dois-je faire ceci ? parce que pour connaître la
    direction à appliquer à la forme courante, il faut savoir où se trouve un espace vide. Je ne vois pas trop comment faire)
    Pour faire simple tu peux calculer seulement des distances le long des verticales ou des horizontales. Le but de l’algo récursif est justement de ne pas avoir à connaître à l’avance où se trouvent les espaces vides, un rectangle demande à un voisin donné de se pousser seulement du minimum nécessaire. Il ne sait pas s’il y a de la place derrière, mais ça c’est au voisin de gérer. Par exemple, le rectangle demandeur pourrait dire « j’ai besoin que tu te pousses de 50 pixels vers la droite, débrouille-toi comme tu veux ».

    Quant à savoir dans quelle direction le voisin doit se pousser, je ne sais pas s’il y a une solution idéale, mais intuitivement je tenterais de calculer la distance entre les centres des rectangles, puis prendre le plus grand (en valeur absolue) entre x et y. Si la bibliothèque de collision que tu utilises est bien faite, elle devrait pouvoir te donner cette information, ou quelque chose de similaire.

    - A quel moment dois-je appeler pour la première fois la fonction pousseToi() ? A chaque mouvement de drag de la souris ?
    Bonne question Tu as dû deviner qu’agir sur chaque évènement 'drag', c’est un peu excessif. Il y a un exemple de temporasition d’évènements sur la page MDN scroll qui utilise requestAnimationFrame(), une fonction native cause des appels 60 ou 120 fois par seconde (selon la fréquence d’affichage de l’écran), mais tu peux aussi utiliser setTimeout pour définir ton propre délai. Par exemple, 100 millisecondes correspondent à 10 appels par seconde :
    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
    // Référence: http://www.html5rocks.com/en/tutorials/speed/animations/
     
    let ticking = false;
     
    function faireQuelqueChose() {
      // calculer les collisions, pousser les rectangles
      // ...
    }
     
    rectangle.addEventListener('drag', function(e) {
     
      if (!ticking) {
        setTimeout(function() {
          faireQuelqueChose();
          ticking = false;
        }, 100);
      }
     
      ticking = true;
    });
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  10. #10
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2018
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2018
    Messages : 46
    Par défaut
    Ok, merci beaucoup.
    Je comprend mieux maintenant.
    Je vais tester tout ça et je vous tiens au courant.
    Watilin :
    Auriez vous un conseil à me donner dans le choix de la techno à utiliser entre draggabilly, interact.js ou avec un canvas ?

    Cordialement

    Sybess

  11. #11
    Expert confirmé
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 100
    Par défaut
    Citation Envoyé par sybess Voir le message
    Auriez vous un conseil à me donner dans le choix de la techno à utiliser entre draggabilly, interact.js ou avec un canvas ?
    Je ne connais ni draggabilly ni interact.js, donc je ne peux pas te conseiller. Quant à <canvas>, il s’agit d’une technologie native, donc j’imagine que les deux biblis se basent dessus.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  12. #12
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 532
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 532
    Par défaut
    Citation Envoyé par sybess Voir le message
    J'aimerais que l'utilisateur, avec un drag and drop, puisse déposer sa forme dans la zone.
    pour faire un drag & drop tu n'as pas besoin de bibliothèques additionnelles et de construire une usine-à-gaz

    Un drag & drop qu'est-ce que c'est ? un drag & drop c'est maintenir le bouton gauche de la souris donc tant que ce bouton est maintenu enfoncé il faut déplacer la forme que tu veux à l'écran.
    Une fois que le bouton est relaché eh bien tu vas comparer le rectangle délimitant la forme déplacée ( ce que l'on appelle une "bouding box") avec celui qui de l'emplacement où laisser la forme.
    Mettons si la distance entre les centres des deux formes est faible la forme déplacée ira se placer au bon endroit
    Citation Envoyé par Watilin Voir le message
    Le but de l’algo récursif est justement de ne pas avoir à connaître à l’avance où se trouvent les espaces vides
    pas besoin forcément d'un algorithme récursif...
    il suffit de rechercher dans une liste de formes et tester par le biais d'un booléen si la forme est vide..

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Drag and drop "de l'extérieur"
    Par Invité dans le forum C++Builder
    Réponses: 12
    Dernier message: 31/03/2020, 10h10
  2. [JSP][DRAG AND DROP]
    Par hamed dans le forum Servlets/JSP
    Réponses: 7
    Dernier message: 23/01/2004, 17h36
  3. drag and drop
    Par jujuesteban dans le forum Composants VCL
    Réponses: 5
    Dernier message: 20/06/2003, 09h23

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