Imágenes animadas
Un logo, una imagen del contenido de un video, el rótulo de un presentador o la imagen de fondo de una marca puede ser un SVG animado, y su animación se reproduce en el video terminado. Suba el archivo a la biblioteca multimedia como cualquier otra imagen y úselo donde usaría una imagen fija. No hace falta activar nada más.
Qué se reproduce y cómo
Un SVG puede moverse de dos maneras, y Reelwire reproduce ambas: la animación escrita dentro del archivo con los propios elementos de animación de SVG (animate, animateTransform, animateMotion, set) y la animación escrita con CSS (@keyframes).
Cada fotograma del video se renderiza con el reloj del SVG ajustado al momento de ese fotograma en el video. Así la animación es fluida, es siempre la misma cada vez que se genera el video y empieza cuando la imagen aparece en pantalla. Un logo que gira durante su primer segundo lo hace en el momento en que la plantilla lo muestra.
Todo lo demás se renderiza como antes. Un PNG, JPEG, WebP o GIF, y un SVG sin movimiento, aparecen exactamente como siempre, de modo que ningún video que ya tenga cambia.
Ejemplos
Cada imagen de abajo es un archivo SVG completo, que se reproduce en su navegador como lo haría en un video, con el archivo entero debajo. Para probar uno, copie el código en un archivo de texto, guárdelo con un nombre que termine en .svg y súbalo a la biblioteca multimedia.
Todos siguen un mismo patrón: un elemento de animación está dentro de la forma o el grupo que mueve, e indica qué cambia (attributeName), a través de qué pasos (values, o from y to) y cuánto dura una vuelta (dur).
Mover
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 180" width="320" height="180">
<rect width="320" height="180" rx="16" fill="#0F1420"/>
<g>
<circle cx="80" cy="90" r="28" fill="#C6F432"/>
<animateTransform attributeName="transform" type="translate"
values="0 0; 160 0; 0 0" dur="3s" repeatCount="indefinite"/>
</g>
</svg>
El grupo se mueve 160 hacia la derecha y vuelve, cada tres segundos. Su último paso es igual que el primero, así que el bucle no tiene costura. El punto está dentro de un grupo y es el grupo el que se mueve, que es la forma más rápida de mover cualquier cosa (consulte Mantener rápida la generación del video).
Girar
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 180" width="320" height="180">
<rect width="320" height="180" rx="16" fill="#0F1420"/>
<rect x="130" y="60" width="60" height="60" rx="8" fill="#4FD1FF">
<animateTransform attributeName="transform" type="rotate"
from="0 160 90" to="360 160 90" dur="4s" repeatCount="indefinite"/>
</rect>
</svg>
from="0 160 90" se lee como 0 grados alrededor del punto 160, 90, el centro del cuadrado. Un giro completo termina donde empezó, así que este bucle tampoco tiene costura.
Cambiar de color
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 180" width="320" height="180">
<rect width="320" height="180" rx="16" fill="#0F1420"/>
<circle cx="160" cy="90" r="40" fill="#C6F432">
<animate attributeName="fill"
values="#C6F432; #4FD1FF; #FF7A59; #C6F432" dur="4s" repeatCount="indefinite"/>
</circle>
</svg>
animate cambia cualquier atributo a través de sus pasos, aquí el color de relleno. El mismo elemento puede cambiar un tamaño, una posición o el grosor de una línea.
Seguir un trazado
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 180" width="320" height="180">
<rect width="320" height="180" rx="16" fill="#0F1420"/>
<path d="M60 90 C60 30 260 30 260 90 S60 150 60 90" fill="none" stroke="#2A3245" stroke-width="4"/>
<circle r="12" fill="#C6F432">
<animateMotion path="M60 90 C60 30 260 30 260 90 S60 150 60 90"
dur="4s" repeatCount="indefinite"/>
</circle>
</svg>
animateMotion lleva el punto a lo largo del trazado que nombra. La línea solo está dibujada para mostrar el camino; el punto sigue el trazado se dibuje o no.
Desvanecer, con CSS
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 180" width="320" height="180">
<style>
.blink { animation: blink 2s ease-in-out infinite; }
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.2; } }
</style>
<rect width="320" height="180" rx="16" fill="#0F1420"/>
<circle class="blink" cx="104" cy="90" r="14" fill="#FF4D4D"/>
<text x="130" y="102" font-family="sans-serif" font-size="34" font-weight="700" fill="#FFFFFF">LIVE</text>
</svg>
La misma animación escrita en CSS: @keyframes nombra los pasos y animation se los asigna a todo lo de la clase blink, con dos segundos por vuelta, sin fin. Desvanecer con opacity es rápido de generar.
Una vez, desde el momento en que aparece la imagen
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 180" width="320" height="180">
<rect width="320" height="180" rx="16" fill="#0F1420"/>
<g transform="translate(160 80)">
<g>
<rect x="-32" y="-32" width="64" height="64" rx="14" fill="#C6F432"/>
<animateTransform attributeName="transform" type="scale"
from="0" to="1" dur="1s" fill="freeze"/>
</g>
</g>
<text x="160" y="150" text-anchor="middle" font-family="sans-serif" font-size="22"
font-weight="700" fill="#FFFFFF" opacity="0">Hello
<set attributeName="opacity" to="1" begin="1s"/>
</text>
</svg>
Sin repeatCount, una animación se reproduce una vez, y fill="freeze" conserva su último paso en lugar de volver al primero. set cambia algo en un momento concreto, aquí a un segundo del inicio. En un video, estos momentos se cuentan desde que la plantilla muestra la imagen, de modo que un logo así crece justo cuando aparece en pantalla. En esta página se cuentan desde que se abrió la página: recárguela para verlo de nuevo.
Las partes que fijan el tiempo
| En el archivo | Qué hace |
|---|---|
attributeName | Qué cambia: transform, fill, opacity o una posición como cx |
values | Los pasos por los que pasa, separados por punto y coma. Un último paso igual al primero hace un bucle sin costura |
from, to | Un primer y un último paso, en lugar de values |
dur | Cuánto dura una vuelta, por ejemplo 3s |
repeatCount | indefinite la repite mientras la imagen se muestre; si se omite, se reproduce una vez |
begin | Cuándo empieza, contado desde el momento en que aparece la imagen: 1s es un segundo después |
fill="freeze" | Conserva el último paso al terminar |
@keyframes, animation | Lo mismo en CSS, dentro de un elemento style del archivo |
Qué se omite y por qué
Un SVG es un pequeño programa, y Reelwire lo renderiza dentro de la página del video, por eso se limpia primero:
- Se eliminan los scripts y todo lo que ejecuta código. La animación hecha con un script dentro del archivo no se reproduce. Use en su lugar los elementos de animación del propio archivo o CSS.
- Se eliminan los enlaces a otros archivos y las direcciones web. Una imagen dentro del SVG debe estar incrustada como dirección de datos PNG, JPEG, WebP o GIF, que se conserva.
- Se eliminan los marcos, las páginas incrustadas y el sonido o el video dentro del SVG.
Si un archivo no se puede leer en absoluto, se renderiza como una imagen normal, y un SVG fijo se muestra tal como es.
Dónde se ve distinto
- Ajuste y enfoque. Una imagen dentro de un marco lo llena o cabe entera en él, como cualquier imagen. Donde una plantilla mantiene a la vista una parte de la imagen al recortar, el enfoque de un SVG se mueve en tres pasos (izquierda, centro, derecha y arriba, centro, abajo) y no de forma continua.
- Tamaño. Dé al SVG un
viewBox, o un ancho y un alto, para que conozca sus proporciones.
Mantener rápida la generación del video
La forma en que se mueve un SVG decide cuánto tarda en generarse el video, mucho más que su nivel de detalle. Reelwire genera videos sin tarjeta gráfica, así que un efecto visual (un desenfoque, un resplandor, una sombra, una textura hecha con ruido) que está sobre algo en movimiento debe renderizarse de nuevo en cada fotograma. Un paisaje detallado cuyos efectos están quietos tarda más o menos lo mismo que uno sencillo; el mismo paisaje con un filtro que se mueve sobre él puede tardar diez veces más.
- Deslice grupos enteros. Envuelva lo que se mueve en un grupo y anime la posición, el giro o el tamaño de ese grupo, en lugar de una forma que lleve un filtro.
- No anime nunca un filtro en sí. No anime la intensidad de un desenfoque ni los ajustes de un filtro de ruido.
- Desvanezca con la opacidad en un grupo propio, en lugar de cambiar un filtro.
- Mantenga aparte lo que cambia de forma. Ponga las alas, las olas o cualquier cosa que se deforme en un grupo propio, para que sus cambios no hagan que se vuelva a renderizar la imagen que está debajo.
- Repita sin costura. Si la animación se repite, haga que termine exactamente donde empieza, para que el video nunca capte el momento del reinicio.
Un resplandor suave que se desliza es rápido si el resplandor se mantiene igual y se mueve su grupo:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 180" width="320" height="180">
<defs>
<filter id="glow"><feGaussianBlur stdDeviation="6"/></filter>
</defs>
<style>
.slide { animation: slide 3s ease-in-out infinite; will-change: transform; }
@keyframes slide { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(160px); } }
</style>
<rect width="320" height="180" rx="16" fill="#0F1420"/>
<g class="slide">
<circle cx="80" cy="90" r="28" fill="#C6F432" filter="url(#glow)"/>
</g>
</svg>
Es lento cuando cambia el propio filtro, porque el desenfoque se calcula de nuevo en cada fotograma:
<filter id="glow">
<feGaussianBlur stdDeviation="6">
<!-- Avoid: the blur's amount changes, so it is drawn again on every frame -->
<animate attributeName="stdDeviation" values="6;14;6" dur="3s" repeatCount="indefinite"/>
</feGaussianBlur>
</filter>