// 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 'package:flutter/material.dart'; import 'package:vector_math/vector_math_64.dart'; import 'dart:math'; class RotatedWireCube extends StatefulWidget { const RotatedWireCube({required this.cubeColor, super.key}); final Color cubeColor; @override State createState() => _RotatedWireCubeState(); } class _RotatedWireCubeState extends State with SingleTickerProviderStateMixin { late final AnimationController _animation; @override void initState() { super.initState(); _animation = AnimationController( vsync: this, lowerBound: 0, upperBound: 2 * pi, duration: const Duration(seconds: 15), )..repeat(); } @override void dispose() { _animation.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _animation, builder: (context, child) { return CustomPaint( size: const Size(200, 200), painter: _RotatedWireCubePainter( angle: _animation.value, color: widget.cubeColor, ), ); }, ); } } class _RotatedWireCubePainter extends CustomPainter { static List vertices = [ Vector3(-0.5, -0.5, -0.5), Vector3(0.5, -0.5, -0.5), Vector3(0.5, 0.5, -0.5), Vector3(-0.5, 0.5, -0.5), Vector3(-0.5, -0.5, 0.5), Vector3(0.5, -0.5, 0.5), Vector3(0.5, 0.5, 0.5), Vector3(-0.5, 0.5, 0.5), ]; static const List> edges = [ [0, 1], [1, 2], [2, 3], [3, 0], // Front face [4, 5], [5, 6], [6, 7], [7, 4], // Back face [0, 4], [1, 5], [2, 6], [3, 7], // Connecting front and back ]; final double angle; final Color color; _RotatedWireCubePainter({required this.angle, required this.color}); Offset scaleAndCenter(Vector3 point, double size, Offset center) { final scale = size / 2; return Offset(center.dx + point.x * scale, center.dy - point.y * scale); } @override void paint(Canvas canvas, Size size) { final rotatedVertices = vertices .map((vertex) => Matrix4.rotationX(angle).transformed3(vertex)) .map((vertex) => Matrix4.rotationY(angle).transformed3(vertex)) .map((vertex) => Matrix4.rotationZ(angle).transformed3(vertex)) .toList(); final center = Offset(size.width / 2, size.height / 2); final paint = Paint() ..color = color ..style = PaintingStyle.stroke ..strokeWidth = 2; for (var edge in edges) { final p1 = scaleAndCenter(rotatedVertices[edge[0]], size.width, center); final p2 = scaleAndCenter(rotatedVertices[edge[1]], size.width, center); canvas.drawLine(p1, p2, paint); } } @override bool shouldRepaint(_RotatedWireCubePainter oldDelegate) => true; }