ANIMATION VIA LES ÉQUATIONS DE ROBERT PENNER

nickadele Messages postés 1251 Date d'inscription mercredi 7 août 2002 Statut Modérateur Dernière intervention 10 avril 2013 - 26 juin 2008 à 20:56
cs_Kimjoa Messages postés 262 Date d'inscription vendredi 6 mai 2005 Statut Membre Dernière intervention 19 septembre 2014 - 28 juin 2008 à 22:12
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/47120-animation-via-les-equations-de-robert-penner

cs_Kimjoa Messages postés 262 Date d'inscription vendredi 6 mai 2005 Statut Membre Dernière intervention 19 septembre 2014
28 juin 2008 à 22:12
ok , j'ai regardé a koi il correspondait, le a correspond a l étirement maximum, le p a l'élasticité

Cependant ma fonction permet de gérer les va et viens et la tension meme si les valeur doivent etre precise pour un resultat satisfaisant

J ai modifié la fonction de ROBERT PENNER pour kel prenne en compte le nbr de va et viens.
J'ai ajouté une fonction classic d'élasticité et de rebond.

voici le code a modifié
pour le select:

<option value="elasticKimjoa">elasticKimjoa</option>elasticClassic
<option value="elasticBounce">elasticBounce</option>
<option value="elasticClassic">elasticClassic</option>

pour l'objet transition

elasticClassic : function(t,b,c,d){
return c*(((1-Math.cos((t/=d) * Math.PI * 4)) * (1 - t)) + t)+b;
},
elasticKimjoa : function(t,b,c,d,te,bo,r){
// te=tension ,r=resistance, bo=rebont formule test
return c*(((1-Math.cos(Math.pow((t/=d),(1/(te || 1.5))) * Math.PI * (bo || 4))) * (1 - Math.pow(t,1/(t*(r || 10))))) + Math.pow(t,1/(t*(r || 10))))+b;
},
elastic: function (t,b,c,d,a,p){
t/=d;
if (!a)a=c*3;
//p=nbr de va et viens a etirement max reste tension
p=(p)?(p>1)?(c*10)/((p-1)/(d/1000)):(c*10)/(1/(d/1000)):(c*10)/(3/(d/1000));
if (a < Math.abs(c))
var s=p/4;
else
var s = p/(2*Math.PI) * Math.asin (c/a);
return (a*Math.pow(2,-10*(t)) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b);
},
elasticBounce: function (t,b,c,d,a,p){//p=bounce
var value=transitions.elastic(t,b,c,d,a,p);
if(Math.abs((value-b))>Math.abs(c))
return b+c-(value-c-b);
else return value;
}

je sais pas encore kel fonction je vais mettre dans ma librairie , j'aimerait bien pouvoir géré la tension

voila, a+
XtremDuke Messages postés 626 Date d'inscription samedi 28 septembre 2002 Statut Membre Dernière intervention 18 mai 2009 4
28 juin 2008 à 18:23
Slt,

Pour l'équation 'élastique', tu as deux paramètres supplémentaires qui servent à gérer l'effet de l'animation.

