javascript css3 css-transitions css-animations css-transforms

javascript - La combinación de animación y transición no funciona correctamente.



css3 css-transitions (2)

Es un comportamiento esperado. Necesita usar dos animaciones separadas o seguir solo con la transición.

Una transición es una animación, solo una que se realiza entre dos estados distintos, es decir, un estado inicial y un estado final. Al igual que un menú de cajón, el estado inicial podría estar abierto y el estado final podría estar cerrado, o viceversa.

Si desea realizar algo que no implique específicamente un estado inicial y un estado final, o necesita más control de grano fino sobre los fotogramas clave en una transición, entonces debe usar una animación.

Esta es la forma de animar el elemento con transición:

$(''button'').click(function() { $(''div'').toggleClass(''clicked''); });

div { background-color: #ccc; height: 100px; width: 100px; transition-property: top, left; transition-duration: 1s; transition-timing-function: linear; position: relative; top: 0; left: 0; } .clicked { top: 100px; left: 100px; }

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button type="button">Click Me!</button> <div></div>

He estado tratando de poner algo de animación CSS3 básica. El objetivo es alternar una clase en el evento de clic de un botón y animar un div basado en la clase agregada. El código funciona perfectamente para la primera iteración de alternar en Firefox, pero para otros navegadores como Chrome y para la siguiente iteración en Firefox, la transformación se activa en un abrir y cerrar de ojos. Por favor, ayúdame a descubrir qué está pasando mal.

Retazo:

$(''button'').click(function() { $(''div'').toggleClass(''clicked''); });

div { background-color: #ccc; height: 100px; width: 100px; transition-property: top, left; transition-duration: 1s; transition-timing-function: linear; position: relative; top: 0; left: 0; } .clicked { animation-name: clicked; animation-duration: 1s; animation-timing-function: linear; animation-fill-mode: forwards; } @keyframes clicked { 0% { top: 0; left: 0; } 100% { top: 100px; left: 100px; } }

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button type="button">Click Me!</button> <div></div>

También he preparado un violín here .


Este es un comportamiento conocido con Chrome. Firefox parece ser capaz de manejar la eliminación de la animación sin problemas con la transición, pero Chrome no lo hace. Había visto este comportamiento suceder antes también en este hilo .

¿Por qué la eliminación de una animación no funciona con la transición en Chrome?

Si bien no puedo proporcionar una explicación 100% infalible de por qué sucede esto, podemos decodificarlo en cierta medida en base a este artículo HTML5Rocks sobre renderizado acelerado en Chrome y este sobre composición acelerada por GPU en Chrome .

Lo que parece suceder es que el elemento obtiene su propia capa de representación porque tiene establecida una propiedad de posición explícita. Cuando una capa (o parte de ella) se invalida debido a la animación, Chrome solo vuelve a pintar esa capa que se ve afectada por el cambio. Cuando abra la Consola de desarrollador de Chrome, active la opción "Mostrar pinturas de pintura", verá que cuando se produce la animación, Chrome solo pinta el elemento real que se está animando.

Sin embargo, al comienzo y al final de la animación, se está repitiendo una página completa que vuelve a colocar el elemento en su posición original de inmediato y anula el comportamiento de transición.

$(''button'').click(function(){ $(''div'').toggleClass(''clicked''); });

div{ background-color: #ccc; height: 100px; width: 100px; transition-property: top, left; transition-duration: 1s; transition-timing-function: linear; position: relative; top: 0; left: 0; } .clicked{ animation-name: clicked; animation-duration: 1s; animation-timing-function: linear; animation-fill-mode: forwards; } @keyframes clicked{ 0% {top: 0; left: 0;} 100% {top: 100px; left: 100px;} }

<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button type="button">Click Me!</button> <div></div>

¿Cuál es la solución?

Dado que su movimiento es en realidad un movimiento lineal de una posición a otra, puede lograrlo sin la necesidad de ninguna animación. Todo lo que necesitamos hacer es usar una transformación de translate y cambiar el elemento por el no requerido. de píxeles cuando se activa la clase. Dado que hay una transición asignada al elemento a través de otro selector, el desplazamiento ocurriría de forma lineal. Mientras la clase está desactivada, el elemento vuelve a su posición original nuevamente de forma lineal debido a la transición en el elemento.

$(''button'').click(function() { $(''div'').toggleClass(''clicked''); });

div { background-color: #ccc; height: 100px; width: 100px; transition-property: transform; transition-duration: 1s; transition-timing-function: linear; position: relative; top: 0; left: 0; } .clicked { transform: translate(100px, 100px); }

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script> <button type="button">Click Me!</button> <div></div>