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 :

Utilisation d'image préchargée impossible hors de fonction


Sujet :

JavaScript

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 4
    Par défaut Utilisation d'image préchargée impossible hors de fonction
    Bonjour à tous !

    Voilà, je me suis mis au javascript hier, et suis en train de développer une application mélant JS et la balise <canvas> du html.

    Jusque là, je n'ai pas trop de problème, j'avance lentement, mais surement.

    Voici la base de mon code : (déclaration des variables et initialisation) :

    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
     
    var canvas;
    var ctx;
    var imgMoon;
    var imgIdent;
    var angle;
    var x, dx;
    var y, dy;
    var started;
     
    function init () {
    	//Mise en place du context
    	canvas = document.getElementById("canvas");
    	ctx = canvas.getContext("2d");
     
    	//Initialisation des variables
    	imgIdent = new Image();
    	imgIdent.src='style/ident.png';
    	imgMoon = new Image();
    	imgMoon.src='style/moon.png';
    	angle = 0;
    	x = 0;
    	y = 0;
    	dx = 2;
    	dy = 2;
    	started = false;
     
     
    	//Preload des images
    	if (document.images)
        {
          preload_image_object = new Image();
          // set image url
          image_url = new Array();
          image_url[0] = "style/moon.png";
          image_url[1] = "style/ident.png";
     
           var i = 0;
           for(i=0; i<=3; i++) 
             preload_image_object.src = image_url[i];
        }
      // Mise en place de l'eventListener sur MouseMove
      canvas.addEventListener('mousemove', ev_mousemove, false);
    }


    J'en suis actuellement à essayer de gérer le déplacement d'une image dans le Canvas. Pour ce faire, j'utilise la fonction suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    function draw(img){
    	ctx.clearRect(0, 0, 300, 300);
    	ctx.drawImage(img, x, y);
    	x += dx;
    	y += dy;
    }
    Je l'appelle ensuite en utilisant l'instruction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    init();
    setInterval(draw(imgMoon), 10);
    Et là... Ca ne fonctionne pas. Rien ne s'affiche. Le script arrive jusqu'au bout (j'utilise un alert() à la fin du code, celui-ci s'affiche correctement), mais rien. Le Canvas reste désespérément vide.

    J'ai bidouillé un peu, et en utilisant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    function draw(){
    	ctx.clearRect(0, 0, 300, 300);
    	ctx.drawImage(imgMoon, x, y);
    	x += dx;
    	y += dy;
    }
    init();
    setInterval(draw, 10);

    C'est à dire en utilisant la variable globale directement dans la fonction, sans passer par un parametre, cela fonctionne. (Affichage et déplacement de l'image...) Or j'aimerai pouvoir afficher l'image entrer en parametre...

    Quelqu'un a une idée d'où peut venir le problème ?

    Merci !


    Edit : je développe en utilisant le navigateur Chromium et Notepad++, mais je ne pense pas que ça change grand chose dans ce cas là...

    Edit 2 :

    Je me rends compte que je charge 2 fois les images, mais j'ai la désagréable sensation que je ne préload rien du tout...

  2. #2
    Membre Expert
    Avatar de gwyohm
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2007
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 925
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    setInterval(draw(imgMoon), 10);
    En écrivant ce code, tu fais un setInterval sur le résultat de l'éxecution de draw... donc un setInterval sur undefined vu que draw ne renvoie rien.

    Il faut donc que tu crées une fonction qui renvoie une fonction :

    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
     
    function draw(img){
    	ctx.clearRect(0, 0, 300, 300);
    	ctx.drawImage(img, x, y);
    	x += dx;
    	y += dy;
    }
     
    function prepareDraw(img) {
      return function() {
        draw(img);
      };
    }
     
    init();
    setInterval(prepareDraw(imgMoon), 10);

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 4
    Par défaut
    Génial, ça marche !
    Merci pour le coup de main, j'ai passé le sujet en résolu et j'ai plussoyé ta réponse. =)

    Sinon, au niveau du preload, ça a l'air correct ? Il me parait inutile de faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    imgIdent = new Image();
    	imgIdent.src='style/ident.png';
    	imgMoon = new Image();
    	imgMoon.src='style/moon.png';
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    if (document.images)
        {
          preload_image_object = new Image();
          // set image url
          image_url = new Array();
          image_url[0] = "style/moon.png";
          image_url[1] = "style/ident.png";
     
           var i = 0;
           for(i=0; i<=3; i++) 
             preload_image_object.src = image_url[i];
        }
    puisqu'il semble qu'elles fassent la même chose... Quelle méthode garder ? =)

  4. #4
    Membre Expert
    Avatar de gwyohm
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2007
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 925
    Par défaut
    Effectivement ca n'a pas trop d'utilité ; d'autant que tu ne fais rien de preload_image_object ...

    Attention tout de même, tu créées des objets image, mais leur chargement est asynchrone... donc ton code de dessin dans le canvas peut démarrer alors que tes images ne sont pas arrivées...

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 4
    Par défaut
    Citation Envoyé par gwyohm Voir le message
    Attention tout de même, tu créées des objets image, mais leur chargement est asynchrone... donc ton code de dessin dans le canvas peut démarrer alors que tes images ne sont pas arrivées...
    C'est justement ce problème que j'essaye de régler en "préchargeant" les images, mais je ne suis pas sur que ce soit le cas.

    En faisant quelques recherche, la majeure partie des script "préloadant" les image ne faisaient que indiquer le src de l'image via le script.
    Je ne suis pas sur que ce soit suffisant, en tout cas, d'apres https://developer.mozilla.org/fr/Tut...n_d&#39;images

    et plus précisément la partie "création d'une image à partir de rien", il indique qu'il est plus interessant d'utiliser la fonction onload.

    Toutefois, je ne vois pas comment utiliser cette fonction pour plusieurs images, d'autant que le tuto qu'ils nous propose m'apparait tout sauf clair...

    (Le tuto en question : http://www.webreference.com/programm...pt/gr/column3/)

    Des idées d'alternative ? :s

  6. #6
    Membre Expert
    Avatar de gwyohm
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2007
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 925
    Par défaut
    Voici le code que j'utilise mais il est basé sur prototype... tu peux surement l'adapter...
    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
    51
    52
     
    ImageLoader = (function() {
      var images = {};
     
      return {
        getImage: function(imagePath, options) {
          // Si pas d'image path, on lance une exception
          if(! imagePath) {
            throw "ImageLoader#handleParameters imagePath is a mandatory parameter.";
          }
          // Définition des options
          options = Object.extend( {
            callBack: Prototype.emptyFunction,
            forceReload: true,
            target: $(document.body)
          }, options );
          // L'image est-elle en cache ?
          var image = images[imagePath];
          // Si l'image est trouvée et qu'on ne force pas le reload, on lance le callback avec l'image
          if( image && ! options.forceReload) {
            options.callBack(image);
          } else {
            // Si l'image existe, on stop le listener, on supprime le cache
            if(image) {
              // Stop le listener
              image.stopObserving();
              // suppression de l'image
              image.remove();
            }
            // construction de l'image
            image = new Element("img");
            image.store("serverPath", options.serverPath || null);
            // on ajoute l'image dans le conteneur
            options.target.insert(image);
            // on attache le listener pour observer quand l'image est chargée
            image.observe("load", options.callBack.curry(image));
            // on écrit le src avec un timestamp pour éviter le cache navigateur
            var ts = new Date().getTime();
     
            if(imagePath.indexOf("?") >= 0) {
              image.writeAttribute("src", imagePath + "&ts=" + ts);
            } else {
              image.writeAttribute("src", imagePath + "?ts=" + ts);
            }
     
            // on conserve l'image dans le cache
            images[imagePath] = image;
          }
     
        }
      };
    })();
    Pour l'utiliser, on fait comme ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ImageLoader.getImage("chemin/vers/image", options);
    Les options sont
    • callBack: un pointeur sur une fonction prenant en paramètre une image ; sera appelé quand l'image sera chargée (par défaut fonction qui ne fait rien)
    • forceReload: forcer le reload (par défaut true)
    • target: le conteneur dans lequel on insère l'image (par défaut le body)

    tu peux donc faire (avec prototype) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    ImageLoader.getImage("chemin/vers/image", {
      callBack: draw,
      forceReload: false
    });
    Mais tu ne dois voir ca que comme une piste pour ton cas...

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

Discussions similaires

  1. [JAR] Utiliser des images
    Par Seiya dans le forum Général Java
    Réponses: 2
    Dernier message: 26/08/2005, 17h59
  2. Droit d'utilisation des images clipart
    Par Civodul4 dans le forum Autres Logiciels
    Réponses: 2
    Dernier message: 23/05/2005, 08h30
  3. Utilisation de template dans un role de fonctions/procedures
    Par Punky65250 dans le forum XSL/XSLT/XPATH
    Réponses: 14
    Dernier message: 01/09/2004, 10h05
  4. Utilisation d'images au format png
    Par chtiot dans le forum Langage
    Réponses: 2
    Dernier message: 24/10/2003, 15h56

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