You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
274 lines
8.0 KiB
274 lines
8.0 KiB
// import 'dart:math' as Math; |
|
// |
|
// import 'dart:typed_data'; |
|
// |
|
// import 'package:flutter/material.dart'; |
|
// import 'package:flutter/rendering.dart'; |
|
// import 'package:huixiang/utils/pixel_utils.dart'; |
|
// |
|
// class ExplosionWidget extends StatefulWidget { |
|
// final Widget child; |
|
// final Rect bound; |
|
// final String tag; |
|
// |
|
// const ExplosionWidget({Key key, this.child, this.bound, this.tag}) |
|
// : super(key: key); |
|
// |
|
// @override |
|
// State<StatefulWidget> createState() { |
|
// return _ExplosionWidget(); |
|
// } |
|
// } |
|
// |
|
// class _ExplosionWidget extends State<ExplosionWidget> |
|
// with SingleTickerProviderStateMixin { |
|
// ByteData _byteData; |
|
// Size _imageSize; |
|
// |
|
// AnimationController _animationController; |
|
// |
|
// GlobalObjectKey globalKey; |
|
// |
|
// @override |
|
// void initState() { |
|
// super.initState(); |
|
// globalKey = GlobalObjectKey(widget.tag); |
|
// _animationController = |
|
// AnimationController(duration: Duration(milliseconds: 600), vsync: this); |
|
// } |
|
// |
|
// @override |
|
// void dispose() { |
|
// super.dispose(); |
|
// _animationController.dispose(); |
|
// } |
|
// |
|
// void onTap() { |
|
// if (_byteData == null || _imageSize == null) { |
|
// RenderRepaintBoundary boundary = |
|
// globalKey.currentContext.findRenderObject(); |
|
// boundary.toImage().then((image) { |
|
// _imageSize = Size(image.width.toDouble(), image.height.toDouble()); |
|
// image.toByteData().then((byteData) { |
|
// _byteData = byteData; |
|
// _animationController.value = 0; |
|
// _animationController.forward(); |
|
// setState(() {}); |
|
// }); |
|
// }); |
|
// } else { |
|
// _animationController.value = 0; |
|
// _animationController.forward(); |
|
// setState(() {}); |
|
// } |
|
// } |
|
// |
|
// @override |
|
// void didUpdateWidget(ExplosionWidget oldWidget) { |
|
// super.didUpdateWidget(oldWidget); |
|
// if (widget.tag != oldWidget.tag) { |
|
// _byteData = null; |
|
// _imageSize = null; |
|
// globalKey = GlobalObjectKey(widget.tag); |
|
// } |
|
// } |
|
// |
|
// @override |
|
// Widget build(BuildContext context) { |
|
// return Container( |
|
// alignment: Alignment.center, |
|
// child: GestureDetector( |
|
// onTap: onTap, |
|
// child: AnimatedBuilder( |
|
// animation: _animationController, |
|
// builder: (context, child) { |
|
// return ExplosionRenderObjectWidget( |
|
// key: globalKey, |
|
// child: widget.child, |
|
// byteData: _byteData, |
|
// imageSize: _imageSize, |
|
// progress: _animationController.value, |
|
// ); |
|
// }, |
|
// ), |
|
// ), |
|
// ); |
|
// } |
|
// } |
|
// |
|
// class ExplosionRenderObjectWidget extends RepaintBoundary { |
|
// final ByteData byteData; |
|
// final Size imageSize; |
|
// final double progress; |
|
// final Rect bound; |
|
// |
|
// const ExplosionRenderObjectWidget( |
|
// {Key key, |
|
// Widget child, |
|
// this.byteData, |
|
// this.imageSize, |
|
// this.progress, |
|
// this.bound}) |
|
// : super(key: key, child: child); |
|
// |
|
// @override |
|
// _ExplosionRenderObject createRenderObject(BuildContext context) => |
|
// _ExplosionRenderObject( |
|
// byteData: byteData, imageSize: imageSize, bound: bound); |
|
// |
|
// @override |
|
// void updateRenderObject( |
|
// BuildContext context, _ExplosionRenderObject renderObject) { |
|
// renderObject.update(byteData, imageSize, progress); |
|
// } |
|
// } |
|
// |
|
// class _ExplosionRenderObject extends RenderRepaintBoundary { |
|
// ByteData byteData; |
|
// Size imageSize; |
|
// double progress; |
|
// List<_Particle> particles; |
|
// Rect bound; |
|
// |
|
// _ExplosionRenderObject( |
|
// {this.byteData, this.imageSize, this.bound, RenderBox child}) |
|
// : super(child: child); |
|
// |
|
// void update(ByteData byteData, Size imageSize, double progress) { |
|
// this.byteData = byteData; |
|
// this.imageSize = imageSize; |
|
// this.progress = progress; |
|
// markNeedsPaint(); |
|
// } |
|
// |
|
// @override |
|
// void paint(PaintingContext context, Offset offset) { |
|
// if (byteData != null && |
|
// imageSize != null && |
|
// progress != 0 && |
|
// progress != 1) { |
|
// if (particles == null) { |
|
// if (bound == null) { |
|
// bound = Rect.fromLTWH(0, 0, size.width, size.height * 2); |
|
// } |
|
// particles = initParticleList(bound, byteData, imageSize); |
|
// } |
|
// draw(context.canvas, particles, progress); |
|
// } else { |
|
// if (child != null) { |
|
// context.paintChild(child, offset); |
|
// } |
|
// } |
|
// } |
|
// } |
|
// |
|
// const double END_VALUE = 1.4; |
|
// const double V = 2; |
|
// const double X = 5; |
|
// const double Y = 20; |
|
// const double W = 1; |
|
// |
|
// List<_Particle> initParticleList( |
|
// Rect bound, ByteData byteData, Size imageSize) { |
|
// int partLen = 15; |
|
// List<_Particle> particles = List(partLen * partLen); |
|
// Math.Random random = new Math.Random(DateTime.now().millisecondsSinceEpoch); |
|
// int w = imageSize.width ~/ (partLen + 2); |
|
// int h = imageSize.height ~/ (partLen + 2); |
|
// for (int i = 0; i < partLen; i++) { |
|
// for (int j = 0; j < partLen; j++) { |
|
// particles[(i * partLen) + j] = generateParticle( |
|
// getColorByPixel(byteData, imageSize, |
|
// Offset((j + 1) * w.toDouble(), (i + 1) * h.toDouble())), |
|
// random, |
|
// bound); |
|
// } |
|
// } |
|
// return particles; |
|
// } |
|
// |
|
// bool draw(Canvas canvas, List<_Particle> particles, double progress) { |
|
// Paint paint = Paint(); |
|
// for (int i = 0; i < particles.length; i++) { |
|
// _Particle particle = particles[i]; |
|
// particle.advance(progress); |
|
// if (particle.alpha > 0) { |
|
// paint.color = particle.color |
|
// .withAlpha((particle.color.alpha * particle.alpha).toInt()); |
|
// canvas.drawCircle( |
|
// Offset(particle.cx, particle.cy), particle.radius, paint); |
|
// } |
|
// } |
|
// return true; |
|
// } |
|
// |
|
// _Particle generateParticle(Color color, Math.Random random, Rect bound) { |
|
// _Particle particle = _Particle(); |
|
// particle.color = color; |
|
// particle.radius = V; |
|
// if (random.nextDouble() < 0.2) { |
|
// particle.baseRadius = V + ((X - V) * random.nextDouble()); |
|
// } else { |
|
// particle.baseRadius = W + ((V - W) * random.nextDouble()); |
|
// } |
|
// double nextDouble = random.nextDouble(); |
|
// particle.top = bound.height * ((0.18 * random.nextDouble()) + 0.2); |
|
// particle.top = nextDouble < 0.2 |
|
// ? particle.top |
|
// : particle.top + ((particle.top * 0.2) * random.nextDouble()); |
|
// particle.bottom = (bound.height * (random.nextDouble() - 0.5)) * 1.8; |
|
// double f = nextDouble < 0.2 |
|
// ? particle.bottom |
|
// : nextDouble < 0.8 |
|
// ? particle.bottom * 0.6 |
|
// : particle.bottom * 0.3; |
|
// particle.bottom = f; |
|
// particle.mag = 4.0 * particle.top / particle.bottom; |
|
// particle.neg = (-particle.mag) / particle.bottom; |
|
// f = bound.center.dx + (Y * (random.nextDouble() - 0.5)); |
|
// particle.baseCx = f; |
|
// particle.cx = f; |
|
// f = bound.center.dy + (Y * (random.nextDouble() - 0.5)); |
|
// particle.baseCy = f; |
|
// particle.cy = f; |
|
// particle.life = END_VALUE / 10 * random.nextDouble(); |
|
// particle.overflow = 0.4 * random.nextDouble(); |
|
// particle.alpha = 1; |
|
// return particle; |
|
// } |
|
// |
|
// class _Particle { |
|
// double alpha; |
|
// Color color; |
|
// double cx; |
|
// double cy; |
|
// double radius; |
|
// double baseCx; |
|
// double baseCy; |
|
// double baseRadius; |
|
// double top; |
|
// double bottom; |
|
// double mag; |
|
// double neg; |
|
// double life; |
|
// double overflow; |
|
// |
|
// void advance(double factor) { |
|
// double f = 0; |
|
// double normalization = factor / END_VALUE; |
|
// if (normalization < life || normalization > 1 - overflow) { |
|
// alpha = 0; |
|
// return; |
|
// } |
|
// normalization = (normalization - life) / (1 - life - overflow); |
|
// double f2 = normalization * END_VALUE; |
|
// if (normalization >= 0.7) { |
|
// f = (normalization - 0.7) / 0.3; |
|
// } |
|
// alpha = 1 - f; |
|
// f = bottom * f2; |
|
// cx = baseCx + f; |
|
// cy = (baseCy - this.neg * Math.pow(f, 2.0)) - f * mag; |
|
// radius = V + (baseRadius - V) * f2; |
|
// } |
|
// }
|
|
|