| 1 | // Copyright 2014 The Flutter Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | // This example shows how to perform a simple animation using the underlying |
| 6 | // render tree. |
| 7 | |
| 8 | import 'dart:math' as math; |
| 9 | |
| 10 | import 'package:flutter/animation.dart'; |
| 11 | import 'package:flutter/rendering.dart'; |
| 12 | import 'package:flutter/scheduler.dart'; |
| 13 | |
| 14 | import 'src/binding.dart'; |
| 15 | |
| 16 | class NonStopVSync implements TickerProvider { |
| 17 | const NonStopVSync(); |
| 18 | @override |
| 19 | Ticker createTicker(TickerCallback onTick) => Ticker(onTick); |
| 20 | } |
| 21 | |
| 22 | void main() { |
| 23 | // We first create a render object that represents a green box. |
| 24 | final RenderBox green = RenderDecoratedBox( |
| 25 | decoration: const BoxDecoration(color: Color(0xFF00FF00)), |
| 26 | ); |
| 27 | // Second, we wrap that green box in a render object that forces the green box |
| 28 | // to have a specific size. |
| 29 | final RenderBox square = RenderConstrainedBox( |
| 30 | additionalConstraints: const BoxConstraints.tightFor(width: 200.0, height: 200.0), |
| 31 | child: green, |
| 32 | ); |
| 33 | // Third, we wrap the sized green square in a render object that applies rotation |
| 34 | // transform before painting its child. Each frame of the animation, we'll |
| 35 | // update the transform of this render object to cause the green square to |
| 36 | // spin. |
| 37 | final RenderTransform spin = RenderTransform( |
| 38 | transform: Matrix4.identity(), |
| 39 | alignment: Alignment.center, |
| 40 | child: square, |
| 41 | ); |
| 42 | // Finally, we center the spinning green square... |
| 43 | final RenderBox root = RenderPositionedBox(child: spin); |
| 44 | // and attach it to the window. |
| 45 | ViewRenderingFlutterBinding(root: root); |
| 46 | |
| 47 | // To make the square spin, we use an animation that repeats every 1800 |
| 48 | // milliseconds. |
| 49 | final AnimationController animation = AnimationController( |
| 50 | duration: const Duration(milliseconds: 1800), |
| 51 | vsync: const NonStopVSync(), |
| 52 | )..repeat(); |
| 53 | // The animation will produce a value between 0.0 and 1.0 each frame, but we |
| 54 | // want to rotate the square using a value between 0.0 and math.pi. To change |
| 55 | // the range of the animation, we use a Tween. |
| 56 | final Tween<double> tween = Tween<double>(begin: 0.0, end: math.pi); |
| 57 | // We add a listener to the animation, which will be called every time the |
| 58 | // animation ticks. |
| 59 | animation.addListener(() { |
| 60 | // This code runs every tick of the animation and sets a new transform on |
| 61 | // the "spin" render object by evaluating the tween on the current value |
| 62 | // of the animation. Setting this value will mark a number of dirty bits |
| 63 | // inside the render tree, which cause the render tree to repaint with the |
| 64 | // new transform value this frame. |
| 65 | spin.transform = Matrix4.rotationZ(tween.evaluate(animation)); |
| 66 | }); |
| 67 | } |
| 68 | |