Skip to content

Instantly share code, notes, and snippets.

@liyuqian
Last active December 26, 2018 21:07
Show Gist options
  • Save liyuqian/5b9eed3d9d80dde0c93da84d4c45aa34 to your computer and use it in GitHub Desktop.
Save liyuqian/5b9eed3d9d80dde0c93da84d4c45aa34 to your computer and use it in GitHub Desktop.
import 'dart:ui' as ui;
import 'dart:typed_data';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
final double width = 400;
final double height = 400;
final bool dropShadow = true;
final bool useSnapshot = true; // CHANGE ME AND COLD RESTART TO SEE THE DIFFERENCE
final String photo = 'https://github.com/flutter/website/blob/master/src/_includes/code/layout/lakes/images/lake.jpg?raw=true';
GlobalKey _snapshotWidgetKey = new GlobalKey();
Uint8List _snapshotByteData;
Uint8List _photoBytes;
bool _gpuImageCached = false;
Animation<double> animation;
AnimationController controller;
void _fetchImage() async {
http.Response response = await http.get(photo);
setState((){
_photoBytes = response.bodyBytes;
});
}
void _trySnapshot() async {
do {
await Future.delayed(Duration(milliseconds: 20));
if (_photoBytes == null || _snapshotWidgetKey.currentContext == null) {
continue;
}
await Future.delayed(Duration(milliseconds: 200)); // wait for image to be shown
RenderRepaintBoundary boundary = _snapshotWidgetKey.currentContext.findRenderObject();
if (boundary == null) {
continue;
}
ui.Image image = await boundary.toImage();
_snapshotByteData = (await image.toByteData(format: ui.ImageByteFormat.png)).buffer.asUint8List();
} while (_snapshotByteData == null);
await Future.delayed(Duration(seconds: 1));
_gpuImageCached = true;
}
Widget createSnapshotWidget() {
if (useSnapshot && _snapshotByteData != null && _gpuImageCached) {
return Image.memory(_snapshotByteData);
}
Widget cacheStack = Stack(
children: <Widget>[
_snapshotByteData == null ? Container() : Image.memory(_snapshotByteData),
Container(color: Colors.white),
_photoBytes == null ? Container() : Image.memory(_photoBytes),
],
);
return RepaintBoundary(
key: _snapshotWidgetKey,
child: Container(
padding: EdgeInsets.all(10), // padding for box shadow
child: Container(
width: width,
height: height,
decoration: BoxDecoration(
boxShadow: dropShadow
? [
BoxShadow(
color: Colors.black.withOpacity(0.4),
blurRadius: 5.0,
offset: Offset(0.0, 1.0))
]
: [],
borderRadius: BorderRadius.all(Radius.circular(10.0)),
color: Colors.white,
),
child: ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: cacheStack,
),
),
)
);
}
@override
void initState() {
super.initState();
_fetchImage();
if (useSnapshot) {
_trySnapshot();
}
controller = AnimationController(vsync: this);
animation = Tween(begin: 0.0, end: 360.0).animate(controller)
..addListener((){
setState((){});
});
controller.repeat(period: Duration(seconds: 2));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Rotation Demo'),
),
body: Center(
child: MemberCard(
snapshotWidget: createSnapshotWidget(),
rotation: animation.value,
),
),
);
}
}
class MemberCard extends StatelessWidget {
final double rotation;
final Offset offset;
final double scale;
final Widget snapshotWidget;
MemberCard({
@required this.snapshotWidget,
this.rotation = 0.0,
this.offset = const Offset(0.0, 0.0),
this.scale = 1.0,
});
@override
Widget build(BuildContext context) {
double angle = rotation * (3.1415926 / 180.0);
var matrix = Matrix4.translationValues(offset.dx, offset.dy, 0.0);
if (scale != 1.0) {
matrix..scale(scale);
}
if (rotation != 0.0) {
matrix.rotateZ(angle);
}
return Transform(
alignment: Alignment.center,
transform: matrix,
child: Stack(
children: <Widget>[
snapshotWidget
],
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment