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 :

Placer un cercle svg au bon endroit sur une image


Sujet :

JavaScript

  1. #1
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2018
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2018
    Messages : 166
    Points : 61
    Points
    61
    Par défaut Placer un cercle svg au bon endroit sur une image
    Ce sujet fait suite à celui-ci

    Résumé de ma recherche : je souhaite réaliser un jeu où le joueur clique sur des éléments d'une image et rentre une réponse, si celle-ci est juste, il marque des points si elle est fausse il perd des vies.
    Je souhaite à présent faire apparaitre les réponses justes sur un radar (pour que le joueur est une vision d'ensemble de toutes les réponses trouvées).

    Le click sur le radar fait apparaitre l'image du jeu en noir et blanc.

    Le jeu

    A cette étape, j'imagine donc qu'il faut que je lui dise de placer un rond (en svg?) à l'endroit où il y avait une map area (qui n'est pas forcément ronde).
    Je pense donc que je dois créer une variable dans la partie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    if (result === elClicked["dataset"]["nom"]) {
        let win;
          win="Bravo, c'était bien "+elClicked["dataset"]["nom"];
            // diffère l'affichage de la boîte alert
        setTimeout(() => alert(win), 100);  
        compt += 10;
        document.getElementById("champDuPrompt").innerHTML = compt;
        // (1) suppression de l'écouteur
        elClicked.removeEventListener("click", fonctionSurClic);  // fonctionSurClic est le nom de la fonction appelée
      }
    cette variable doit donner les coordonnées pour un affichage dans la fonction setStateImageFond. Et celle-ci affichera le svg.

    Mon raisonnement tient-il la route?

  2. #2
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2018
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2018
    Messages : 166
    Points : 61
    Points
    61
    Par défaut
    Est-ce que je peux récupérer les coordonnées du premier point d'une forme définit par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    elCliked["dataset"]["nom"]
    ?

    Si c'est le cas, peut-être je peux demander de tracer un cercle en svg à ce point précis.

  3. #3
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 048
    Points : 44 562
    Points
    44 562
    Par défaut
    Bonjour,
    Citation Envoyé par bahh66
    Est-ce que je peux récupérer les coordonnées du premier point d'une forme définit par elCliked["dataset"]["nom"]?
    oui elles sont dans l'attribut coords, pour les rectangles c'est le plus simple puisque avec x0, y0, x1 ,y1, x0 correspond à left et y0 à top.

    Pour les polygones cela peut être différent l'ordre n'aillant pas plus d'importance que cela.

    Pour les cercles c'est comme pour les rectangles.

    Si c'est le cas, peut-être je peux demander de tracer un cercle en svg à ce point précis.
    Pourquoi du SVG quand une simple <div> peut suffire ?

  4. #4
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2018
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2018
    Messages : 166
    Points : 61
    Points
    61
    Par défaut
    Bonjour NoSmoking,
    du coup ça donne quoi?

    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
    if (result === elClicked["dataset"]["nom"]) {
    /* je définis un élément qui est associé à la map area["dataset"]["nom"]*/
     
    let cerclereponse= document.getElementById("elClicked["dataset"]["nom"]").coords ;
     
     
        let win;
          win="Bravo, c'était bien "+elClicked["dataset"]["nom"];
            // diffère l'affichage de la boîte alert
        setTimeout(() => alert(win), 100);  
        compt += 10;
        document.getElementById("champDuPrompt").innerHTML = compt;
        // (1) suppression de l'écouteur
        elClicked.removeEventListener("click", fonctionSurClic);  // fonctionSurClic est le nom de la fonction appelée
      }
    pour le tracé du cercle, tu me parles d'utiliser une div? Avec border-radius:50%?
    Je pensais utiliser cerclereponse pour lui dire où le tracer.

  5. #5
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 048
    Points : 44 562
    Points
    44 562
    Par défaut
    du coup ça donne quoi?
    Ça donne quoi quoi ?

    Tu récupères l'élément <area> qui t'intéresse :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const elemArea = document.getElementById("id-area");
    ..grand classique mais d'autres méthodes peuvent être utilisées.

    Tu récupères la valeur de l'attribut coords :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const strCoords = elemArea.getAttribute("coords");
    ... la méthode getAttribute() va te retourner une String

    Tu converties cette String en Array :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const tabCoords = strCoords.split(",");
    ... on utilise la méthode classique split().

    Enfin les positions left et top sont aux indices 0 et 1 de ton tableau :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    const left = tabCoords[0];
    const top = tabCoords[1];
    ... aux restrictions prêtes que j'ai déjà indiquées.

    Il ne te reste plus qu'a créer et à positionner une <div> à cette position :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    const elCircle = document.createElement("DIV");
    elCircle.style.left = left + "px";     // il faut ajouter l'unité pour utiliser pour style 
    elCircle.style.top = top + "px";
    elCircle.style.position = "absolute";  // pour qu'il puisse être correctement placé
    // et enfin ajout au parent prévu
    elementDestination.append(elCircle)
    Voilà qu devrait te permettre de poursuivre.

    Nota : pour tout ce qui est cosmétique, border, color..., tu peux passer par l'ajout d'une classe CSS.

  6. #6
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2018
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2018
    Messages : 166
    Points : 61
    Points
    61
    Par défaut
    Ça donne quoi quoi ?
    je pensais être clair, ça donne quoi était pour le code qui était en dessous du coup.

    J'ai essayé d'utiliser les codes que tu as super bien expliqué.
    Mais il y a quelque chose que je ne comprends quand même pas.

    Tu récupères les coordonnées de l'area (id-area doit être remplacé par le nom de l'area, non?) et tu les mets dans un tableau.
    Tu crées une div à cette position.

    Mais tout ceci tu le fais à quel moment, uniquement quand la bonne réponse est donnée ou n'importe quand? Du coup je l'ai mis dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (result === elClicked["dataset"]["nom"]) {
    mais ça m'a l'air pas à sa place
    Je me dis aussi qu'il faudrait que la div soit plutot dans la fonction setStateImageFond, vu que le cercle ne s'affiche que sur l'image en noir et blanc normalement?

  7. #7
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 048
    Points : 44 562
    Points
    44 562
    Par défaut
    Tu récupères les coordonnées de l'area (id-area doit être remplacé par le nom de l'area, non?) et tu les mets dans un tableau.
    Tu crées une div à cette position.
    Oui c'est exactement cela !

    Mais tout ceci tu le fais à quel moment, uniquement quand la bonne réponse est donnée ou n'importe quand ...
    Effectivement, tu ne crées le point que si la réponse est bonne, tu as mis l'instruction de création au bon endroit.


    Je me dis aussi qu'il faudrait que la div soit plutot dans la fonction setStateImageFond,
    Encore exact, tu affiches l'overlay, la <div> contenant les points, qu'à la demande d'affichage, enfin c'est ce que j'ai compris de ce que tu voulais faire.

    Pour info j'ai posté : Rendre une <area> responsive, il y a des choses qui peuvent potentiellement t'intéresser

  8. #8
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2018
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2018
    Messages : 166
    Points : 61
    Points
    61
    Par défaut
    Pour info j'ai posté : Rendre une <area> responsive, il y a des choses qui peuvent potentiellement t'intéresser
    Tu essaies d'anticiper mes questions ou tu en as marre que j'en pose?

    Trêve de plaisanterie, j'ai bien regardé le doc que tu as mis (ultra complexe pour moi) et je ne vois pas comment adapté.

    J'ai mis ceci :
    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
    if (result === elClicked["dataset"]["nom"]) {
     
        let win;
          win="Bravo, c'était bien "+elClicked["dataset"]["nom"];
            // diffère l'affichage de la boîte alert
        setTimeout(() => alert(win), 100);  
        compt += 10;
        document.getElementById("champDuPrompt").innerHTML = compt;
        // (1) suppression de l'écouteur
        elClicked.removeEventListener("click", fonctionSurClic);  // fonctionSurClic est le nom de la fonction appelée
     
     
     
          const elemArea = document.getElementById(["dataset"]["nom"]);
          const strCoords = elemArea.getAttribute("coords");
          const tabCoords = strCoords.split(",");
          const left = tabCoords[0];
          const top = tabCoords[1];
          const elCircle = document.createElement("DIV");
          elCircle.style.left = left + "px";     // il faut ajouter l'unité pour utiliser pour style 
          elCircle.style.top = top + "px";
          elCircle.style.position = "absolute";  // pour qu'il puisse être correctement placé
          // et enfin ajout au parent prévu
          elementDestination.append(elCircle)
     
      }
    j'ai donc essayé de donner id-area : ["dataset"]["nom"] mais je suis pas sur de moi

    et puis je suis bloqué ici :
    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
    function setStateImageFond(on) {
      const imgRadar = document.getElementById("img-radar");
      const imgFond = document.getElementById("img-fond");
      const oSuivi = document.getElementById("play-state");
      if (on) {
        imgRadar.classList.remove("stop-animation");
        imgFond.classList.remove("img-disabled");
        oSuivi.style.display = "initial";
     
          //affichage du cercle
     
     
     
     
      }
      else {
        imgRadar.classList.add("stop-animation");
        imgFond.classList.add("img-disabled");
        oSuivi.style.display = "none";
      }
    }
    pour l'affichage du cercle créé si le résultat est juste, tu utilises dans ton document une fonction createOverlay (si je ne me trompe pas)? Mais moi je n'en ai pas de telle, dois-je en créé une?
    Je suis un peu perdu car ton code parle de redimensionnements des area en fonction de l'image de départ il me semble et du coup je n'arrive pas à en extraire les infos qui me sont nécessaires.

  9. #9
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 048
    Points : 44 562
    Points
    44 562
    Par défaut
    Tu essaies d'anticiper mes questions ou tu en as marre que j'en pose?
    Non uniquement que ta préoccupation m'a rappelé que j'avais, suite à une « analyse expérimentale », cette source à mettre au propre.
    Cela n'empêche que cela te montre ce que l'on peut faire « simplement » même si cela peut paraître compliqué au premier abord !

    Ce que tu veux faire est de rajouter un point correspondant à la zone cliquée.
    Il te faut pour cela deux choses au minimum, savoir comment les réaliser. et où mettre ces éléments.

    Je t'ai fourni l'essentiel ... mais ...

    Tout d'abord, où mettre les éléments, on va opter pour un conteneur particulier.

    Dans ton code HTML il faut donc ajouter un élément par exemple, en reprenant la dernière construction que je connais :
    Code html : 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
    <div class="cadre-image">
      <!-- image fond de jeu -->
      <img id="img-fond" usemap="#testmap" src="image-de-fond.jpg">
      <!-- conteneur ou image -->
      <div id="img-radar"></div>
      <!-- bandeau de suivi -->
      <div id="play-state" class="container">
        Score : <span id="champDuPrompt"></span>
        Vies : <span id="nbdevies"></span>
        <div class="svg-heart">
          <svg><use href="#empty-heart"></use></svg>
          <svg><use href="#empty-heart"></use></svg>
          <svg><use href="#empty-heart"></use></svg>
        </div>
      </div>
      <!-- overlay pour les points -->
      <div id="img-overlay-point"></div>
    </div>
    .. donc ajout d'un conteneur <div id="img-overlay-point"> pour recevoir les points crées.

    Attachons nous tout de suite au CSS pour le conteneur et les points, cela pourrait être :
    Code css : 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
    #img-overlay-point {
      display: none;
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      pointer-events: none;
    }
    #img-overlay-point .img-point {
      position: absolute;
      box-sizing: border-box;
      width: 1em;
      border: .25em solid currentColor;
      border-radius: 50%;
      font-size: 1em;
      color: #F00;
      transform: translate(-50%, -50%);
      pointer-events: inherit;
      aspect-ratio: 1 /1;
    }
    ... je ne pense pas qu'il y ait des choses trop compliquées la dedans

    Plutôt que de mettre le code dans la fonction définie sur le clic, on va créer une fonction d'ajout des points, addPointOnImage à laquelle on va passer en paramètre la zone <area> concernée :
    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
    function addPointOnImage(area) {
      // récup. infos traitement
      const elementDestination = document.getElementById("img-overlay-point");
      const strCoords = area.getAttribute("coords");
      const tabCoords = strCoords.split(",");
      const left = tabCoords[0];
      const top = tabCoords[1];
      // création du point
      const elCircle = document.createElement("DIV");
      elCircle.classList.add("img-point");
      elCircle.style.left = left + "px"; // il faut ajouter l'unité pour l'utiliser avec style
      elCircle.style.top = top + "px";
      // et enfin ajout au parent prévu
      elementDestination.append(elCircle);
    }
    ... je pense que tu reconnais le code fourni, il te manquait le conteneur destination.

    Où mettre cette fonction, à la place du code que tu as mis dans la fonction, ni plus ni moins, cela devient plus clair ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    if (result === elClicked["dataset"]["nom"]) {
      let win;
      win = "Bravo, c'était bien " + elClicked["dataset"]["nom"];
      // diffère l'affichage de la boîte alert
      setTimeout(() => alert(win), 100);
      compt += 10;
      document.getElementById("champDuPrompt").innerHTML = compt;
      // (1) suppression de l'écouteur
      elClicked.removeEventListener("click", fonctionSurClic); // fonctionSurClic est le nom de la fonction appelée
      // ajout création d'un point sur l'image
      addPointOnImage(elClicked);     elClicked est la zone AREA
    }
    Pour finir, concernant la fonction setStateImageFond, il faut prendre en compte le conteneur des points soit :
    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
    function setStateImageFond(on) {
      const imgRadar = document.getElementById("img-radar");
      const imgFond = document.getElementById("img-fond");
      const oSuivi = document.getElementById("play-state");
      const oPoint = document.getElementById("img-overlay-point");
      if (on) {
        imgRadar.classList.remove("stop-animation");
        imgFond.classList.remove("img-disabled");
        oSuivi.style.display = "initial";
        oPoint.style.display = "none";
      }
      else {
        imgRadar.classList.add("stop-animation");
        imgFond.classList.add("img-disabled");
        oSuivi.style.display = "none";
        oPoint.style.display = "initial";
      }
    }
    ... tous ceci pourrait être factorisé et/ou géré directement via le CSS.

    Dernier point, pour vraiment finir :
    Je suis un peu perdu car ton code parle de redimensionnements des area
    Il est important au départ de savoir si ton image a des dimensions fixes ou pas (responsive donc), cela peut en effet modifier la façon de gérer la position des points affichés, en px ou en %.


    Voilà j’espère avoir était clair et que tu va t'en sortir pour intégrer (et comprendre) tout cela

  10. #10
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2018
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2018
    Messages : 166
    Points : 61
    Points
    61
    Par défaut
    J'ai compris l'essentiel de ce que tu as mis, même si certains éléments ne me sont pas du tout naturels.

    J'ai vraiment du mal à penser à des trucs comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      const oPoint = document.getElementById("img-overlay-point");
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        oPoint.style.display = "none";
    En tout cas ça fonctionne.
    Jeu avec balise radar

    Merci

    PS : pour le redimensionnement, je ne sais pas si je vais devoir m'y atteler vu que ce n'est pas la taille de l'image qui va changer mais plutôt la taille de l'écran du joueur (mais j'aborderai le sujet dans un autre topic )

  11. #11
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2018
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2018
    Messages : 166
    Points : 61
    Points
    61
    Par défaut
    Je rouvre le sujet suite à une modification importante du code pour pouvoir adapter les boites de dialogue.

    Le code tel qu'il est maintenant est ici.https://codepen.io/foreach-chance/pen/qBYeYGq

    J'ai essayé d'adapter les deux codes mais l'image principale étant passée en css, je ne sais plus définir la balise id=img_fond.
    Et donc le code pour la mise en place du radar ne fonctionne plus.

  12. #12
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 048
    Points : 44 562
    Points
    44 562
    Par défaut
    Citation Envoyé par bahh66 Voir le message
    Je rouvre le sujet suite à une modification importante du code pour pouvoir adapter les boites de dialogue.
    il est préférable d'ouvrir une nouvelle discussion, le contexte est différent, même si des éléments pourraient être identique. Peut-être te faut-il repenser la structure même de ton code, mais pas regardé le lien.

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

Discussions similaires

  1. Placer des points sur une image
    Par vallgui dans le forum WinDev
    Réponses: 9
    Dernier message: 22/01/2008, 15h19
  2. placer des balise xml au bon endroit dans le fichier existant.
    Par calimero91 dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 07/01/2008, 09h43
  3. placer un filtre de couleur sur une image
    Par mm2405 dans le forum Traitement d'images
    Réponses: 2
    Dernier message: 06/12/2007, 11h25
  4. placer du texte sur une image
    Par sandytarit dans le forum Balisage (X)HTML et validation W3C
    Réponses: 10
    Dernier message: 23/12/2006, 14h38
  5. Réponses: 8
    Dernier message: 07/08/2006, 17h40

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