Pular para o conteúdo
charmotion

Rive no Compose Multiplatform e Ionic/Capacitor

Por equipe Charmotion · Atualizado em

Ilustração de capa do guia de frameworks e no-code: Rive no Compose Multiplatform e no Ionic/Capacitor, com personagens de demonstração do Charmotion

O Rive não tem runtime oficial para Compose Multiplatform; o wrapper da comunidade RiveCMP, listado na documentação do Rive, encapsula o rive-android, o rive-ios e o runtime web e é marcado como experimental. Apps Ionic e Capacitor renderizam código web, então usam diretamente o runtime web oficial do Rive, @rive-app/canvas. Inclua o rive.wasm no pacote com RuntimeLoader.setWasmUrl() para o app funcionar offline.

Principais pontos

  • O RiveCMP é mantido pela comunidade e experimental; ele não pertence ao Rive.
  • No iOS, o RiveCMP não consegue renderizar fundos transparentes, segundo o README.
  • Apps Capacitor rodam o runtime web padrão dentro da WebView nativa.
  • Por padrão, o runtime web baixa o rive.wasm do unpkg; inclua-o no pacote para aberturas offline.
  • Quando um wrapper de plataforma é arriscado demais, o vídeo com fundo transparente roda em qualquer lugar.

Existe suporte oficial do Rive para Compose Multiplatform?

Não. O Rive mantém runtimes oficiais para Android (incluindo Jetpack Compose), plataformas Apple e web, mas nada voltado diretamente ao Compose Multiplatform. A documentação do Rive lista o RiveCMP entre os runtimes da comunidade, ao lado de Angular, C# e Qt, e informa que não é um projeto do Rive nem mantido por ele.

Isso deixa três opções para um app Kotlin Multiplatform:

OpçãoMantenedorPlataformasPrós e contras
RiveCMPComunidadeAndroid, iOS, webUma API Compose; experimental
Runtimes oficiais por trás de expect/actualRiveCada plataformaMais código de integração; suporte completo
Exportações em vídeoNenhum necessárioTodasSem state machine

Vale a pena considerar a segunda opção para apps em produção. Declare um composable expect, como Mascot(mood: Int), no código comum, implemente-o com o runtime oficial do Android no Android e envolva a view do runtime Apple em UIKitView no iOS. Você escreve um pouco mais de código, mas todos os caminhos de renderização são mantidos pelo Rive.

O que é o RiveCMP e quão estável ele é?

O RiveCMP, publicado no GitHub como muazkadan/Rive-CMP, oferece ao Compose Multiplatform uma única API sobre três runtimes oficiais: rive-android no Android, rive-ios no iOS e @rive-app/canvas na web. A documentação do Rive o descreve como uma biblioteca wrapper para Compose Multiplatform e inclui um link para ele.

O README chama o projeto de experimental. Na prática, isso significa:

  • As APIs podem mudar entre versões, então fixe a versão e leia as notas de versão antes de atualizar.
  • Talvez nem todos os recursos dos runtimes subjacentes estejam expostos. Verifique se a versão que você usa oferece suporte a inputs de state machine e Data Binding antes de construir em cima deles.
  • Ele depende de um único mantenedor acompanhar as atualizações de runtime do Rive em três plataformas.

Para protótipos, ferramentas internas ou apps que já aceitam algum risco na stack Kotlin Multiplatform, é uma forma rápida de colocar um personagem na tela em todas as plataformas. Siga o README para as coordenadas Gradle e os nomes de composables atuais, em vez de copiar trechos de posts antigos.

Tabela de decisão: APIs nativas para feedback de interface, efeitos de ícone para ícones, uma state machine do Rive para personagens, vídeo para clipes de marketing
Escolha o método de animação conforme a tarefa.

Quais limitações no iOS devo esperar com o RiveCMP?

A principal documentada é a transparência. No iOS, o RiveCMP hospeda a view nativa do Rive dentro do Compose por meio de UIKitView, e o README observa que isso não consegue renderizar fundos transparentes. Um mascote que flutua sobre o fundo da tela no Android pode ficar dentro de uma caixa sólida no iOS.

Formas de lidar com isso:

  • Coloque o personagem sobre uma superfície sólida, como um card, cuja cor combine com o fundo da view.
  • Crie o artboard com uma forma de fundo própria, para que a caixa pareça intencional.
  • Use a abordagem expect/actual no iOS com o runtime oficial da Apple e teste a transparência na sua própria configuração.

Views de interoperabilidade também se comportam de forma diferente do conteúdo Compose puro: elas são desenhadas em uma camada separada, então elementos Compose sobrepostos, recortes e animações do contêiner podem ficar diferentes do Android. Teste em um iPhone real, não só no simulador, e verifique listas com rolagem onde aparecem vários mascotes.

Como usar Rive em um app Ionic ou Capacitor?

Use o runtime web exatamente como faria em um site. O Capacitor roda seu app web dentro da WebView da plataforma, então o @rive-app/canvas funciona sem nenhum plugin nativo, seja seu app Ionic feito com Angular, React ou 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();

