blob: f1e9865f55309c53c82e5c5202e428ecbf666995 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.6
import 'dart:math' as math;
import 'dart:ui';
import 'scenario.dart';
/// A square that animates it color and bounces off the sides of the
/// device.
///
/// This scenario drives animation as quickly as possible, requesting new frames
/// that are constantly changing.
class AnimatedColorSquareScenario extends Scenario {
/// Creates the AnimatedColorSquare scenario.
///
/// The [window] parameter must not be null.
AnimatedColorSquareScenario(Window window)
: assert(window != null),
super(window);
static const double _squareSize = 200;
/// Used to animate the red value in the color of the square.
final _NumberSwinger<int> _r = _NumberSwinger<int>(0, 255);
_NumberSwinger<double> _top = _NumberSwinger<double>(
0,
window.physicalSize.height - _squareSize,
);
_NumberSwinger<double> _left = _NumberSwinger<double>(
0,
window.physicalSize.width - _squareSize,
);
@override
void onBeginFrame(Duration duration) {
final SceneBuilder builder = SceneBuilder();
final PictureRecorder recorder = PictureRecorder();
final Canvas canvas = Canvas(recorder);
canvas.drawRect(
const Rect.fromLTWH(0, 0, _squareSize, _squareSize),
Paint()..color = Color.fromARGB(255, _r.swing(), 50, 50),
);
final Picture picture = recorder.endRecording();
builder.pushOffset(_left.swing(), _top.swing());
builder.addPicture(
Offset.zero,
picture,
willChangeHint: true,
);
final Scene scene = builder.build();
window.render(scene);
scene.dispose();
}
@override
void onDrawFrame() {
window.scheduleFrame();
}
@override
void onMetricsChanged() {
_top = _NumberSwinger<double>(
0,
window.physicalSize.height - _squareSize,
math.min(_top.current, window.physicalSize.height - _squareSize),
);
_left = _NumberSwinger<double>(
0,
window.physicalSize.width - _squareSize,
math.min(_left.current, window.physicalSize.width - _squareSize),
);
}
}
class _NumberSwinger<T extends num> {
_NumberSwinger(this._begin, this._end, [this._current])
: assert(_begin != null),
assert(_end != null),
_up = _begin < _end {
_current ??= _begin;
}
final T _begin;
final T _end;
/// The current value of the swinger.
T get current => _current;
T _current;
bool _up;
T swing() {
if (_current >= _end) {
_up = false;
} else if (_current <= _begin) {
_up = true;
}
_current = (_up ? _current + 1 : _current - 1) as T;
return _current;
}
}