自定義一個(gè)水波進(jìn)度球

自定義一個(gè)水波進(jìn)度球

最終樣式:


圖片發(fā)自簡(jiǎn)書(shū)App

1.自定義View

在Flutter中自定義View需要繼承CustomPainter控件,需要實(shí)現(xiàn)兩個(gè)方法:
void paint(Canvas canvas, Size size)以及bool shouldRepaint(CustomPainter oldDelegate),重要的方法當(dāng)然就是前者,如何在畫(huà)布上畫(huà)出我們想要的圖案;

至于CusetomPainter控件的使用如下:

Container(
  width: 200.0,
  height: 200.0,
  child: new WavePainter(),
),

2.繪制波浪

繪制波浪的原理其實(shí)很簡(jiǎn)單,重點(diǎn)就是使用path貝塞爾曲線的使用,繪制如下:

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);
  ..quadraticBezierTo(
            waveCenter.dx +
                width*3/4,
            waveCenter.dy + waveHeight,
            waveCenter.dx +
                width * 1/2,
            waveCenter.dy)
  ..quadraticBezierTo(
            waveCenter.dx +
                width*1/4,
            waveCenter.dy - waveHeight,
            waveCenter.dx,
            waveCenter.dy)
  ..quadraticBezierTo(
            waveCenter.dx -
                width*1/4,
            waveCenter.dy + waveHeight,
            waveCenter.dx -
                width * 1/2,
            waveCenter.dy)  
  ..quadraticBezierTo(
            waveCenter.dx -
                width*3/4,
            waveCenter.dy - waveHeight,
            waveCenter.dx -
                width,
            waveCenter.dy);

然后使用canvas進(jìn)行繪制:

canvas.drawPath(path, paint);
圖片發(fā)自簡(jiǎn)書(shū)App

這里其實(shí)繪制了兩段重復(fù)的波浪,然后在后面使用一個(gè)動(dòng)畫(huà)讓它向右平移width的寬度,然后重復(fù)動(dòng)畫(huà),這樣在給定的視野框中就像是波浪一直向右滾動(dòng)。
這里我們需要在波浪外套上一層圓形,然后讓圓形內(nèi)的波浪顯示,而圓形外的波浪隱藏,就使用到了paintblendMode屬性,這個(gè)屬性的值有很多種,兄弟們自行了解,這里使用到的如下:

paint..blendMode = BlendMode.srcATop

具體代碼如下:

var paint = new Paint()
  ..color = circleBackgroundColor
  ..style = PaintingStyle.fill;

canvas.drawCircle(center, min(width, height) / 2, paint);
paint
  ..blendMode = BlendMode.srcATop
  ..style = PaintingStyle.fill
  ..strokeWidth = 2.0;

canvas.drawPath(paint, paint);
圖片發(fā)自簡(jiǎn)書(shū)App

然后我們可以在中加入一個(gè)顯示進(jìn)度的文字,使用TextPainter進(jìn)行繪制:

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));

3.加入進(jìn)度功能

加入進(jìn)度的功能也就是為了能讓波浪能夠由下至上填滿,和波浪平移一樣,這里給一個(gè)動(dòng)畫(huà):

yController = new AnimationController(
    vsync: this, duration: Duration(milliseconds: 500));
yAnimation = new Tween(begin: 0.0, end: 1.0).animate(yController);
yAnimation.addListener(_onProgressChange);
yAnimation.addStatusListener(_onProgressStatusChange);

void _onProgressChange() {
  setState(() {
    curProgress = yAnimation.value;
  });
}
void _onProgressStatusChange(status) {
  if (status == AnimationStatus.completed) {
    onProgressChange();
  }
}

讓后讓波浪的高度由這個(gè)動(dòng)畫(huà)數(shù)值來(lái)控制,這里刷新的遠(yuǎn)離就是當(dāng)動(dòng)畫(huà)數(shù)值變化的時(shí)候,調(diào)用StatefulWidgetsetState({})進(jìn)行界面刷新。

4.波浪特效

對(duì)于滾動(dòng)的波浪我們可以加入以下特效:

paint..maskFilter = MaskFilter.blur(BlurStyle.inner, 10.0)

通過(guò)maskFilter屬性我們可以設(shè)置繪制區(qū)域高斯模糊,這里設(shè)置強(qiáng)度為10.0,方向?yàn)橄騼?nèi)

對(duì)于顯示的文字我們也加入特效:

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,
),

blendMode表示繪制有重疊的區(qū)域顏色區(qū)別處理,然后colorFilter表示對(duì)繪制的顏色與白色進(jìn)行混色,就可以做出,波浪經(jīng)過(guò)的時(shí)候文字水中與不在水中的部分有不同的顏色。

全部代碼:點(diǎn)擊這里,記得給個(gè)Star喲~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容