九、Flutter水波动画

作者: 星星编程 | 来源:发表于2019-07-31 06:48 被阅读24次

    目录
    一、效果展示
    二、CustomPaint
    三、CustomPainter
    四、水波效果
    五、文字效果
    六、动起来

    一、效果展示

    Flutter水波动画.png

    二、CustomPaint

    WaterWave继承CustomPainter用画笔画出来的水波动画效果需要CustomPaint呈现出来。
    CustomPaint有两个参数painter和size,painter是一个继承了CustomPainter的对象,主要实现了绘画控件的功能。size指定了控件的大小,如果CustomPaint的child不为空,size的值就是child控件的大小,指定size的值则无效;如果child为空,所指定的size的值,就是画布的大小。

    CustomPaint(
                    painter: WaterWave(this.variable, 0.79, this.offsetX),
                    size: Size(160, 160),
                  )
    

    三、CustomPainter

    WaterWave继承了CustomPainter,实现了其中两个重要方法:paint和shouldRepaint。paint当自定义控件需要重画时被调用。shouldRepaint则决定当条件变化时是否需要重画。

    class WaterWave extends CustomPainter {
      @override
      void paint(Canvas canvas, Size size) {
      }
    
      @override
      bool shouldRepaint(ClockPainter oldDelegate) {
        return true;
      }
    }
    

    四、水波效果

    绘出水波效果有几个重要的参数:波纹振幅:double waveAmplitude;
    波纹周期:double waveCycle;波纹上升速度:double waveGrowth;
    波浪x位移:double offsetX;当前波浪上市高度Y(高度从大到小 坐标系向下增长):double currentWavePointY; 模拟波纹:double variable;这几个参数在sin函数和cos函数地计算下模拟出水波的形状,然后画出来。

    void firstWave() {
        Path path = new Path();
        double y = this.currentWavePointY;
        path.moveTo(0, y);
        for (double x = 0.0; x <= this.waterWaveWidth; x++) {
          y = this.waveAmplitude * sin(this.waveCycle * x + this.offsetX) +
              this.currentWavePointY;
          path.lineTo(x, y);
        }
        path.lineTo(this.waterWaveWidth, this.size.height);
        path.lineTo(0, this.size.height);
        path.close();
        var paint = new Paint()
          ..color = Color.fromRGBO(223, 83, 64, 1)
          ..style = PaintingStyle.fill
          ..maskFilter = MaskFilter.blur(BlurStyle.inner, 5.0);
        this.canvas.drawPath(path, paint);
      }
    
    
    void secondWave() {
        Path path = new Path();
        double y = this.currentWavePointY;
        path.moveTo(0, y);
        for (double x = 0.0; x <= this.waterWaveWidth; x++) {
          y = this.waveAmplitude * cos(this.waveCycle * x + this.offsetX) +
              this.currentWavePointY;
          path.lineTo(x, y);
        }
        path.lineTo(this.waterWaveWidth, this.size.height);
        path.lineTo(0, this.size.height);
        path.close();
        var paint = new Paint()
          ..color = Color.fromRGBO(236, 90, 66, 1)
          ..style = PaintingStyle.fill
          ..maskFilter = MaskFilter.blur(BlurStyle.inner, 5.0);
        this.canvas.drawPath(path, paint);
    }
    
    

    五、文字效果

    绘画文字的时候需要添加引用,import 'dart:ui' as UI;

     UI.ParagraphBuilder pb = UI.ParagraphBuilder(UI.ParagraphStyle(
          textAlign: TextAlign.center,
          fontWeight: FontWeight.w500,
          fontStyle: FontStyle.normal,
          fontSize: 70.0,
        ));
        pb.pushStyle(UI.TextStyle(color: Colors.white));
        pb.addText('86');
        UI.Paragraph paragraph = pb.build();
        paragraph.layout(UI.ParagraphConstraints(width: 140));
        Offset offset = Offset(10, 30.0);
        this.canvas.drawParagraph(paragraph, offset);
    
    
        UI.ParagraphBuilder pb2 = UI.ParagraphBuilder(UI.ParagraphStyle(
          textAlign: TextAlign.center,
          fontWeight: FontWeight.w500,
          fontStyle: FontStyle.normal,
          fontSize: 18.0,
        ));
        pb2.pushStyle(UI.TextStyle(color: Colors.white));
        pb2.addText('评分');
        UI.Paragraph paragraph2 = pb2.build();
        paragraph2.layout(UI.ParagraphConstraints(width: 100));
        Offset offset2 = Offset(30, 105.0);
        this.canvas.drawParagraph(paragraph2, offset2);
    

    六、动起来

    重新initState方法,添加一个定时器没25毫秒改变一下水波的波纹。
    variable模拟波纹上下浮动的效果,offsetX模拟波浪的位移,从而能够增强波纹震动的效果。

    @override
      void initState() {
        super.initState();
    
        this.variable = widget.variable;
        this.increase = widget.increase;
        this.waveSpeed = 0.4 / pi;
        this.offsetX = 0.0;
    
        this.timer = Timer.periodic(new Duration(milliseconds: 25), (timer) {
          setState(() {
            this.offsetX += this.waveSpeed;
    
            if (this.increase) {
              this.variable += 0.01;
            } else {
              this.variable -= 0.01;
            }
    
            if (this.variable <= 1) {
              this.increase = true;
            }
    
            if (this.variable >= 1.6) {
              this.increase = false;
            }
          });
        });
      }
    
    关注公众号,查看更多内容.jpg

    相关文章

      网友评论

        本文标题:九、Flutter水波动画

        本文链接:https://www.haomeiwen.com/subject/qegkkctx.html