Skip to content

RivePanel: useSharedTexture children drift from their layout offset during scroll #633

@eli1stark

Description

@eli1stark

Summary

When a RiveWidget with useSharedTexture: true lives inside a scrollable (e.g. GridView/ListView) under a RivePanel, the Rive draw lags behind its Flutter-determined layout offset during fast scroll. The animation visibly slides inside its cell while the cell itself scrolls correctly. When scrolling stops, it snaps back into place.

A non-Rive sibling (DecoratedBox) inside the same cell stays locked to the cell as expected — only the shared-texture Rive draw drifts. This isn't the documented "cannot interleave Rive and Flutter drawing commands" limitation, since the Rive draw also drifts relative to its own cell's layout (no interleaving involved).

Minimal repro

Drop any .riv file into assets/your_animation.riv (and declare it in pubspec.yaml).

import 'package:flutter/material.dart';
import 'package:rive/rive.dart';

void main() => runApp(const MaterialApp(home: _Page()));

class _Page extends StatefulWidget {
  const _Page();

  @override
  State<_Page> createState() => _PageState();
}

class _PageState extends State<_Page> {
  File? _file;

  @override
  void initState() {
    super.initState();
    _load();
  }

  Future<void> _load() async {
    final file = await File.asset(
      'assets/your_animation.riv',
      riveFactory: Factory.rive,
    );
    if (mounted) setState(() => _file = file);
  }

  @override
  Widget build(BuildContext context) {
    final file = _file;
    if (file == null) return const Scaffold();

    return Scaffold(
      body: RivePanel(
        child: GridView.builder(
          physics: const BouncingScrollPhysics(),
          padding: const EdgeInsets.all(16),
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 2,
            mainAxisSpacing: 12,
            crossAxisSpacing: 12,
          ),
          itemCount: 40,
          itemBuilder: (_, _) => DecoratedBox(
            // Reference frame — stays locked to the cell during scroll.
            decoration: BoxDecoration(
              border: Border.all(color: const Color(0xFFFF0000), width: 3),
            ),
            child: Padding(
              padding: const EdgeInsets.all(20),
              child: RiveWidget(
                controller: RiveWidgetController(file),
                useSharedTexture: true,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

Expected

The Rive animation stays aligned with the red border throughout the scroll.

Actual

During fast scroll the Rive animation drifts inside the red border. It snaps back to alignment when scrolling stops.

Environment

  • rive: 0.14.6
  • Flutter: 3.41.5 stable
  • Platform: iOS (reproduced); we believe this is platform-agnostic but haven't verified on Android
  • Factory: Factory.rive

Notes

  • Setting useSharedTexture: false (or removing RivePanel) fully fixes the drift, at the cost of the shared-texture perf benefit.
  • Tested with multiple animations per cell; behavior is the same.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions