龙空技术网

flutter 绘制流水(水波上升)动态效果

科技Future 54

前言:

当前同学们对“js水波效果”大约比较讲究,同学们都需要学习一些“js水波效果”的相关知识。那么小编在网上收集了一些有关“js水波效果””的相关文章,希望各位老铁们能喜欢,各位老铁们一起来学习一下吧!

欢迎去浏览原文:

效果

你可以先简单理解下贝塞尔曲线的原理:

推荐这个关于贝塞尔的教程:

代码:

1.创建绘制波浪边界的代码

创建一个基础的绘制类,可接收动画的x和y值:

import 'package:flutter/material.dart';abstract class BasePainter extends CustomPainter{ Animation<double> _xAnimation; Animation<double> _yAnimation; set XAnimation(Animation<double> value) { _xAnimation = value; } set YAnimation(Animation<double> value) { _yAnimation = value; } Animation<double> get YAnimation => _yAnimation; Animation<double> get XAnimation => _xAnimation;}

实现

欢迎去浏览原文:

import 'dart:math';import 'package:flutter_wave/painter_base.dart';import 'package:flutter/material.dart';class WavePainter extends BasePainter { int waveCount; int crestCount; double waveHeight; List<Color> waveColors; double circleWidth; Color circleColor; Color circleBackgroundColor; bool showProgressText; TextStyle textStyle; WavePainter( {this.waveCount = 1, this.crestCount = 2, this.waveHeight, this.waveColors, this.circleColor = Colors.grey, this.circleBackgroundColor = Colors.white, this.circleWidth = 5.0, this.showProgressText = true, this.textStyle = const TextStyle( fontSize: 60.0, color: Colors.blue, fontWeight: FontWeight.bold, shadows: [ Shadow(color: Colors.grey, offset: Offset(5.0, 5.0), blurRadius: 5.0) ], )}); @override void paint(Canvas canvas, Size size) { double width = size.width; double height = size.height; if (waveHeight == null) { waveHeight = height / 10; height = height + waveHeight; } if (waveColors == null) { waveColors = [ Color.fromARGB( 100, Colors.blue.red, Colors.blue.green, Colors.blue.blue) ]; } Offset center = new Offset(width / 2, height / 2); double xMove = width * XAnimation.value; double yAnimValue = 0.0; if (YAnimation != null) { yAnimValue = YAnimation.value; } double yMove = height * (1.0 - yAnimValue); Offset waveCenter = new Offset(xMove, yMove); var paintCircle = new Paint() ..color = Colors.grey ..style = PaintingStyle.fill ..strokeWidth = circleWidth ..maskFilter = MaskFilter.blur(BlurStyle.inner, 5.0);// canvas.drawCircle(center, min(width, height) / 2, paintCircle); List<Path> wavePaths = []; for (int index = 0; index < waveCount; index++) { double direction = pow(-1.0, index); Path path = new Path() ..moveTo(waveCenter.dx - width, waveCenter.dy) ..lineTo(waveCenter.dx - width, center.dy + height / 2) ..lineTo(waveCenter.dx + width, center.dy + height / 2) ..lineTo(waveCenter.dx + width, waveCenter.dy); for (int i = 0; i < 2; i++) { for (int j = 0; j < crestCount; j++) { double a = pow(-1.0, j); path ..quadraticBezierTo( waveCenter.dx + width * (1 - i - (1 + 2 * j) / (2 * crestCount)), waveCenter.dy + waveHeight * a * direction, waveCenter.dx + width * (1 - i - (2 + 2 * j) / (2 * crestCount)), waveCenter.dy); } } path..close(); wavePaths.add(path); } var paint = new Paint() ..color = circleBackgroundColor ..style = PaintingStyle.fill ..maskFilter = MaskFilter.blur(BlurStyle.inner, 5.0); canvas.saveLayer( Rect.fromCircle(center: center, radius: min(width, height) / 2), paint);// canvas.drawCircle(center, min(width, height) / 2, paint); paint// ..blendMode = BlendMode.srcATop ..style = PaintingStyle.fill ..strokeWidth = 2.0 ..maskFilter = MaskFilter.blur(BlurStyle.inner, 10.0); for (int i = 0; i < wavePaths.length; i++) { if (waveColors.length >= wavePaths.length) { paint.color = waveColors[i]; } else { paint.color = waveColors[0]; } canvas.drawPath(wavePaths[i], paint); }// paint.blendMode = BlendMode.srcATop; if (showProgressText) { TextPainter tp = TextPainter( text: TextSpan( text: '${(yAnimValue * 100.0).toStringAsFixed(0)}%', style: textStyle), textDirection: TextDirection.rtl) ..layout(); tp.paint( canvas, Offset(center.dx - tp.width / 2, center.dy - tp.height / 2)); } canvas.restore(); } @override bool shouldRepaint(CustomPainter oldDelegate) { return oldDelegate != this; }}

欢迎去浏览原文:

2.创建工厂方法,用于创建波浪图形

import 'package:flutter/material.dart';

import 'package:flutter_wave/painter_base.dart';

import 'package:flutter_wave/painter/painter_wave.dart';

abstract class BasePainterFactory {

BasePainter getPainter();

}

class WavePainterFactory extends BasePainterFactory {

BasePainter getPainter() {

return WavePainter(

waveCount: 1,

waveColors: [

Colors.lightBlueAccent[200],

],

textStyle:

TextStyle(

fontSize: 60.0,

foreground: Paint()

..color = Colors.lightBlue

..style = PaintingStyle.fill

..strokeWidth = 2.0

..blendMode = BlendMode.difference

..colorFilter = ColorFilter.mode(Colors.white, BlendMode.exclusion)

..maskFilter = MaskFilter.blur(BlurStyle.solid, 1.0),

fontWeight: FontWeight.bold,

),

);

}

}

给波浪添加动画

推荐你先学一下动画基础知识:

原理解释:

xAnimation和yAnimation不断的从0到1变化,然后上面绘制波浪的地方根据这些值不断的进行绘制,形成动画。

import 'package:flutter_wave/painter_factory.dart';import 'package:flutter/material.dart';class ProgressManager extends StatefulWidget { @override _ProgressManagerState createState() => new _ProgressManagerState().._factory = WavePainterFactory();}class _ProgressManagerState extends State<ProgressManager> with TickerProviderStateMixin { AnimationController xController; AnimationController yController; Animation<double> xAnimation; Animation<double> yAnimation; List<double> _progressList = []; double curProgress = 0; BasePainterFactory _factory; set painter(BasePainterFactory factory) { _factory = factory; } setProgress(double progress) { _progressList.add(progress); onProgressChange(); } onProgressChange() { if (_progressList.length > 0) { if (yController != null && yController.isAnimating) { return; } double nextProgress = _progressList[0]; _progressList.removeAt(0); final double begin = curProgress; yController = new AnimationController( vsync: this, duration: Duration(milliseconds: 1000)); yAnimation = new Tween(begin: begin, end: nextProgress).animate(yController); yAnimation.addListener(_onProgressChange); yAnimation.addStatusListener(_onProgressStatusChange); yController.forward(); } } @override void initState() { super.initState(); xController = new AnimationController( vsync: this, duration: Duration(milliseconds: 4000)); xAnimation = new Tween(begin: 0.0, end: 1.0).animate(xController); xAnimation.addListener(_change); yController = new AnimationController( vsync: this, duration: Duration(milliseconds: 5000)); yAnimation = new Tween(begin: 0.0, end: 1.0).animate(yController); yAnimation.addListener(_onProgressChange); yAnimation.addStatusListener(_onProgressStatusChange); doDelay(xController, 0); Future.delayed(Duration(milliseconds: 3000), () { setProgress(0.66); }); } @override Widget build(BuildContext context) { return Center( child: Container( width: MediaQuery.of(context).size.width, height: 400.0, child: new CustomPaint( painter: _factory.getPainter() ..XAnimation = xAnimation ..YAnimation = yAnimation, size: new Size(MediaQuery.of(context).size.width, 400.0), ), ), ); } void _change() { setState(() {}); } void _onProgressChange() { setState(() { curProgress = yAnimation.value; }); } void _onProgressStatusChange(status) { if (status == AnimationStatus.completed) { onProgressChange(); } } void doDelay(AnimationController controller, int delay) async { Future.delayed(Duration(milliseconds: delay), () { controller..repeat(); }); } @override void dispose() { xController.dispose(); yController.dispose(); xAnimation.removeListener(_change); yAnimation.removeListener(_onProgressChange); yAnimation.removeStatusListener(_onProgressStatusChange); super.dispose(); }}

使用的地方

body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ ProgressManager(), ], ), ),

欢迎去浏览原文:

下载demo地址

标签: #js水波效果