福建省建设继续教育网站,深圳关键词优化报价,软件开发中以下模型哪些不是采用,qq可以上网和尚今天尝试一下绘制波浪的效果#xff0c;虽然 pub 仓库中已经有成熟的插件#xff0c;但和尚还是准备用之前学习的 Canvas 和 Animation 尝试自定义一个 ACEWave#xff1b;1. 绘制曲线绘制波浪首先需要绘制曲线#xff0c;采用 Canvas 绘制贝塞尔曲线#xff1b;常用的… 和尚今天尝试一下绘制波浪的效果虽然 pub 仓库中已经有成熟的插件但和尚还是准备用之前学习的 Canvas 和 Animation 尝试自定义一个 ACEWave1. 绘制曲线 绘制波浪首先需要绘制曲线采用 Canvas 绘制贝塞尔曲线常用的是数学中通常用的 sin(x) / cos(y) 函数即可 其中和尚通过 Canvas 绘制时使用了 path.quadraticBezierTo 来绘制从第一个 Point 到另一个 Point 的贝塞尔曲线class _ACEWavePainter extends CustomPainter { override void paint(Canvas canvas, Size size) { Paint paint Paint() ..color Colors.red..strokeCap StrokeCap.round ..strokeWidth 10..style PaintingStyle.stroke; Path path Path() ..moveTo(0, 500) ..quadraticBezierTo(size.width / 4, 300, size.width / 2, 500) ..quadraticBezierTo(size.width / 4 * 3, 700, size.width, 500); canvas.drawPath(path, paint); } override bool shouldRepaint(CustomPainter oldDelegate) false;}2. 循环动画 和尚使用最常用的平移动画来让曲线动起来其中注意的是当第一次动画结束时通过 controller.repeat() 来实现循环播放动画需要使用 Curves.linear 线性动画否则在循环播放过程中衔接不顺畅使用动画时均需在生命周期结束时 dispose() 销毁动画class _ACEWaveState extends StateACEWave with TickerProviderStateMixin { AnimationController _waveController; Animationdouble _waveAnimation; int _duration 2000; CurvedAnimation _curvedAnimation; override Widget build(BuildContext context) { return Transform.translate( offset: Offset(MediaQuery.of(context).size.width * _curvedAnimation.value, 0.0), child: Container(width: MediaQuery.of(context).size.width, child: CustomPaint(painter: _ACEWavePainter()))); } _initAnimations() { _waveController AnimationController(duration: Duration(milliseconds: _duration), vsync: this); _curvedAnimation CurvedAnimation(parent: _waveController, curve: Curves.linear); _waveAnimation Tween(begin: 0.0, end: 1.0).animate(_waveController); _waveAnimation.addListener(() setState(() {})); _waveController.forward(); _waveAnimation.addStatusListener((status) { switch (status) { case AnimationStatus.completed: _waveController.repeat(); break; case AnimationStatus.dismissed: _waveController.forward(); break; default: break; } }); } _disposeAnimations() { _waveController.dispose(); } override void initState() { super.initState(); _initAnimations(); } override void dispose() { _disposeAnimations(); super.dispose(); }}3. 增加波浪周期 在执行循环动画之后发现动画过程中会有一半是空白的此时我们增加波浪的周期即可多绘制一个屏幕的波浪即可和尚建议前后多绘制两个屏幕的曲线在循环过程中更流畅Path path Path() ..moveTo(0 - size.width, 500) ..quadraticBezierTo(size.width / 4 - size.width, 300, size.width / 2 - size.width, 500) ..quadraticBezierTo(size.width / 4 * 3 - size.width, 700, size.width - size.width, 500) ..quadraticBezierTo(size.width / 4, 300, size.width / 2, 500) ..quadraticBezierTo(size.width / 4 * 3, 700, size.width, 500);canvas.drawPath(path, paint);4. 调整波浪起始位置 和尚尝试的曲线是 sin(x) 方式的起始位置都是 (0.0, 0.0)然而多条波浪时不会都从起点开始于是和尚提供了一个初始位置来错开各波浪展示位置Path path Path() ..moveTo(0 - size.width - startOffset, 500) ..quadraticBezierTo(size.width / 4 - size.width - startOffset, 500 - waveHeight, size.width / 2 - size.width - startOffset, 500) ..quadraticBezierTo(size.width / 4 * 3 - size.width - startOffset, 500 waveHeight, size.width - size.width - startOffset, 500) ..quadraticBezierTo(size.width / 4 - startOffset, 500 - waveHeight, size.width / 2 - startOffset, 500) ..quadraticBezierTo(size.width / 4 * 3 - startOffset, 500 waveHeight, size.width - startOffset, 500) ..quadraticBezierTo(size.width / 4 size.width - startOffset, 500 - waveHeight, size.width / 2 size.width - startOffset, 500) ..quadraticBezierTo(size.width / 4 * 3 size.width - startOffset, 500 waveHeight, size.width size.width - startOffset, 500);5. 调整波浪宽度和峰值 和尚调整完波浪起始位置之后对于波浪的宽度和峰值也要进行调整保证每条波浪效果略有不同 和尚预先绘制了前中后三个屏幕曲线在测试过程中若屏幕并非是曲线周期倍数时衔接过程中会有空余如图 于是和尚计算波浪完整周期倍数与屏幕宽的差值作为移动点 moveTo 的附加宽度即可for (int i 0; i path..moveTo(waveWidth * i - size.width - startOffset, 500.0) ..quadraticBezierTo( _quaterWidth waveWidth * i - size.width - startOffset, 500 - waveHeight, _quaterWidth * 2 waveWidth * i - size.width - startOffset, 500.0) ..moveTo( _quaterWidth * 2 waveWidth * i - size.width - startOffset, 500.0) ..quadraticBezierTo( _quaterWidth * 3 waveWidth * i - size.width - startOffset, 500 waveHeight, _quaterWidth * 4 waveWidth * i - size.width - startOffset, 500.0) ..moveTo(waveWidth * i startOffset (plusWidth), 500.0) ..quadraticBezierTo( _quaterWidth waveWidth * i startOffset plusWidth, 500 - waveHeight, _quaterWidth * 2 waveWidth * i startOffset plusWidth, 500.0) ..moveTo( _quaterWidth * 2 waveWidth * i startOffset plusWidth, 500.0) ..quadraticBezierTo( _quaterWidth * 3 waveWidth * i startOffset plusWidth, 500 waveHeight, _quaterWidth * 4 waveWidth * i startOffset plusWidth, 500.0) ..moveTo(waveWidth * i - size.width startOffset, 500.0) ..quadraticBezierTo( _quaterWidth waveWidth * i - size.width startOffset, 500 - waveHeight, _quaterWidth * 2 waveWidth * i - size.width startOffset, 500.0) ..moveTo( _quaterWidth * 2 waveWidth * i - size.width startOffset, 500.0) ..quadraticBezierTo( _quaterWidth * 3 waveWidth * i - size.width startOffset, 500 waveHeight, _quaterWidth * 4 waveWidth * i - size.width startOffset, 500.0);} 至此一个基本的波浪模型基本完成但还有很多优化的方面和尚在下篇中进一步绘制波浪效果如有错误请多多指导来源阿策小和尚