From 00798ca173c56f410ba2602d4e788f75470d07f4 Mon Sep 17 00:00:00 2001 From: HayesGordon Date: Mon, 13 Feb 2023 18:13:08 +0000 Subject: [PATCH] Perf/flutter runtime opacity check - Adds checks to see if a drawable has a 0% opacity before performing draw commands - Add skinning example Diffs= a61f4c6b5 apply changes to rive_core 8152b8a02 docs: update CHANGELOG b8f61022c perf: check if opacity is 0 before drawing 4c4826e67 chore: add typedef argument names ff94982f9 docs: add skinning sample f1ddd88d4 Fix artboard pieces slowly popping in. (#4818) 3039909c2 Update to using deployment workflow similar to ios 53a8f9517 Fix direction when looping. (#4786) 4c5a576ad Fix ping pong hang (#4776) ae1e02afc Fix tess test linking (#4773) 4ecbf9321 Fix remap based on issue JC caught. (#4771) 89e38b700 allow negative speed (#4770) 4d115b4c6 Adding GLSL100 for tess renderer. (#4767) 31a3972aa ios shaders for tess (#4765) 686e5125b Add dependency to correct grand parent for linear gradients. (#4753) e737ee427 Revert "Update to using deployment workflow similar to ios" de0e57d55 Update to using deployment workflow similar to ios 051769242 Runtime Text! (#4741) 331ad0d55 Build cleanups 2538229d6 Use Rive's libpng premake dependency in golden testing 42a0377bc Fix condition with trim paths where all contours are 0 length. (#4722) ea1c83d02 Use os.copyfile() instead of the '{COPY}' command 5c03e1640 Remove forcing arch to arm64 for libpng (#4715) 404a04d35 Cleaning up libpng premake to be isolated/stand-alone. (#4713) --- .rive_head | 2 +- CHANGELOG.md | 4 + example/assets/skins_demo.riv | Bin 0 -> 19672 bytes example/lib/custom_controller.dart | 2 +- example/lib/main.dart | 2 + example/lib/skinning_demo.dart | 106 ++++++++++++++++++ .../rive_core/state_machine_controller.dart | 2 +- 7 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 example/assets/skins_demo.riv create mode 100644 example/lib/skinning_demo.dart diff --git a/.rive_head b/.rive_head index 4efdc80..45e5d02 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -a82894157d54309bf540efc4b1e6ab6648a328b4 +a61f4c6b55916294a69226fbd8312b602ad37466 diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e37220..684c56a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## Upcoming +- Performance improvement: No longer drawing components with an opacity of 0. +- Updated example, see "Skinning Demo". + ## 0.10.1 - Fix [[277](https://github.com/rive-app/rive-flutter/issues/277)] and [[278](https://github.com/rive-app/rive-flutter/issues/278)] that resuled in `onInit` being called with each `setState` - thank you [xuelongqy](https://github.com/xuelongqy). diff --git a/example/assets/skins_demo.riv b/example/assets/skins_demo.riv new file mode 100644 index 0000000000000000000000000000000000000000..e7ab5a5925181a86f304a66899115ba41179ca0e GIT binary patch literal 19672 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 literal 0 HcmV?d00001 diff --git a/example/lib/custom_controller.dart b/example/lib/custom_controller.dart index 0e3a79b..2954dc4 100644 --- a/example/lib/custom_controller.dart +++ b/example/lib/custom_controller.dart @@ -11,7 +11,7 @@ class SpeedyAnimation extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: const Text('Custom Controller'), + title: const Text('Custom Controller - Speed'), ), body: Center( child: RiveAnimation.asset( diff --git a/example/lib/main.dart b/example/lib/main.dart index 8afcb04..008afe0 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -10,6 +10,7 @@ import 'package:rive_example/simple_animation.dart'; import 'package:rive_example/simple_animation_network.dart'; import 'package:rive_example/simple_machine_listener.dart'; import 'package:rive_example/simple_state_machine.dart'; +import 'package:rive_example/skinning_demo.dart'; import 'package:rive_example/state_machine_skills.dart'; void main() => runApp( @@ -48,6 +49,7 @@ class _RiveExampleAppState extends State { const _Page('Custom Controller - Speed', SpeedyAnimation()), const _Page('Simple State Machine', SimpleStateMachine()), const _Page('State Machine with Listener', StateMachineListener()), + const _Page('Skinning Demo', SkinningDemo()), const _Page('Animation Carousel', AnimationCarousel()), ]; diff --git a/example/lib/skinning_demo.dart b/example/lib/skinning_demo.dart new file mode 100644 index 0000000..24fcc84 --- /dev/null +++ b/example/lib/skinning_demo.dart @@ -0,0 +1,106 @@ +import 'package:flutter/material.dart'; +import 'package:rive/rive.dart'; + +/// Basic skinning example. The skinning states is set in the Rive editor and +/// triggers are used to change the value. +class SkinningDemo extends StatefulWidget { + const SkinningDemo({Key? key}) : super(key: key); + + @override + State createState() => _SkinningDemoState(); +} + +class _SkinningDemoState extends State { + static const _skinMapping = { + "Skin_0": "Plain", + "Skin_1": "Summer", + "Skin_2": "Elvis", + "Skin_3": "Superhero", + "Skin_4": "Astronaut" + }; + + String _currentState = 'Plain'; + + SMITrigger? _skin; + + void _onRiveInit(Artboard artboard) { + final controller = StateMachineController.fromArtboard( + artboard, + 'Motion', + onStateChange: _onStateChange, + ); + + artboard.addController(controller!); + _skin = controller.findInput('Skin') as SMITrigger; + } + + void _onStateChange(String stateMachineName, String stateName) { + if (stateName.contains("Skin_")) { + setState(() { + _currentState = _skinMapping[stateName] ?? 'Plain'; + }); + } + } + + void _swapSkin() { + _skin?.fire(); + } + + @override + Widget build(BuildContext context) { + const textColor = Color(0xFFefcb7d); + + return Scaffold( + appBar: AppBar( + title: const Text('Skinning Demo'), + ), + body: Stack( + children: [ + Center( + child: RiveAnimation.asset( + 'assets/skins_demo.riv', + fit: BoxFit.cover, + onInit: _onRiveInit, + ), + ), + Align( + alignment: Alignment.topCenter, + child: Column( + children: [ + const Padding( + padding: EdgeInsets.all(24.0), + child: Text( + 'Choose an Avatar', + style: TextStyle( + fontSize: 48, + fontWeight: FontWeight.bold, + color: textColor, + ), + ), + ), + FilledButton( + onPressed: _swapSkin, + style: const ButtonStyle( + backgroundColor: + MaterialStatePropertyAll(Color(0xFF7d99ef)), + ), + child: const Text('Swap Skin'), + ), + const Spacer(), + Text( + 'Skin: $_currentState', + style: const TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + color: textColor, + ), + ), + const SizedBox(height: 48) + ], + ), + ) + ], + ), + ); + } +} diff --git a/lib/src/rive_core/state_machine_controller.dart b/lib/src/rive_core/state_machine_controller.dart index 82316b8..0cffd37 100644 --- a/lib/src/rive_core/state_machine_controller.dart +++ b/lib/src/rive_core/state_machine_controller.dart @@ -24,7 +24,7 @@ import 'package:rive/src/rive_core/rive_animation_controller.dart'; import 'package:rive/src/rive_core/shapes/shape.dart'; import 'package:rive_common/math.dart'; -/// Callback signature for satate machine state changes +/// Callback signature for state machine state changes typedef OnStateChange = void Function(String, String); /// Callback signature for layer state changes