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 :

Faire apparaitre plusieurs fois la même image aléatoirement sur la page


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 Faire apparaitre plusieurs fois la même image aléatoirement sur la page
    Bonjour,

    Je souhaite créer un jeu pour mes élèves. Le principe est assez simple (mais peut-être pas la mise en œuvre), je souhaite qu'une image s'affiche en quantité aléatoire dans des emplacements aléatoires sur la page.
    Une fois ceci fait, j'aimerai que le joueur puisse cliquer sur 10 images et qu'une "forme" (ou un sac) se trace autour de ces 10 images et ainsi de suite jusqu'à ce que toutes les images soient comptées.

    Dans ma tête, voici les étapes que j'imagine :
    1- afficher un nombre aléatoire d'images sur la page à des endroits sur la page.
    2- pouvoir cliquer (une fois et une seule) sur les images
    3- former un "cercle" (ou patatoïde) autour des images cliquées.

    Maintenant que j'ai expliqué ce que je souhaite, je reviens à l'étape 1.

    J'ai utilisé un code trouvé qui m'affiche une image aléatoirement sur la page (dès fois le coeur apparait en dehors de la page)
    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width"=head>
            <script>
            function affiche(){
            // recuperation de la resolution de l'ecran chez l'utilisateur
            largeur = screen.width;
            hauteur = screen.height;
            // positionnement aleatoire
            posx = Math.round(Math.random()*largeur);
            posy = Math.round(Math.random()*hauteur);
            
            // recuperation de l'element div servant a afficher l'image
            elementDivImage = document.getElementById("elemImage");
            // ajustement de l'attribute style, notament left et top
            elementDivImage.style.position='absolute';
            elementDivImage.style. left=posx+"px";
            elementDivImage.style.top=posy+"px";
            elementDivImage.style.width="160px";
            elementDivImage.style.height="120px";
            elementDivImage.style.Zindex="1";
            }
            </script>
     
     
        <title>Document</title>
    </head>
    <body onLoad="affiche()">
     
        <div id="elemImage" style="">
        <img src="images/coeur.png" name="image" width="160" height="120" id="image">
        </div>
     
        <div id="layer2" style="">
        <button onclick="affiche()">Coeur aléatoire</button>
        </div>
     
        </body>
     
    </html>

    Ma question est la suivante, comment je peux modifier la fonction affiche pour que j'ai 3 ou 15 ou 50 coeurs qui s'affichent

    J'imagine que je vais devoir utiliser Math.random

  2. #2
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 640
    Points : 66 663
    Points
    66 663
    Billets dans le blog
    1
    Par défaut
    If suffit de cloner dans une boucle
    https://jsfiddle.net/bnursz6f/

  3. #3
    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
    Merci SpaceFrog de ta réponse.

    J'ai légèrement modifié le code pour que le nombre de cœurs soit aléatoire.

    J'ai 3 nouvelles questions mais peut-être faut-il ouvrir un nouveau sujet, si c'est nécessaire je le ferai.

    1- Peut-on enlever le coeur initial de l'affichage, cela risque de perturber mes élèves car il ne faut pas le compter j'imagine?
    2- Dans la fonction populate(), il faut que je mette une remise à zéro de l'écran. Sinon je me retrouve avec une quantité de coeurs impressionnante. Je pensais donc créer un button restart qui réinitialise le fond à 0 coeur mais je ne sais pas comment vider l'affichage.
    3- Peut-on programmer que 2 images ne se chevauchent pas (mes élèves ont 6 ans et cela entrainera des problèmes de comptage, c'est sur)?

    Je réfléchis aux réponses à ces questions en attendant.

  4. #4
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 640
    Points : 66 663
    Points
    66 663
    Billets dans le blog
    1
    Par défaut
    Vu que cela concerne un seul et même projet, il n'est pas illogique de poursuivre dans ce post.

    https://jsfiddle.net/vdj51wt9/1/

    Pour enlever le coeur initial de l'affichage il y a deux possibilités:
    la plus simple est de le mettre en display none au départ mais de ne pas oublier de modifier le display lors du clonage
    le seconde est de ne pas le mettre dans le html et de le créer dynamiquement avec js.

    pour effacer les coeurs créés j'ai rajouté un conteneur global dédié a recevoir les coeurs, ill suffit alors de le vider des tous ses enfants (cf. fonction effacer() )

    Pour éviter le chevauchement avec le système actuel cela risque d'être un peu complexe, car il faudrait tenir un log (array) des position et vérifier que le nouvelle positon générée ne génère pas de chevauchement... à moins qu'il y ait une fonction js que je ne connais pas encore.

    Je vois trois possibilités,:
    1 - Ne pas mettre de position aléatoire, ce qui fera en sorte que les coeurs vont s'empiler à la suite dans leur conteneur, mais du coup ils seront alignés
    2 - On pourrait alors jouer sur la taille du div pour faire varier un peu les alignements
    3 - en fonction du nombre de coeurs a ajouter prévoir un tableau (balise table) avec un nombre de cases plus important et lors du clonage s'assurer que la cellule n'est pas déja occupée ... mia sles alignement seront tout de même sous forme de grille (avec des places vides)

  5. #5
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 640
    Points : 66 663
    Points
    66 663
    Billets dans le blog
    1
    Par défaut
    Sinon pour éviter le chevauchement certains se sont déja penché sur la question de façon plus approfondie
    https://gist.github.com/u01ai11/ce3f...0006ccdf96be62

  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
    Merci des réponses :

    3 - en fonction du nombre de coeurs a ajouter prévoir un tableau (balise table) avec un nombre de cases plus important et lors du clonage s'assurer que la cellule n'est pas déja occupée ... mais les alignement seront tout de même sous forme de grille (avec des places vides)
    Cela me parait être la solution la plus simple et efficace pour mes élèves. Le fait que ce soit des grilles n'est pas dérangeant vu qu'il y aura des cases vides (un tableau de 100 cases).

    En revanche pour la réalisation, j'ai cherché un peu et plusieurs solutions proposées (ici, ou encore ) me paraissent utilisable comme base mais je ne sais pas comment démarrer.

    Ma démarche envisagée:
    - créer un tableau 10x10.
    - utiliser la fonction populate()- créer une fonction verifCaseVide qui cherche si la case est vide et met l'image dans la case si c'est le cas.

    Mais je me dis qu'il faut peut être créer la fonction avant d'utiliser populate()?

  7. #7
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 640
    Points : 66 663
    Points
    66 663
    Billets dans le blog
    1
    Par défaut
    J'ai du trouver un bidouille pour ne pas pouvoir réattribuer la même cellule deux fois, en passant par un array de toutes les coordonnées que je mélange puis pop()
    https://jsfiddle.net/458eka7v/

  8. #8
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 640
    Points : 66 663
    Points
    66 663
    Billets dans le blog
    1
    Par défaut
    Petite modification
    pour prendre en compte le reset de l'array des positions au cas ou l'on appuye deux fois sur la creation des coeurs ...
    mais on pourrait aussi le blocker ...

    https://jsfiddle.net/458eka7v/1/

    en blocant la multiple création
    https://jsfiddle.net/458eka7v/4/
    avec un flag attribut data-running tru ou false

  9. #9
    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
    WOW!

    Alors c'est nickel mais c'est allé un peu vite pour moi.
    Si ca ne te dérange pas, j'aimerais revoir un peu l'utilité de chaque chose pour mieux les comprendre avant de passer à la suite.

    Code javascript : 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 createTable() {
      Table = document.createElement('table');
     
      for (i = 0; i < 10; i++) {
        line = document.createElement('tr');
        for (j = 0; j < 10; j++) {
          cell = document.createElement('td');
          cell.id = "cell" + i + "_" + j;
          line.appendChild(cell);
        }
        Table.appendChild(line)
      }
      document.body.appendChild(Table);
    }
    createTable();

    Si je comprends bien, tu définis la table en créant d'abord les lignes de 0 à 9 puis 10 cellules dans chaque ligne (que tu normes avec le css).

    Code javascript : 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
    function clonePic() {
     
      // recuperation de la resolution de l'ecran chez l'utilisateur
      largeur = window.innerWidth;
      hauteur = window.innerHeight;
      // positionnement aleatoire
      cellpos = posXY.pop();
     
      // recuperation de l'element div servant a afficher l'image
      ImageHeart = document.getElementById("elemImage").cloneNode(true);
      // ajustement de l'attribute style, notament left et top
      ImageHeart.style.width = "150px";
      ImageHeart.style.height = "120px";
      //elementDivImage.style.Zindex=increment++;
      ImageHeart.id = 'DivCoeur' + increment;
      ImageHeart.style.display = "inline-block";
     
      document.getElementById('cell' + cellpos).appendChild(ImageHeart);
     
    }

    Alors là, j'ai beaucoup de mal. Tu récupères les infos de l'image avec cloneNode, tu définis la taille de l'image.
    Mais je ne vois pas d'où sort le DivCoeur, je le retrouve plus tard dans la fonction effacer mais je ne vois pas à quoi ça sert? A repérer dans quelle case est un coeur?

    Code javascript : 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
    function populate() {
      run = document.getElementById('populate').dataset.running;
      if (run == "true") {
        return false;
      }
      document.getElementById('populate').dataset.running = "true";
      for (i = 0; i < 10; i++) {
        for (j = 0; j < 10; j++) {
          posXY.push(i + '_' + j);
        }
     
      }
      posXY.sort(() => Math.random() - 0.5);
      maxhearts = 10;
      nbrhearts = Math.ceil(Math.random() * maxhearts);
      for (p = 0; p < nbrhearts; p++) {
        clonePic();
      }
      document.getElementById('nbr').value = nbrhearts;
    }

    Là aussi, je ne comprends pas le code dataset.running.
    Bon après c'est le placement des coeurs dans les bonnes cases avec la modification du nombre de coeurs dans maxheart si je ne me trompe pas.

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function effacer() {
      allhearts = document.querySelectorAll('[id^=DivCoeur]');
      if (allhearts.length > 0) {
        for (var heart of allhearts) {
          heart.parentNode.removeChild(heart.parentNode.firstChild);
        }
        document.getElementById('populate').dataset.running = "false";
        document.getElementById('nbr').value = "";
      }
    }
    Celle si non plus je ne la comprends pas vu qu'elle réutilise DivCoeur et dataset.runningSi tu peux m'éclairer, je suis allé chercher les informations dans des leçons mais cela ne m'a guère aider.

  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 encore une question la fonction ClonePic récupère la résolution de l'écran, pourtant des coeurs continuent de s'afficher en dehors de l'écran (apparition de barre de défilement).
    Comment cela se fait? Il faut réduire la taille de largeur et hauteur?

  11. #11
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 640
    Points : 66 663
    Points
    66 663
    Billets dans le blog
    1
    Par défaut
    Dans l'ordre:

    Oui je créé un tableau 10 x 10


    Je clone bien l'image avec cloneNode
    puis je modifie son id pour le nommer DivCoeur1, DivCoeur2 etc ...
    mais j'ai oublié de l'incrémenter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ImageHeart.id = 'DivCoeur' + increment++;
    Et en effet cela me sert ensuite à récupérer les coeurs pour les supprimer


    le dataset running c'est pour mettre un flag sur le bouton de création des coeurs pour savoir si j'ai déjà clické dessus ou pas, et si oui, ne pas autoriser une nouvelle création ...
    en fait cela créé un attribut data-running="true" (ou false) sur le bouton.

    Pour l'effacement je recupère la collection des coeurs dont l'id commence par DivCoeur, ce qui me permet de boucler sur la collection pour les supprimer.
    Une fois les coeurs supprimés, je remet le flag data-running du bouton à false ce qui permet de créer à nouveau des coeurs.

    Après pour le placement des coeurs, j'ai généré un array de coordonnées que je pop pour ne pas avoir deux coeurs dans la même cellule

    Et pour terminer oui le maxheart est un paramètre pour le nombre random de coeur et definit le nombre max de coeurs à afficher.

    N'hesite pas à poser d'autres questions...

    Ha j'oubliais, pour la taille de l'écran, plus besoin car il suffira de dimensionner le tableau à 100% du width en css et de mettre les images à 100% de la taille de leur cellule.

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

Discussions similaires

  1. [Débutant] Comment faire apparaitre plusieurs msgbox en même temps ?
    Par Arthur. dans le forum VB.NET
    Réponses: 5
    Dernier message: 05/04/2017, 16h50
  2. Réponses: 4
    Dernier message: 16/01/2012, 18h26
  3. [QtGui] Afficher plusieurs fois la même image avec PySide
    Par Gorglum dans le forum PyQt
    Réponses: 3
    Dernier message: 03/12/2011, 03h51
  4. Réponses: 2
    Dernier message: 12/11/2009, 22h35
  5. Réponses: 4
    Dernier message: 29/01/2009, 14h44

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