目錄
一柱查、效果展示
二、CustomPaint
三云石、CustomPainter
四唉工、水波效果
五、文字效果
六汹忠、動起來
一淋硝、效果展示
二、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;
}
});
});
}