function (t,b,c,d,a /!\ ,p /!\){
cs_Kimjoa Messages postés 262 Date d'inscription vendredi 6 mai 2005 Statut Membre Dernière intervention 19 septembre 2014
28 juin 2008 à 12:06
salut , je connais bien ses formules , pour les avoir utilisé dans mon propre script d'animation que je sortirais avec ma bibliothèques, qui me prend plus de temps que prévu. J'ai créer une formule d'élasticité en 'tatonant' pour permettre d'y inclure des options de résistance, nombre de va et viens, et de tension , je suis pas bon en math, et cette formule est sans doute fausse mais l'effet est pas mal , voici la fonction

elasticDown : function(t,s,e,obj){
return (e-s)*(((1-Math.cos(Math.pow(t,(1/obj.tension)) * Math.PI * obj.bounce)) * (1 - Math.pow(t,1/(t*obj.resistance)))) + Math.pow(t,1/(t*obj.resistance)))+s;
}
concernant les variables
t est le temp (compris entre 0 et 1)
s est la valeur de départ
e est la valeur d'arrivé
obj est l'objet avec les options

si un matheu pouvais me dire se kil en pense .

Pour les curieux http://www.dblog.free.fr/?act=article&art=64

bye
XtremDuke Messages postés 626 Date d'inscription samedi 28 septembre 2002 Statut Membre Dernière intervention 18 mai 2009 4
27 juin 2008 à 20:28
"j'ai été obligé de rajouter un Singleton Fx.Listener"

Je ne connais pas ce singleton mais d'après son nom, c'est exactement ça. Faut créer un pseudo gestionnaire d'effets afin de supprimer les effets qui sont déjà en application.

"Animation est bien une classe vu que je l'utilise comme un constructeur."

Effectivement, j'ai lu en diagonale, toutes mes confuses.

"Le problème de gestion des timers dont tu parles est également présent dans la source que tu présentes ici."

Comme dis plus haut, ce n'est qu'une base pour l'utilisation des équations.
ralecul Messages postés 111 Date d'inscription dimanche 23 mars 2003 Statut Membre Dernière intervention 1 août 2008
27 juin 2008 à 17:34
Utilisation de window.setInterval au lieu de interval
>> Alors ça, aucune idée, c'est une mauvaise (ou bonne ???) habitude.
A mon avis c'est facultatif et surtout je trouve que ça n'apporte pas grand chose au niveau de la lisibilité.
En revanche si tu souhaites remplacer la fonction alert par une méthode perso, ça me parait intéressant.
(En gros pour l'appel je ne m'en sers pas, mais pour la redéfinition je m'en sers)

>> tu n'as pas écris de classe mais deux objets.
Pourquoi deux objets ? -> ya une fonction (animate, qui créé un objet) et une définition de classe (Animation).
Animation est bien une classe vu que je l'utilise comme un constructeur.
Le problème de gestion des timers dont tu parles est également présent dans la source que tu présentes ici.
Je n'ai fait que la convertir à la mode Prototype, cependant j'ai ensuite tenté de reproduite ta démo avec cette source.
Le résultat : http://astre.henri.free.fr/creations_sandbox_mootools.php utilise les fichiers :
http://astre.henri.free.fr/js/effect.js
http://astre.henri.free.fr/js/myPrototype.js

Je serais curieux de voir comment tu as fait dans ta démo pour pouvoir comparer avec ma version.
En effet, j'ai été obligé de rajouter un Singleton Fx.Listener qui contient une liste de tous les effets appliqués à un élément.
Ya peut-être une méthode plus élégante ? Je n'ai pas pu comparer avec ta source car minified.js est assez illisible ;-)
lakichemole Messages postés 253 Date d'inscription vendredi 13 juin 2003 Statut Membre Dernière intervention 18 mai 2009
27 juin 2008 à 13:56
à non au temps pour moi, erreur de copier coller :)
lakichemole Messages postés 253 Date d'inscription vendredi 13 juin 2003 Statut Membre Dernière intervention 18 mai 2009
27 juin 2008 à 13:54
Il manque l'include de prototype dans ton exemple :/
XtremDuke Messages postés 626 Date d'inscription samedi 28 septembre 2002 Statut Membre Dernière intervention 18 mai 2009 4
27 juin 2008 à 10:37
"tu ne te sers pas de cette variable"

>> Effectivement je ne m'en sers pas. Il s'agit en fait d'un simple copie/colle d'un travaille personnel.

"pourquoi tu spécifies window "

>> Alors ça, aucune idée, c'est une mauvaise (ou bonne ???) habitude.

"Il suffit de remplacer la fonction animate par celle-ci et d'ajouter la classe Animation"

>> tu n'as pas ecris de classe mais deux objets.

Pour parler de ta 'classe', il te faut rajouter une gestion des timers. Sinon, tu vas avoir des surprises si tu utilises cette fonction sur des 'mouseover'.

Remarque : Cette base que j'ai fournis et normalement ecrit sous forme de classe ds un projet perso. Voir :
http://joof-api.net/demo.html
ralecul Messages postés 111 Date d'inscription dimanche 23 mars 2003 Statut Membre Dernière intervention 1 août 2008
27 juin 2008 à 00:38
Désolé, je n'ai pas résisté à "prototyper" ta source :

function animate() {
new Animation("animation", {
duration : $('duration').value,
transition : $('transition').value,
amplitude : $('nbPix').value,
mode : $('cssRule').value,
initSize : 32
});
};

function Animation(div, options) {
var _options = options || {};
var _fps = _options.fps || 80;
var _duration = _options.duration || 800;
var _transition = _options.transition || "linear";
var _amplitude = _options.amplitude || 180;
var _mode = _options.mode || "both";
var _initSize = _options.initSize || 42; //because 42 is the answer ;-)
var _div = $(div);

var _interval = 1000/_fps;
var _nbSteps = Math.round(_duration/_interval);

var _mapping = [];
for(var i=1; i<=_nbSteps; ++i)
_mapping.push(transitions[_transition](i*_interval, _initSize, _amplitude - _initSize, _duration));

var currentStep = 0;
var timer = setInterval(iter, _interval);

function iter() {
if (_mapping[currentStep]) {
if (_mode == 'both') {
_div.style.height = _mapping[currentStep]+'px';
_div.style.width = _mapping[currentStep]+'px';
}
else {
_div.style[_mode] = _mapping[currentStep]+'px';
}
currentStep++;
}
else {
clearInterval(timer);
return;
}
}
}

PS : c'est fait à la va-vite, ya peut-être quelques erreurs...
PPS : Il suffit de remplacer la fonction animate par celle-ci et d'ajouter la classe Animation.
ralecul Messages postés 111 Date d'inscription dimanche 23 mars 2003 Statut Membre Dernière intervention 1 août 2008
27 juin 2008 à 00:06
Bravo!

Cette source me donne effectivement envie de faire mon moteur d'animation à la mootools.
C'est une très bonne base pour découvrir les effets de Robert Penner.
Cela permettra également à certain de découvrir les singletons en JS.

La version de mootools n'utilise pas exactement les mêmes équations.
En revanche, j'ai pu constaté que tu as scrupuleusement respecté la version AS de Robert Penner ;-)
Ça aurait été sympa aussi de pouvoir choisir entre les modes easeIn, easeOut et easeInOut.
La version de mootools est beaucoup plus simple pour cela par rapport aux équations fournies par Robert Penner.

Commentaires sur le code :
var step = Math.abs(32 - $('nbPix').value)/nbSteps; -> tu ne te sers pas de cette variable.
window.setInterval et window.clearInterval -> pourquoi tu spécifies window ? je suppose que tu n'utilises pas window.alert...
corps de animate() -> j'aurais bien vu une version objet à la place (du genre : new Animate("animation", {duration: 800, type: linear}); )
nickadele Messages postés 1251 Date d'inscription mercredi 7 août 2002 Statut Modérateur Dernière intervention 10 avril 2013
26 juin 2008 à 20:56
Très bonne source au niveau du résultat et de l'effet !
Vu que l'objet de cette source c'est de montrer les effets de ROBERT PENNER, un + aurait été des commentaires sur la méthode utilisée.

Nickadele
Rejoignez-nous