Ir al contenido
charmotion

Rive en Compose Multiplatform e Ionic/Capacitor

Por el equipo de Charmotion · Actualizado el

Ilustración de portada de la guía de frameworks y no-code: Rive en Compose Multiplatform e Ionic/Capacitor, con personajes de demostración de Charmotion

Rive no tiene un runtime oficial para Compose Multiplatform; el wrapper comunitario RiveCMP, que aparece en la documentación de Rive, envuelve rive-android, rive-ios y el runtime web, y está marcado como experimental. Las apps de Ionic y Capacitor renderizan código web, así que usan directamente el runtime web oficial de Rive, @rive-app/canvas. Incluye rive.wasm en el paquete con RuntimeLoader.setWasmUrl() para que la app funcione sin conexión.

Puntos clave

  • RiveCMP lo mantiene la comunidad y es experimental; no pertenece a Rive.
  • En iOS, RiveCMP no puede renderizar fondos transparentes, según su README.
  • Las apps de Capacitor ejecutan el runtime web estándar dentro del WebView nativo.
  • Por defecto, el runtime web descarga rive.wasm desde unpkg; inclúyelo en el paquete para que la app abra sin conexión.
  • Cuando un wrapper de plataforma es demasiado arriesgado, el video con fondo transparente se reproduce en todas partes.

¿Rive tiene soporte oficial para Compose Multiplatform?

No. Rive mantiene runtimes oficiales para Android (incluido Jetpack Compose), las plataformas de Apple y la web, pero ninguno dirigido directamente a Compose Multiplatform. La documentación de Rive incluye RiveCMP entre los runtimes de la comunidad, junto con Angular, C# y Qt, y aclara que no es un proyecto propiedad de Rive ni mantenido por Rive.

Eso deja tres opciones para una app de Kotlin Multiplatform:

OpciónMantenido porPlataformasVentajas y desventajas
RiveCMPComunidadAndroid, iOS, webUna sola API de Compose; experimental
Runtimes oficiales detrás de expect/actualRiveCada plataformaMás código de integración; soporte completo
Exportaciones de videoNo hace falta ningunoTodasSin máquina de estados

La segunda opción vale la pena para apps en producción. Declara un composable expect, como Mascot(mood: Int), en el código común, impleméntalo con el runtime oficial de Android en Android y envuelve la vista del runtime de Apple en UIKitView en iOS. Escribes un poco más de código, pero Rive mantiene cada ruta de renderizado.

¿Qué es RiveCMP y qué tan estable es?

RiveCMP, publicado en GitHub como muazkadan/Rive-CMP, ofrece a Compose Multiplatform una sola API sobre tres runtimes oficiales: rive-android en Android, rive-ios en iOS y @rive-app/canvas en la web. La documentación de Rive lo describe como una biblioteca wrapper para Compose Multiplatform y enlaza a él.

Su README califica el proyecto como experimental. En la práctica, eso significa:

  • Las API pueden cambiar entre versiones, así que fija la versión y lee las notas de la versión antes de actualizar.
  • Es posible que no se expongan todas las funciones de los runtimes subyacentes. Comprueba si la versión que usas admite inputs de la máquina de estados y Data Binding antes de construir sobre ellos.
  • Depende de que un solo mantenedor siga el ritmo de las actualizaciones de runtime de Rive en tres plataformas.

Para prototipos, herramientas internas o apps que ya aceptan cierto riesgo en su stack de Kotlin Multiplatform, es una forma rápida de mostrar un personaje en pantalla en todas partes. Sigue el README para obtener las coordenadas de Gradle y los nombres de composables actuales, en lugar de copiar fragmentos de publicaciones antiguas.

Tabla de decisión: APIs integradas para el feedback de la interfaz, efectos de íconos para íconos, una máquina de estados de Rive para personajes y video para clips de marketing
Elige el método de animación según la tarea.

¿Qué limitaciones en iOS debo esperar con RiveCMP?

La principal documentada es la transparencia. En iOS, RiveCMP aloja la vista nativa de Rive dentro de Compose mediante UIKitView, y su README indica que esto no puede renderizar fondos transparentes. Una mascota de marca que flota sobre el fondo de tu pantalla en Android puede quedar dentro de un recuadro sólido en iOS.

Formas de resolverlo:

  • Coloca el personaje sobre una superficie sólida, como una tarjeta, cuyo color coincida con el fondo de la vista.
  • Diseña el artboard con su propia forma de fondo para que el recuadro se vea intencional.
  • Usa el enfoque expect/actual en iOS con el runtime oficial de Apple y prueba la transparencia en tu propia configuración.

Las vistas de interoperabilidad también se comportan distinto del contenido puro de Compose: se dibujan en una capa separada, por lo que los elementos de Compose superpuestos, el recorte y las animaciones del contenedor pueden verse diferentes que en Android. Prueba en un iPhone real, no solo en el simulador, y revisa las listas con scroll donde aparecen varias mascotas.

¿Cómo uso Rive en una app de Ionic o Capacitor?

Usa el runtime web exactamente como lo harías en un sitio web. Capacitor ejecuta tu app web dentro del WebView de la plataforma, así que @rive-app/canvas funciona sin ningún plugin nativo, ya sea que tu app de Ionic use Angular, React o Vue.

import { Rive } from "@rive-app/canvas";

const r = new Rive({
  src: "/assets/character.riv",
  canvas: document.getElementById("mascot"),
  stateMachine: "CharacterViewModelMachine",
  autoplay: true,
  autoBind: true,
  onLoad: () => {
    r.resizeDrawingSurfaceToCanvas();
    r.viewModelInstance.number("mood").value = 0;    // idle
  },
});

