Реализация Rive-анимаций на сайте

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация Rive-анимаций на сайте
Средняя
~2-3 рабочих дня
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Реализация Rive-анимаций на сайте

Rive — инструмент для создания интерактивных анимаций с State Machine. В отличие от Lottie (линейное воспроизведение), Rive-анимации реагируют на события: клики, наведение, ввод данных, внешние триггеры. Рантайм легковесный (~40 КБ gzip), рендерит через WebGL или Canvas 2D.

Установка

npm install @rive-app/react-canvas
# или WebGL-рендерер (лучше для сложных сцен):
npm install @rive-app/react-webgl2

Базовая интеграция

// components/RiveAnimation.tsx
'use client'
import { useRive, Layout, Fit, Alignment } from '@rive-app/react-canvas'

interface RiveAnimationProps {
  src: string
  stateMachine?: string
  animation?: string
  className?: string
}

export function RiveAnimation({
  src,
  stateMachine,
  animation,
  className,
}: RiveAnimationProps) {
  const { RiveComponent } = useRive({
    src,
    stateMachines: stateMachine ? [stateMachine] : undefined,
    animations: animation ? [animation] : undefined,
    autoplay: true,
    layout: new Layout({
      fit: Fit.Contain,
      alignment: Alignment.Center,
    }),
  })

  return <RiveComponent className={className} />
}

State Machine: управление состояниями

State Machine — главная фишка Rive. Дизайнер создаёт граф переходов между анимациями, разработчик управляет входными параметрами (inputs):

// components/InteractiveButton.tsx
'use client'
import { useRive, useStateMachineInput } from '@rive-app/react-canvas'

export function RiveButton() {
  const { RiveComponent, rive } = useRive({
    src: '/animations/button.riv',
    stateMachines: 'ButtonSM',
    autoplay: true,
  })

  // Получаем inputs из State Machine
  const isHoverInput = useStateMachineInput(rive, 'ButtonSM', 'isHover')
  const isPressedInput = useStateMachineInput(rive, 'ButtonSM', 'isPressed')
  const isLoadingInput = useStateMachineInput(rive, 'ButtonSM', 'isLoading')

  const handleClick = async () => {
    if (isLoadingInput) isLoadingInput.value = true
    await fetch('/api/action')
    if (isLoadingInput) isLoadingInput.value = false
  }

  return (
    <button
      className="relative w-48 h-14"
      onMouseEnter={() => isHoverInput && (isHoverInput.value = true)}
      onMouseLeave={() => isHoverInput && (isHoverInput.value = false)}
      onMouseDown={() => isPressedInput && (isPressedInput.value = true)}
      onMouseUp={() => isPressedInput && (isPressedInput.value = false)}
      onClick={handleClick}
    >
      <RiveComponent />
    </button>
  )
}

Триггеры и числовые inputs

State Machine поддерживает три типа inputs:

  • Boolean — переключатель (hover, active, visible)
  • Number — числовое значение (прогресс, уровень, скорость)
  • Trigger — одноразовое событие (клик, успех, ошибка)
// components/ProgressRive.tsx
'use client'
import { useRive, useStateMachineInput } from '@rive-app/react-canvas'

interface ProgressRiveProps {
  progress: number // 0–100
}

export function ProgressRive({ progress }: ProgressRiveProps) {
  const { RiveComponent, rive } = useRive({
    src: '/animations/progress.riv',
    stateMachines: 'ProgressSM',
    autoplay: true,
  })

  const progressInput = useStateMachineInput(rive, 'ProgressSM', 'progress')
  const completeTrigger = useStateMachineInput(
    rive,
    'ProgressSM',
    'complete',
    false // это триггер, не boolean
  )

  // Синхронизируем progress при изменении пропса
  if (progressInput) progressInput.value = progress
  if (progress >= 100 && completeTrigger) completeTrigger.fire()

  return <RiveComponent style={{ width: 300, height: 80 }} />
}

Отслеживание событий из Rive

Rive может отправлять события обратно в JavaScript:

// components/RiveWithEvents.tsx
'use client'
import { useEffect } from 'react'
import { useRive, EventType, RiveEvent } from '@rive-app/react-canvas'

export function RiveWithEvents() {
  const { RiveComponent, rive } = useRive({
    src: '/animations/interactive.riv',
    stateMachines: 'Main',
    autoplay: true,
  })

  useEffect(() => {
    if (!rive) return

    const handler = (event: RiveEvent) => {
      const { name, properties } = event.data as any

      switch (name) {
        case 'ButtonClicked':
          console.log('Rive кнопка нажата, данные:', properties)
          break
        case 'AnimationComplete':
          console.log('Анимация завершена')
          break
      }
    }

    rive.on(EventType.RiveEvent, handler)
    return () => rive.off(EventType.RiveEvent, handler)
  }, [rive])

  return <RiveComponent style={{ width: 400, height: 300 }} />
}

Оптимизация: ручной Canvas

Для максимального контроля (несколько Rive-инстанций, кастомный цикл рендера):

// components/LowLevelRive.tsx
'use client'
import { useEffect, useRef } from 'react'
import Rive, { Fit } from '@rive-app/canvas'

export function LowLevelRive({ src }: { src: string }) {
  const canvasRef = useRef<HTMLCanvasElement>(null)

  useEffect(() => {
    if (!canvasRef.current) return

    const r = new Rive({
      canvas: canvasRef.current,
      src,
      autoplay: true,
      onLoad: () => {
        r.resizeDrawingSurfaceToCanvas()
      },
    })

    // Обработка resize
    const observer = new ResizeObserver(() => {
      r.resizeDrawingSurfaceToCanvas()
    })
    observer.observe(canvasRef.current)

    return () => {
      r.cleanup()
      observer.disconnect()
    }
  }, [src])

  return (
    <canvas
      ref={canvasRef}
      style={{ width: '100%', height: '100%' }}
    />
  )
}

Типичные сроки

Воспроизведение готового .riv-файла — 2–3 часа. Интеграция с State Machine, inputs, событиями — 1–2 рабочих дня. Создание самого .riv-файла в Rive Editor (если нет готового) — отдельная задача для дизайнера/моушн-дизайнера.