Estoy animando un elemento svg actualmente como el siguiente
.r1 { transform-box: fill-box; transform-origin: 50% 50%; animation-name: simpleRotation,xRotation; animation-delay: 0s, 2s; animation-duration: 2s; animation-iteration-count: 1, 1; animation-timing-function: linear; animation-direction: normal; animation-fill-mode: forwards; } @keyframes simpleRotation { from { transform: rotate(0deg); } to { transform: rotate(359deg); } } @keyframes xRotation { from { transform: rotateX(0deg); } to { transform: rotateX(359deg); } }
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200"> <rect class="r1" id="r1" x="10" y="10" width="10" height="10" stroke="black" stroke-width="0.25" fill="orange"></rect> </svg>
¿Es posible poner en cola las animaciones (con javascript) de manera que cada 2 segundos la animación se ejecute una tras otra en un bucle como simpleRotation(0-2s);xRotation(2-4s);simpleRotation(4-6s);xRotation(6-8s);simpleRotation(8-10s);.....
Este es un caso en el que el formato de animación SVG es más fácil de usar que la animación de fotogramas clave CSS, en principio.
Las animaciones SVG pueden definir la hora de inicio de una animación en relación con los eventos, entre ellos el final de otra animación. De esta manera, puede encadenar animaciones y puede definir bucles:
<animate id="first" begin="0s;second.end" ... /> <animate id="second" begin="first.end" ... />
La primera animación comienza en 0s
y, además, se activa al final de la segunda animación, y la segunda animación se activa al final de la primera animación.
El problema con su caso de uso es que desea animar funciones de transformación 3D. La transform
SVG difiere en sintaxis de transform
CSS y solo admite transformaciones 2D. Entonces, el siguiente ejemplo puede simular el efecto en el mejor de los casos, y una serie de detalles deben escribirse de manera diferente.
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200"> <rect id="r1" x="-5" y="-5" transform="translate(15 15)" width="10" height="10" stroke="black" stroke-width="0.25" fill="orange"> <animateTransform id="simpleRotation" attributeName="transform" type="rotate" additive="sum" begin="0s;xRotation.end" dur="2s" from="0" to="360" /> <animateTransform id="xRotation" attributeName="transform" type="scale" additive="sum" begin="simpleRotation.end" dur="2s" values="1 1;1 -1;1 1" keyTimes="0;0.5;1" calcMode="spline" keySplines=".375 0 .375 1;.375 0 .375 1" /> </rect> </svg>
0,0
para simplificar las siguientes transformaciones. Cada <animateTransform>
obtiene un atributo additive="sum"
para que se multiplique posteriormente al atributo static translate()
en el objeto animado.xRotate()
, se usa una transformación de scale
que escala el eje y de 1 a -1 y viceversa. Además, se define una interpolación spline para dar la impresión de una "rotación" suave. Tenga en cuenta que esta simulación solo funciona en ausencia de una perspective
.Una alternativa al enfoque svg SMIL de ccprog podría ser usar la API de animaciones web
La animación de fotogramas clave se puede traducir a un objeto de animación como este
let ani1 = animEl.animate( [{ transform: "rotate(0deg)" }, { transform: "rotate(359deg)" }], { delay: 500, duration: 1000, iterations: 1 } );
Ver también: MDN: Uso de la API de animaciones web
let animEl = document.querySelector(".rect1"); let ani1 = animEl.animate( [{ transform: "rotate(0deg)" }, { transform: "rotate(359deg)" }], { delay: 500, duration: 1000, iterations: 1 } ); let ani2 = animEl.animate( [{ transform: "rotateX(0deg)" }, { transform: "rotateX(359deg)" }], { delay: 500, duration: 1000, iterations: 1, } ); // pause 2. animation ani2.pause(); // chain animations ani1.onfinish = function() { ani2.play(); }; ani2.onfinish = function() { ani1.play(); };
svg { border: 1px solid #ccc; display: block; width: 10em }
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"> <rect class="rect1" id="r1" x="25" y="25" width="50" height="50" stroke="black" stroke-width="0.25" fill="orange" transform-origin="50 50" ></rect> </svg>
Hacemos una pausa en el segundo al iniciar la animación a través de
ani2.pause();
y agregue un eventListener para iniciar la segunda animación después de que la primera haya terminado.
ani1.onfinish = function() { ani2.play(); };
Edite , también podría usar premisas como las describe Dan Wilson
Especialmente cuando se trata de animaciones relacionadas con svg, todavía ofrecen muchas campanas y silbatos que no están disponibles en animaciones css como
Animaciones secuenciales:
<animar[...] begin="primeraAnimación.fin" />
La capacidad de iniciar una animación consecutiva (sin ningún cálculo de la duración anterior) a través de la propiedad de begin
es simplemente increíble: este elegante concepto debería haberse adoptado para los métodos de animación CSS correspondientes.
Las animaciones SMIL tienden a tener un soporte de navegador más sólido que la API de animaciones web.
Aunque, es despreciable debido al agradecido retiro de Internet Explorer.