| // Copyright 2014 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. | |
| import 'dart:ui' as ui; | |
| import 'package:flutter/material.dart'; | |
| Future<ui.Image> loadImage(String asset) async { | |
| final ui.ImmutableBuffer buffer = await ui.ImmutableBuffer.fromAsset(asset); | |
| final ui.Codec codec = await PaintingBinding.instance.instantiateImageCodecWithSize(buffer); | |
| final ui.FrameInfo frameInfo = await codec.getNextFrame(); | |
| return frameInfo.image; | |
| } | |
| class DrawVerticesPage extends StatefulWidget { | |
| const DrawVerticesPage({super.key}); | |
| @override | |
| State<DrawVerticesPage> createState() => _DrawVerticesPageState(); | |
| } | |
| class _DrawVerticesPageState extends State<DrawVerticesPage> with SingleTickerProviderStateMixin { | |
| late final AnimationController controller; | |
| double tick = 0.0; | |
| ui.Image? image; | |
| @override | |
| void initState() { | |
| super.initState(); | |
| loadImage('packages/flutter_gallery_assets/food/butternut_squash_soup.png').then((ui.Image pending) { | |
| setState(() { | |
| image = pending; | |
| }); | |
| }); | |
| controller = AnimationController(vsync: this, duration: const Duration(hours: 1)); | |
| controller.addListener(() { | |
| setState(() { | |
| tick += 1; | |
| }); | |
| }); | |
| controller.forward(from: 0); | |
| } | |
| @override | |
| void dispose() { | |
| controller.dispose(); | |
| super.dispose(); | |
| } | |
| @override | |
| Widget build(BuildContext context) { | |
| if (image == null) { | |
| return const Placeholder(); | |
| } | |
| return CustomPaint( | |
| size: const Size(500, 500), | |
| painter: VerticesPainter(tick, image!), | |
| child: Container(), | |
| ); | |
| } | |
| } | |
| class VerticesPainter extends CustomPainter { | |
| VerticesPainter(this.tick, this.image); | |
| final double tick; | |
| final ui.Image image; | |
| @override | |
| void paint(Canvas canvas, Size size) { | |
| canvas.translate(0, tick); | |
| final ui.Vertices vertices = ui.Vertices( | |
| VertexMode.triangles, | |
| const <Offset>[ | |
| Offset.zero, | |
| Offset(0, 250), | |
| Offset(250, 0), | |
| Offset(0, 250), | |
| Offset(250, 0), | |
| Offset(250, 250) | |
| ], | |
| textureCoordinates: <Offset>[ | |
| Offset.zero, | |
| Offset(0, image.height.toDouble()), | |
| Offset(image.width.toDouble(), 0), | |
| Offset(0, image.height.toDouble()), | |
| Offset(image.width.toDouble(), 0), | |
| Offset(image.width.toDouble(), image.height.toDouble()) | |
| ], | |
| colors: <Color>[ | |
| Colors.red, | |
| Colors.blue, | |
| Colors.green, | |
| Colors.red, | |
| Colors.blue, | |
| Colors.green, | |
| ] | |
| ); | |
| canvas.drawVertices(vertices, BlendMode.plus, Paint()..shader = ImageShader(image, TileMode.clamp, TileMode.clamp, Matrix4.identity().storage)); | |
| canvas.translate(250, 0); | |
| canvas.drawVertices(vertices, BlendMode.plus, Paint()..shader = ImageShader(image, TileMode.clamp, TileMode.clamp, Matrix4.identity().storage)); | |
| canvas.translate(0, 250); | |
| canvas.drawVertices(vertices, BlendMode.plus, Paint()..shader = ImageShader(image, TileMode.clamp, TileMode.clamp, Matrix4.identity().storage)); | |
| canvas.translate(-250, 0); | |
| canvas.drawVertices(vertices, BlendMode.plus, Paint()..shader = ImageShader(image, TileMode.clamp, TileMode.clamp, Matrix4.identity().storage)); | |
| } | |
| @override | |
| bool shouldRepaint(covariant CustomPainter oldDelegate) { | |
| return true; | |
| } | |
| } |