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