Crie a instância no hook de montagem do seu framework (ngAfterViewInit, useEffect ou onMounted) e chame cleanup() quando a página for destruída. O Ionic mantém as páginas ativas na pilha de navegação, então pause os mascotes fora da tela com r.pause() quando a página sair de vista e use r.play() quando ela voltar. Os guias de Angular e Vue mostram componentes completos.

Devo hospedar o rive.wasm por conta própria em apps Capacitor offline?

Sim. A documentação do Rive explica que o runtime web baixa o rive.wasm do unpkg por padrão. No navegador isso costuma funcionar bem; em um app mobile, significa que o mascote falha na primeira abertura sem conexão, e o revisor da loja, em uma rede restrita, pode ver só um espaço vazio. Inclua o arquivo no pacote e aponte o runtime para ele antes de criar qualquer instância:

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);

Em um projeto Ionic baseado em Vite, o import com ?url copia o wasm para o build, e o npx cap sync o inclui dentro do app. Com outros bundlers, copie o arquivo de node_modules/@rive-app/canvas/rive.wasm para os seus assets durante o build. A documentação do Rive exige que a versão do wasm corresponda à versão instalada do pacote @rive-app, então sempre copie do pacote instalado, nunca de um download.

Inclua o .riv no pacote também. Os arquivos do Charmotion têm um bom tamanho para isso: um único .riv traz todas as 17 animações geradas a partir do seu personagem ou logo, com um view model Character (um número mood de 0 a 9 e seis triggers) e inputs legados da CharacterStateMachine, junto com um exemplo web index.html que roda sem alterações em uma WebView do Capacitor.

Quando uma exportação em vídeo é a opção multiplataforma mais segura?

Quando a animação não precisa reagir, ou quando nenhum caminho de runtime é confiável em uma das suas plataformas. O vídeo roda nativamente em todos os lugares onde Compose Multiplatform e Capacitor rodam, sem wrapper para manter.

  • Loops de splash e onboarding que sempre tocam do mesmo jeito.
  • Telas de marketing em que o tamanho do arquivo importa menos que a fidelidade.
  • Plataformas em que seu caminho com Rive ainda é experimental, como alternativa protegida por uma feature flag.

O preço é a flexibilidade: cada estado é outro arquivo, e alternar entre eles significa trocar as fontes e aceitar um corte visível. O vídeo com fundo transparente também exige duas codificações (HEVC com canal alfa para plataformas Apple, VP9 WebM nas demais). O comparativo de formatos detalha tamanhos e suporte.

Um híbrido comum é usar vídeo na primeira versão em todas as plataformas e depois Rive nas plataformas em que seu caminho de runtime se mostrar estável.

Dez estados em loop de um personagem, cada um selecionado por um número de mood de 0 a 9
Os dez estados em loop em um arquivo Rive do Charmotion, selecionados com o input numérico mood.

Como rodar Rive offline em um app Capacitor

  1. Instale o runtime. Execute npm install @rive-app/canvas no projeto Ionic ou Capacitor.
  2. Inclua o wasm no pacote. Importe @rive-app/canvas/rive.wasm?url e passe para RuntimeLoader.setWasmUrl() antes de criar instâncias.
  3. Inclua o .riv no pacote. Coloque o arquivo nos assets do app para que ele seja incluído no build.
  4. Crie a instância. Use stateMachine: "CharacterViewModelMachine" e autoBind: true no hook de montagem da página.
  5. Controle e pause. Defina o humor e dispare triggers a partir de eventos do app; pause quando a página sair da tela.
  6. Sincronize e teste offline. Execute npx cap sync e abra o app no modo avião.

Perguntas frequentes

Posso usar a API Compose do Rive para Android no Compose Multiplatform?

Só no source set do Android. O runtime Android do Rive, incluindo o suporte a Compose, depende de bibliotecas do Android, então o código comum não consegue chamá-lo. Use-o na implementação actual do Android de um composable expect e use o runtime da Apple na implementação para iOS, ou adote o wrapper RiveCMP.

O Rive tem boa performance em uma WebView do Capacitor?

As WebViews modernas do iOS e do Android rodam bem WebAssembly e renderização em canvas, então um ou dois mascotes têm a mesma performance que no Safari ou no Chrome para celular. Use @rive-app/canvas quando uma tela exibir muitas animações e pause as instâncias em páginas que ficam na pilha de navegação do Ionic, mas não estão visíveis.

Existe um plugin do Capacitor para renderização nativa do Rive?

O Rive não publica nenhum, e a documentação dele não lista um runtime da comunidade para Capacitor. O caminho com suporte é o runtime web dentro da WebView. Se você precisa de renderização totalmente nativa em uma tela, essa parte do app fica melhor com uma view nativa usando o runtime oficial do Rive para iOS ou Android.

Respostas rápidas deste guia

Fontes

Guias relacionados