11522 sujets

JavaScript, DOM et API Web HTML5

Bonjour

N'ayant pas reçu de réponse à ma question http://forum.alsacreations.com/topic-4-74978-1-TransitionsetanimationsCSS3.html j'ai poursuivi mes essais d'animation avec jQuery
voir http://www.alma-musica.net/tests/train.html

Cette fois, j'ai mis un bouton pour faire démarrer le train.
Voici ce qui se passe:
Clic 1: le train part vers la gauche jusqu’à ce que le dernier wagon soit visible
Clic 2: le train part vers la droite jusqu'à ce que le premier wagon soit visible
Clic 3: le train ne bouge pas

Pourquoi?
Le programme regarde la position de la gauche du train (
var positionLeft = $train.position()['left'];
)
Selon que positionLeft est négatif ou non, il sait dans quelle direction lancer le mouvement du train
Pour partir vers la gauche, le mouvement se fait par
$train.animate({right:0}, 2500, ...);

pour partir vers la droite, il se fait par
$train.animate({left:0}, 2500, ...);

Mais (j'ai regardé par FireBig) jQuery ne recalcule pas la valeur de "right" lors du 2ème clic et laisse la valeur 0 qui était l'objet de la première animation.

Question: comment contourner ce problème?

Merci de vos propositions de solution.
Modifié par PapyJP (02 Mar 2015 - 12:46)
Modérateur
le Problème est qu'à l'origine, on a:
left: auto; right: auto;

lors de la 1re animation: $train.animate({right:0}, 2500, function(){direction=''});
jQuery évalue la valeur actuelle calculée et la fait passer à 0;

left: auto; right: 0;

Même chose à l'inverse pour la seconde et on passe à:

left: 0; right: 0;

Du coup dans cette situation, #train prend exactement la largeur du conteneur et left sera toujours évalué à 0 et right toujours évalué à 0 vu que c'est ses positions. (par contre le contenu (donc les wagons) dépassent de #train et sortent à droite.

On pourrait contourner ce problème en faisant passer left ou right à auto à des moments judicieux:
$('#train').css('left', 'auto');

Mais le plus simple à mon avis est de ne se servir que d'une seule coordonées, finalement on oscille itérativement entre
left = 0
et
left = $('#conteneur').width() - $('#train').width()
Modifié par kustolovic (02 Mar 2015 - 14:32)
@kustolovic
Merci 1000 fois!

Entre temps j'ai effectivement testé en local la solution "left only" qui bien entendu fonctionne, mais je n'aime pas trop faire ce genre de calcul alors que right:0 est beaucoup plus clair.
Je vais essayer "auto" et voir ce que ça donne. Ça correspondrait plus à ce que j'avais envie de faire.

Edit: je viens de tester la solution 'auto' comme suit; ça ne marche pas, mais peut être y a-t-il quelque chose que je ne vois pas:

            $('button').click(function(){
                    var $train = $('#train');
                    var positionLeft = $train.position()['left'];
                   /* var trainWidth = $train.width();
                    var containerWidth = $('#container').width();
                    var trainOverflow = trainWidth - containerWidth;*/
                    console.log('direction=', direction, 'positionLeft=', positionLeft);
                    if(direction == '') {
                       if(positionLeft < 0) {
                           direction = 'toRight';
                           console.log('direction=', direction, 'positionLeft=', positionLeft);
                           $train.animate({left:0}, 2500, function(){
                                direction='';
                                $train.css({right:'auto'});
                            });
                       }
                       else {
                           direction = 'toLeft';
                           console.log('direction=', direction, 'positionLeft=', positionLeft);
                           $train.animate({right:0}, 2500, function(){
                                direction='';
                                $train.css({left:'auto'});
                            });
                       }
                   }
                });

Une idée avant que je laisse tomber?
Modifié par PapyJP (02 Mar 2015 - 14:49)