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 :

Dans l'init(), comment charger une image sur un objet qui a été créé avant le init


Sujet :

JavaScript

  1. #1
    Membre confirmé
    Homme Profil pro
    sans
    Inscrit en
    Mai 2023
    Messages
    146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : sans

    Informations forums :
    Inscription : Mai 2023
    Messages : 146
    Par défaut Dans l'init(), comment charger une image sur un objet qui a été créé avant le init
    j'aurais bien voulu savoir comment on fait pour charger une image sur l'objet aprés qu'il a été créé, parce que je crée l'objet en début de page JS et ensuite je voudrais y mettre son image à partir du init().

    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
     
    /* ****************** CLASSES ****************** */
     
    class CObjet{
    	constructor(Image, PX, PY, Width, Height, Nom){
    	this.Image=Image;
            this.PX=PX;
            this.PY=PY;
            this.Width=Width;
            this.Height=Height;
    	this.Nom=Nom;
        }
    }
     
     
    /* ******************* VARIABLES **************** */
     
    var largeur=screen.width;
    var hauteur=screen.height;
     
     
    var image1=new Image();
     
    var X1,X2,Y1,Y2=0;
    var menu=false;
     
     
    var monobjet=new CObjet(image1,100,200); // <----- PX et PY
     
     
     
    /* ************** FONCTIONS *************** */
     
    function anime(timestamp){
     
        ctx1.drawImage(monobjet.Image,monobjet.PX,monobjet.PY);
     
        animtimer=requestAnimationFrame(anime);
    }
     
     
    function init(){
     
    	ecran1.width=largeur;
    	ecran1.height=hauteur;
    	ctx1.width=largeur;
    	ctx1.height=hauteur;
     
        image1.onload=function(){
            monobjet.Image=image1;
        }
     
        // Image à charger pour l'objet.
        image1.src='citrouille.png';
     
     
        var animtimer=requestAnimationFrame(anime);   
    }

  2. #2
    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,
    je ne comprends pas pourquoi tu ne passes pas la scr de l'image lors de la création de l'objet.

    La gestion devrait se faire dans l'objet et ne pas dépendre d'éléments extérieurs.

    De même ton objet devrait avoir une méthode d'affichage, entre d'autres, pour éviter ce type de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ctx1.drawImage(monobjet.Image,monobjet.PX,monobjet.PY)
    mais plutôt quelque chose comme

  3. #3
    Membre Expert
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Par défaut
    Re de ce matin... Tu peux toujours faire un truc simple comme ça... Avec un draw() suivant les conseils de NoSmoking
    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
    <!DOCTYPE html>
    <html lang="fr">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            #cancan{
                border: 1px solid black;
            }
        </style>
    </head>
    <body>
        <canvas id="cancan" width="500" height="500"></canvas>
       <script>
         const cancan=document.getElementById('cancan');
         const context= cancan.getContext("2d");
     
         class Oimage{
            constructor(x,y,ctx,path){
                const im=document.createElement('img');
                im.src=path;
                this.draw=function(){
                    im.addEventListener( 'load', ()=>{
                       ctx.drawImage(im,x,y);
                    });
                }; 
            }
         }
        const image=new Oimage(100,200,context,'image.png');
         image.draw();
       </script> 
    </body>
    </html>

  4. #4
    Membre confirmé
    Homme Profil pro
    sans
    Inscrit en
    Mai 2023
    Messages
    146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : sans

    Informations forums :
    Inscription : Mai 2023
    Messages : 146
    Par défaut
    Merci, je vais essayer ça !

    En fait je voulais respecter la logique des anciens jeux qui était de charger des images en mémoire et de les afficher qu'ensuite, tandis qu'avec le chargement objet de javascript comme l'a dit No smoking, ça pousse plutot à ce que ce soit l'objet qui fasse son affichage
    Je trouvais que c'était plus organisé que le chargement soit séparé de l'affichage.


    ça marche super ! Et j'ai appris des trucs en lisant le code

  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
    Citation Envoyé par nouby
    En fait je voulais respecter la logique des anciens jeux qui était de charger des images en mémoire et de les afficher qu'ensuite
    ce schéma reste néanmoins respecté !

    Je trouvais que c'était plus organisé que le chargement soit séparé de l'affichage
    ce qui a rapport à l'objet doit dépendre de l'objet, diviser pour mieux régner.



    Citation Envoyé par Archimède
    const im=document.createElement('img')
    on peut utiliser directement le constructeur Image() même si fondamentalement cela doit être équivalent.


    Je vous livre l'approche que j'aurais faite :
    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    class Picture {
      constructor(src, posX = 0, posY = 0) {
        this.image = new Image();
        this.x = posX;
        this.y = posY;
        this.width = 0;
        this.height = 0;
        this.setSource(src);
      }
     
      setSource(src) {
        const thisObj = this;
        this.image.onload = function(e) {
          const objImg = e.target;
          thisObj.width = objImg.naturalWidth;
          thisObj.height = objImg.naturalHeight;
        }
        this.image.onerror = function() {
          thisObj.setSource("data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=");
        }
     
        this.image.src = src;
        return this;
      }
     
      addToContext(context) {
        this.context = context;
        return this;
      }
     
      draw() {
        if (!(this.height * this.width)) {
          setTimeout(() => this.draw(), 1);
        }
        else {
          if (this.context) {
            this.context.drawImage(this.image, this.x, this.y);
          }
        }
        return this;
      }
     
      moveTo(x, y) {
        this.x = x;
        this.y = y;
        this.draw();
        return this;
      }
     
    }
    A noter la gestion de l'erreur au chargement de l'image.
    On peut, bien sûr par la suite, enrichir l'objet avec de nouvelles méthodes

  6. #6
    Membre Expert
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Par défaut modif pour prendre en considération la position initiale de l'image lors de l'animation
    Merci NoSmoking, perso j'avais fait ça en plus en cas d'animation (si ça peut servir...)
    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    <!DOCTYPE html>
    <html lang="fr">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            #cancan{
                border: 1px solid black;
            }
        </style>
    </head>
    <body>
        <canvas id="cancan" width="500" height="500"></canvas>
       <script>
         const cancan=document.getElementById('cancan');
         const context= cancan.getContext("2d");
         const cw=cancan.width;
         const ch=cancan.height;
     
         class Point{
            constructor(x,y){
                this.x=x;
                this.y=y;
            }
         }
     
         class Oimage{
            constructor(x,y,ctx,path){
                let pt= new Point(x,y);
                const im=document.createElement('img');
                im.src=path;
                im.addEventListener('load',()=>{ctx.drawImage(im,pt.x,pt.y);});
                
                this.draw=function(){
                        ctx.clearRect(0,0,cw,ch);  //après il vaudrait mieux effacer sur le rect de la position précédente de l'image pour éviter que ça rame avec plusieurs objets en déplacement...
                        // et aussi utiliser les fonctionnalités de canvas avec ctx.save et ctx.restore() ainsi que ctx.translate(pt.x,pt.y) plutôt que de déplacer l'image...
                        ctx.drawImage(im,pt.x,pt.y);
                };
     
                Object.defineProperties(this, {pos: {
                            set: function (value) {
                                pt=new Point(x+value.x,y+value.y);//ici
                                this.draw();
                            }
                        }
                }); 
            }
         }
     
        
     
         
         const image=new Oimage(0,0,context,'image.png');
     
         let dx=0;
     
         function anime(){
          dx+=1;
          image.pos=new Point(dx,100);
          requestAnimationFrame(anime); 
         }
     
         anime();
       </script> 
    </body>
    </html>

  7. #7
    Membre confirmé
    Homme Profil pro
    sans
    Inscrit en
    Mai 2023
    Messages
    146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : sans

    Informations forums :
    Inscription : Mai 2023
    Messages : 146
    Par défaut
    ouaaah c'est super organisé votre truc, et on y apprend des façons de faire.

    Oui en effet je pensais aussi faire des animations par la suite avec ces objets

    Merci pour vos conseils !

  8. #8
    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
    @Archimède :
    Ton objet ne devrait pas dépendre de variables extérieures/globales (ici cw et ch), d'autant que ces valeurs sont disponibles directement dans l'objet via un ctx.canvas.width et height.

    Concernant l'effacement de la zone image la situation n'est pas aussi simple que cela et ce dès que tu vas avoir plusieurs objets à gérer.
    Dans ce cas plusieurs options sont possibles.
    Si peu d'objets on peut envisager un canvas pour chacun d'eux qui se superpose au canvas de fond. Soit il fait la même dimension que le canvas de fond soit il occupe la surface minimum de ton objet et on pourra même lors de déplacements déplacer le canvas sans même faire de redraw.
    On peut également envisager, lors de l'affichage d'un objet de sauveagrder/restaurer le fond, via des getImageData/putImageData, ce dont tu parles d'ailleurs dans un de tes commentaires, le plus complexe à gérer serait les éventuelles collisions.

    Dans la plupart des cas c'est hors des objets que l'on va gérer l'effacement/affichage des objets, typiquement comme dans une animation de « neige qui tombe », on a x flocons et c'est l'application qui lance l'animation, gère le clear et les redraws.

    Tout ceci n'est bien sûr pas exhaustif

    @nouby :
    Tout cela pour dire que cela peut paraître simple au premier abord mais peut vite devenir un casse tête

  9. #9
    Membre Expert
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Par défaut
    Merci NoSmoking, c'est pour ça que je préfère de loin svg pour se rapprocher de flash...Je n'utilise plus vraiment canvas...

  10. #10
    Membre confirmé
    Homme Profil pro
    sans
    Inscrit en
    Mai 2023
    Messages
    146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : sans

    Informations forums :
    Inscription : Mai 2023
    Messages : 146
    Par défaut
    Merci des précisions, trés utile !!!

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

Discussions similaires

  1. Comment charger une image sur un forum avec [img][/img]
    Par tomed dans le forum Balisage (X)HTML et validation W3C
    Réponses: 1
    Dernier message: 24/04/2015, 23h08
  2. comment charger une image dans un fichier Excel?
    Par google_is_my_friend dans le forum Excel
    Réponses: 4
    Dernier message: 14/03/2012, 17h25
  3. Réponses: 3
    Dernier message: 11/12/2010, 14h18
  4. Comment charger une image d'un chemin sur le disque ?
    Par faroukus dans le forum OpenCV
    Réponses: 3
    Dernier message: 23/04/2008, 09h25

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