// later, from app events
r.viewModelInstance.number("mood").value = 5;        // loading
r.viewModelInstance.trigger("success").trigger();    // one-shot

// when the page or component is destroyed
r.cleanup();

Crea la instancia en el hook de montaje de tu framework (ngAfterViewInit, useEffect u onMounted) y llama a cleanup() cuando se destruya la página. Ionic mantiene las páginas activas en su pila de navegación, así que pausa las mascotas fuera de pantalla con r.pause() cuando una página deja de verse y usa r.play() cuando vuelve. Las guías de Angular y Vue muestran componentes completos.

¿Debo alojar rive.wasm por mi cuenta en apps de Capacitor sin conexión?

Sí. La documentación de Rive explica que el runtime web descarga rive.wasm desde unpkg por defecto. En un navegador eso suele estar bien; en una app móvil significa que la mascota falla en el primer inicio sin conexión, y una revisión de la tienda en una red restringida podría ver un espacio vacío. Incluye el archivo en el paquete y apunta el runtime hacia él antes de crear cualquier instancia:

import { RuntimeLoader } from "@rive-app/canvas";
import riveWasmUrl from "@rive-app/canvas/rive.wasm?url";

// Run once, before the first new Rive(...)
RuntimeLoader.setWasmUrl(riveWasmUrl);

En un proyecto de Ionic basado en Vite, la importación ?url copia el wasm en tu build, y npx cap sync lo incluye dentro de la app. Con otros bundlers, copia el archivo desde node_modules/@rive-app/canvas/rive.wasm a tus assets durante el build. La documentación de Rive exige que la versión del wasm coincida con la versión instalada del paquete @rive-app, así que cópialo siempre desde el paquete instalado, nunca desde una descarga.

Incluye también el .riv en el paquete. Los archivos de Charmotion tienen un peso adecuado para esto: un solo .riv contiene las 17 animaciones generadas a partir de tu personaje o logo, con un view model Character (un número mood de 0 a 9 y seis triggers) e inputs heredados de CharacterStateMachine, junto con un ejemplo web index.html que funciona tal cual en un WebView de Capacitor.

¿Cuándo es una exportación de video la opción multiplataforma más segura?

Cuando la animación no necesita reaccionar, o cuando ninguna ruta de runtime es sólida en alguna de tus plataformas. El video se reproduce de forma nativa en todos los lugares donde funcionan Compose Multiplatform y Capacitor, sin ningún wrapper que mantener.

  • Loops de splash screen y onboarding que siempre se reproducen igual.
  • Pantallas de marketing donde el peso del archivo importa menos que la fidelidad.
  • Plataformas donde tu ruta con Rive es experimental, como respaldo detrás de un feature flag.

La desventaja es la flexibilidad: cada estado es otro archivo, y cambiar entre ellos implica reemplazar la fuente y aceptar un corte visible. El video con fondo transparente además requiere dos codificaciones (HEVC con canal alfa para plataformas de Apple y WebM VP9 para las demás). La comparación de formatos detalla pesos y compatibilidad.

Un enfoque híbrido habitual es usar video en la primera versión en todas las plataformas y luego Rive en las plataformas donde tu ruta de runtime demuestre ser estable.

Diez estados en loop de un mismo personaje, cada uno seleccionado con un número de mood del 0 al 9
Los diez estados en loop de un archivo Rive de Charmotion, seleccionados con el input numérico mood.

Cómo ejecutar Rive sin conexión en una app de Capacitor

  1. Instala el runtime. Ejecuta npm install @rive-app/canvas en el proyecto de Ionic o Capacitor.
  2. Incluye el wasm. Importa @rive-app/canvas/rive.wasm?url y pásalo a RuntimeLoader.setWasmUrl() antes de crear instancias.
  3. Incluye el .riv. Coloca el archivo en los assets de tu app para que se incluya en el build.
  4. Crea la instancia. Usa stateMachine: "CharacterViewModelMachine" y autoBind: true en el hook de montaje de la página.
  5. Controla y pausa. Define el estado de ánimo y dispara triggers desde los eventos de la app; pausa la animación cuando la página deja de estar visible.
  6. Sincroniza y prueba sin conexión. Ejecuta npx cap sync y abre la app en modo avión.

Preguntas frecuentes

¿Puedo usar la API de Compose de Rive para Android en Compose Multiplatform?

Solo en tu source set de Android. El runtime de Rive para Android, incluido su soporte para Compose, depende de bibliotecas de Android, así que el código común no puede llamarlo. Úsalo en la implementación actual de Android de un composable expect y usa el runtime de Apple en la implementación de iOS, o adopta el wrapper RiveCMP.

¿Rive tiene buen rendimiento en un WebView de Capacitor?

Las WebViews modernas de iOS y Android ejecutan bien WebAssembly y el renderizado en canvas, así que una o dos mascotas de marca rinden igual que en Safari o Chrome para móviles. Usa @rive-app/canvas cuando una pantalla muestre muchas animaciones, y pausa las instancias en las páginas que Ionic mantiene en su pila de navegación pero que no están visibles.

¿Existe un plugin de Capacitor para renderizar Rive de forma nativa?

Rive no publica ninguno, y su documentación no incluye un runtime de Capacitor de la comunidad. El camino con soporte es el runtime web dentro de la WebView. Si necesitas renderizado totalmente nativo en una pantalla, esa parte de la app funciona mejor con una vista nativa que use el runtime oficial de Rive para iOS o Android.

Respuestas rápidas de esta guía

Fuentes

Guías relacionadas