Skip to content

Instantly share code, notes, and snippets.

@flar
Created March 10, 2020 23:37
Show Gist options
  • Save flar/639cf7fcc0988ee9d68333c269e42181 to your computer and use it in GitHub Desktop.
Save flar/639cf7fcc0988ee9d68333c269e42181 to your computer and use it in GitHub Desktop.
Using Transform vs ImageFiltered to rotate widget
import 'dart:math';
import 'dart:ui';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
AnimationController _controller;
bool _useFilter = false;
bool _complexChild = false;
GlobalKey _childKey = GlobalKey(debugLabel: 'child to rotate');
Offset _childCenter = Offset.zero;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
RenderBox childBox = _childKey.currentContext.findRenderObject();
Offset localCenter = childBox.paintBounds.center;
_childCenter = childBox.localToGlobal(localCenter);
});
_controller = AnimationController(vsync: this, duration: Duration(seconds: 2));
_controller.repeat();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
Widget makeChild(double w, double h) {
if (_complexChild) {
return Stack(
children: <Widget>[
for (int i = 0; i < 300; i++)
Transform(
transform: Matrix4.rotationZ(pi * 2.0 * i / 300.0),
alignment: Alignment.center,
child: Text('child',
style: TextStyle(
color: HSVColor.fromAHSV(1.0, i * 360.0 / 300.0, 1.0, 1.0).toColor(),
fontSize: 36,
),
),
),
Text('child',
style: TextStyle(
color: Colors.white,
fontSize: 36,
),
),
],
);
} else {
return Text('child',
style: TextStyle(
color: Colors.blue,
fontSize: 36,
),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: AnimatedBuilder(
animation: _controller,
builder: (context, child) {
Matrix4 matrix = Matrix4.identity();
if (_useFilter) matrix.translate(_childCenter.dx, _childCenter.dy);
matrix.rotateZ(_controller.value * 2.0 * pi);
if (_useFilter) matrix.translate(- _childCenter.dx, - _childCenter.dy);
if (_useFilter) {
return ImageFiltered(
imageFilter: ImageFilter.matrix(matrix.storage),
child: child,
);
} else {
return Transform(
transform: matrix,
alignment: Alignment.center,
child: child,
);
}
},
child: RepaintBoundary(
child: Container(
key: _childKey,
color: Colors.yellow,
width: 300,
height: 300,
child: Center(
child: makeChild(300, 300),
),
),
),
),
),
bottomNavigationBar: BottomAppBar(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Use ImageFiltered:'),
Checkbox(
value: _useFilter,
onChanged: (b) => setState(() => _useFilter = b),
),
Text('Complex child:'),
Checkbox(
value: _complexChild,
onChanged: (b) => setState(() => _complexChild = b),
),
],
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment