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 :

Object, setTimeout() & animation


Sujet :

JavaScript

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    42
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2008
    Messages : 42
    Points : 43
    Points
    43
    Par défaut Object, setTimeout() & animation
    Bonjour,

    Je viens de faire un script parfaitement inutile mais joli (au niveau du visuel, pas du code). Je suis en train de l'optimiser un maximum et j'ai déjà diviser la charge CPU par 4 ce qui n'est déjà pas mal... Mais... Et bien oui il y a un mais sinon il n'y aurait pas de problème ;-)
    Il me reste quelque chose que je sais consommer du temps inutilement mais je n'arrive pas à trouver de solution... Tout d'abord, un peu de code :

    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
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
     
    var radConstant = Math.PI / 180;
    var degConstant = 180 / Math.PI;
     
    function decHex(number) {
    	if (number < 16){
    		return '0'+number.toString(16);
    	}
    	else{
    		return number.toString(16);
    	}
    }
     
    function hexDec(number) {
    	return parseInt(number,16);
    }
     
    function rad(degree){
    	return degree * radConstant;
    }
     
    function deg(radian){
    	return radian * degConstant;
    }
     
    function createEDiagContainer(containerName){
    	var stdDiv = document.createElement('div');
    	stdDiv.className = 'absoluteDiv';
    	stdDiv.id = containerName;
    	document.body.appendChild(stdDiv);
    	return stdDiv;
    }
     
    function multipleRotate(centerX,centerY,rotatorNumber,width,namePrefix,distance){
    	var objRotator = [];
    	var objPosition = rad(width/rotatorNumber);
    	for(var i=0;i<rotatorNumber;i++){
    		objRotator.push(createEDiagContainer(namePrefix+'_'+i));
    		objRotator[i].innerHTML = i;
    		rotateObject(objRotator[i].id,centerX,centerY,objPosition*i,distance);
    	}
    }
     
    function rotateObject(objId,centerX,centerY,currentDegreeAngle,distance){
    	var sinusAngle = Math.sin(currentDegreeAngle);
    	var obj = document.getElementById(objId); // To Be improved...
    	var factor = 15;
    	var zoomModifier = sinusAngle * factor;
    	var dimensionXY = Math.round(20 + zoomModifier);
    	var colorLevel = Math.round(127 + (127 / factor * zoomModifier));
    	var alphaLevel = decHex(colorLevel);
    	var invertedAplhaLevel = decHex(255-colorLevel);
     
    	obj.style.left = Math.round(centerX + distance*Math.cos(currentDegreeAngle))+'px';
    	obj.style.top = Math.round(centerY + distance*sinusAngle - (zoomModifier*4))+'px';
    	obj.style.height = dimensionXY+'px';
    	obj.style.width = dimensionXY+'px';
    	obj.style.fontSize = (dimensionXY/2)+'px';
    	obj.style.backgroundColor = '#'+alphaLevel+alphaLevel+alphaLevel;
    	obj.style.zIndex = Math.round(1000 + zoomModifier);
    	obj.style.borderStyle = 'solid';
    	obj.style.borderWidth = '1px';
    	obj.style.borderColor = '#'+invertedAplhaLevel+invertedAplhaLevel+invertedAplhaLevel;
     
    	if(deg(currentDegreeAngle) > 360){
    		currentDegreeAngle = rad(deg(currentDegreeAngle) - 360);
    	}
     
    	setTimeout(function(){rotateObject(objId,centerX,centerY,(currentDegreeAngle+0.10),distance)},40);
    }
    Attention je fait usage d'une classe CSS 'absoluteDiv' qui se trouve dans une feuille de style que vous n'avez pas, mais qui en gros ne fait que définir l'attribut 'position' à 'absolute'...

    Le lancement de l'ensemble se fait via la commande suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    multipleRotate(500,500,16,270,'rotatora',100);
    • Les deux premiers paramètres sont la position x,y du centre de rotation.
    • Le troisième c'est le nombre d'éléments.
    • Le quatrième c'est la portion de l'ellipse sur laquelle seront répartis les éléments. (360 = tout le cercle, 270 = 3/4, etc)
    • Le cinquième, c'est le préfixe du nom des 'div' qui seront créée
    • Le sixième, c'est le diamètre de l'ellipse



    Voilà le décor est posé...

    Mon but serait maintenant pouvoir passer directement l'objet "objRotator[i]" dans la fonction exécutée par setTimeout() au lieu de l'horrible getElementById()... Et c'est là que çà coince à cause du "scope" de la fonction évaluée par setTimeout()...
    La première solution que j'ai trouvée mais qui ne me plait pas serait de déclarer mon array d'objets (objRotator) comme variable globale et de ne passer que l'index (i) à la fonction setTimeout()...
    Mais mon but serait de pouvoir vraiment passer directement l'objet d'une autre manière.

    Quelqu'un a-t-il une autre solution ?

    Merci d'avance !

  2. #2
    Expert confirmé
    Avatar de le_chomeur
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2006
    Messages
    3 653
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 3 653
    Points : 4 835
    Points
    4 835
    Par défaut
    pourquoi ne fais tu pas :



    obj vaut l'objet directement ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    rotateObject(obj,centerX,centerY,currentDegreeAngle,distance){
    ...
    }
    et au premier appel :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var monObjet = document.getElementById('tonid');
    rotateObject(monObjet,centerX,centerY,currentDegreeAngle,distance)
    et donc dans le timeout :

    tu peux passer une fonction anonyme ... ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    rotateObject(obj,centerX,centerY,currentDegreeAngle,distance)
    est ton ami fait gagner du temps à ceux qui aident , donc un message avec la balise résolu laisse plus de temps pour résoudre d'autres problèmes

    Premier ministre du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts )

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    42
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2008
    Messages : 42
    Points : 43
    Points
    43
    Par défaut Mmmm...
    Effectivement cela fonctionne... Je suis troublé car j'était certains que cette manière de faire allait être en dehors du 'scope'... Il va falloir que je revois mes notions de 'scope' !!!

    En tout cas merci car cela va me permettre d'aller un peu plus loin maintenant ;-)

    Pour infos je mets le code modifié:

    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
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
     
    var radConstant = Math.PI / 180;
    var degConstant = 180 / Math.PI;
     
    function decHex(number) {
    	if (number < 16){
    		return '0'+number.toString(16);
    	}
    	else{
    		return number.toString(16);
    	}
    }
     
    function hexDec(number) {
    	return parseInt(number,16);
    }
     
    function rad(degree){
    	return degree * radConstant;
    }
     
    function deg(radian){
    	return radian * degConstant;
    }
     
    function createEDiagContainer(containerName){
    	var stdDiv = document.createElement('div');
    	stdDiv.className = 'absoluteDiv';
    	stdDiv.id = containerName;
    	document.body.appendChild(stdDiv);
    	return stdDiv;
    }
     
    function multipleRotate(centerX,centerY,rotatorNumber,width,namePrefix,distance){
    	var objRotator = [];
    	var objPosition = rad(width/rotatorNumber);
    	for(var i=0;i<rotatorNumber;i++){
    		objRotator.push(createEDiagContainer(namePrefix+'_'+i));
    		objRotator[i].innerHTML = i;
    		// rotateObject(objRotator[i].id,centerX,centerY,objPosition*i,distance);
    		rotateObject(objRotator[i],centerX,centerY,objPosition*i,distance);
    	}
    }
     
    function rotateObject(obj,centerX,centerY,currentDegreeAngle,distance){
    	var sinusAngle = Math.sin(currentDegreeAngle);
    	// var obj = document.getElementById(objId); // To Be improved...
    	var factor = 15;
    	var zoomModifier = sinusAngle * factor;
    	var dimensionXY = Math.round(20 + zoomModifier);
    	var colorLevel = Math.round(127 + (127 / factor * zoomModifier));
    	var alphaLevel = decHex(colorLevel);
    	var invertedAplhaLevel = decHex(255-colorLevel);
     
    	obj.style.left = Math.round(centerX + distance*Math.cos(currentDegreeAngle))+'px';
    	obj.style.top = Math.round(centerY + distance*sinusAngle - (zoomModifier*4))+'px';
    	obj.style.height = dimensionXY+'px';
    	obj.style.width = dimensionXY+'px';
    	obj.style.fontSize = (dimensionXY/2)+'px';
    	obj.style.backgroundColor = '#'+alphaLevel+alphaLevel+alphaLevel;
    	obj.style.zIndex = Math.round(1000 + zoomModifier);
    	obj.style.borderStyle = 'solid';
    	obj.style.borderWidth = '1px';
    	obj.style.borderColor = '#'+invertedAplhaLevel+invertedAplhaLevel+invertedAplhaLevel;
     
    	if(deg(currentDegreeAngle) > 360){
    		currentDegreeAngle = rad(deg(currentDegreeAngle) - 360);
    	}
     
    	// setTimeout(function(){rotateObject(objId,centerX,centerY,(currentDegreeAngle+0.10),distance)},40);
    	setTimeout(function(){rotateObject(obj,centerX,centerY,(currentDegreeAngle+0.10),distance)},40);
    }
    Merci

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

Discussions similaires

  1. Animation progressive avec setTimeout
    Par bracket dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 21/03/2009, 13h27
  2. Animation et setTimeout synchrone
    Par odissey dans le forum Général JavaScript
    Réponses: 11
    Dernier message: 11/04/2008, 08h52
  3. Passage de parametre a une anim Flash 5
    Par debug dans le forum Intégration
    Réponses: 4
    Dernier message: 03/06/2002, 17h59

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