Skip to content

Commit 52b5e2b

Browse files
committed
[opt] 优化雨雪绘制逻辑和提升性能
Signed-off-by: xiaweizi <1012126908@qq.com>
1 parent edfbfd3 commit 52b5e2b

File tree

13 files changed

+121
-48
lines changed

13 files changed

+121
-48
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
### 体验
1212

13-
点击[下载链接](http://xiaweizi.top/SimplicityWeather-1_7.apk)下载
13+
点击[下载链接](http://xiaweizi.top/SimplicityWeather-2_0.apk)下载
1414

1515
或者直接扫描二维码抢先体验
1616

assets/images/rain1.png

-1.46 KB
Loading

images/qrcode.png

-24.4 KB
Loading

images/weather4.gif

2.79 MB
Loading

images/weather5.gif

-3.25 MB
Loading

images/weather6.gif

370 KB
Loading

lib/app/res/analytics_constant.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ class AnalyticsConstant {
66
static const String bottomSheet = "bottom_sheet";
77
static const String aboutClick = "about_click";
88
static const String pageShow = "page_show";
9+
static const String weatherType = "weather_type";
910

1011
}

lib/app/utils/print_utils.dart

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
21
import 'package:flutter/widgets.dart';
32

4-
typedef WeatherPrint = void Function(String message, { int wrapWidth, String tag});
3+
typedef WeatherPrint = void Function(String message,
4+
{int wrapWidth, String tag});
5+
6+
const DEBUG = false;
57

68
WeatherPrint weatherPrint = debugPrintThrottled;
79

8-
void debugPrintThrottled(String message, { int wrapWidth, String tag}) {
9-
debugPrint("flutter-weather: $tag: $message", wrapWidth: wrapWidth);
10-
}
10+
void debugPrintThrottled(String message, {int wrapWidth, String tag}) {
11+
if (DEBUG) {
12+
debugPrint("flutter-weather: $tag: $message", wrapWidth: wrapWidth);
13+
}
14+
}

lib/bloc/weather/weather_bloc.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class WeatherBloc extends Bloc<WeatherEvent, WeatherState> {
5858
}
5959
});
6060
if (needRemoveKey != "") {
61-
print('需要先移除定位城市 key: $needRemoveKey');
61+
weatherPrint('需要先移除定位城市 key: $needRemoveKey');
6262
allWeatherData.remove(needRemoveKey);
6363
}
6464
}

lib/views/bg/weather_rain_snow_bg.dart

Lines changed: 104 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@ class _WeatherRainSnowBgState extends State<WeatherRainSnowBg>
2323
List<RainSnowParams> _rainSnows = [];
2424
double width = 0;
2525
double height = 0;
26-
double scale = 0.0;
2726
int count = 0;
28-
double speed = 0;
2927
double baseSpeed = 5;
3028

3129
Future<void> fetchImages() async {
@@ -40,52 +38,36 @@ class _WeatherRainSnowBgState extends State<WeatherRainSnowBg>
4038

4139
Future<void> initParams() async {
4240
if (width != 0 && height != 0 && _rainSnows.isEmpty) {
43-
weatherPrint("开始雨参数初始化 ${_rainSnows.length}, weatherType: ${widget
44-
.weatherType}, isRainy: ${WeatherUtil.isRainy(widget.weatherType)}");
41+
weatherPrint(
42+
"开始雨参数初始化 ${_rainSnows.length}, weatherType: ${widget.weatherType}, isRainy: ${WeatherUtil.isRainy(widget.weatherType)}");
4543
if (WeatherUtil.isSnowRain(widget.weatherType)) {
4644
if (widget.weatherType == WeatherType.lightRainy) {
47-
scale = 0.1;
4845
count = 50;
49-
speed = 10;
5046
baseSpeed = 80;
5147
} else if (widget.weatherType == WeatherType.middleRainy) {
52-
scale = 0.1;
53-
count = 100;
54-
speed = 20;
48+
count = 80;
5549
baseSpeed = 80;
56-
} else if (widget.weatherType == WeatherType.heavyRainy) {
57-
scale = 0.1;
58-
count = 200;
59-
speed = 40;
50+
} else if (widget.weatherType == WeatherType.heavyRainy) {
51+
count = 160;
6052
baseSpeed = 80;
6153
} else if (widget.weatherType == WeatherType.lightSnow) {
62-
scale = 0.5;
6354
count = 30;
64-
speed = 10;
6555
} else if (widget.weatherType == WeatherType.middleSnow) {
66-
scale = 0.5;
6756
count = 100;
68-
speed = 15;
69-
} else if (widget.weatherType == WeatherType.heavySnow) {
70-
scale = 0.6;
57+
} else if (widget.weatherType == WeatherType.heavySnow) {
7158
count = 200;
72-
speed = 15;
7359
}
7460
for (int i = 0; i < count; i++) {
75-
double x = Random().nextInt(width ~/ scale).toDouble();
76-
double y = Random().nextInt(height ~/ scale).toDouble();
77-
_rainSnows.add(RainSnowParams(x, y, baseSpeed + Random().nextInt(speed.toInt()).toDouble()));
61+
var rainSnow = RainSnowParams(width, height, widget.weatherType);
62+
rainSnow.init();
63+
_rainSnows.add(rainSnow);
7864
}
7965
weatherPrint("初始化雨参数成功 ${_rainSnows.length}");
80-
setState(() {
81-
82-
});
66+
setState(() {});
8367
}
8468
}
8569
}
8670

87-
88-
8971
@override
9072
void initState() {
9173
_controller =
@@ -104,6 +86,12 @@ class _WeatherRainSnowBgState extends State<WeatherRainSnowBg>
10486
super.initState();
10587
}
10688

89+
@override
90+
void dispose() {
91+
_controller.dispose();
92+
super.dispose();
93+
}
94+
10795
@override
10896
Widget build(BuildContext context) {
10997
width = MediaQuery.of(context).size.width;
@@ -131,46 +119,69 @@ class RainSnowPainter extends CustomPainter {
131119
}
132120

133121
void drawRain(Canvas canvas, Size size) {
134-
weatherPrint("开始绘制雨层 image:${_state._images?.length}, rains:${_state._rainSnows?.length}");
122+
weatherPrint(
123+
"开始绘制雨层 image:${_state._images?.length}, rains:${_state._rainSnows?.length}");
135124
if (_state._images != null && _state._images.length > 1) {
136125
ui.Image image = _state._images[0];
137-
canvas.save();
138-
canvas.scale(_state.scale, _state.scale);
139126
if (_state._rainSnows != null && _state._rainSnows.isNotEmpty) {
140127
_state._rainSnows.forEach((element) {
141128
move(element);
142129
ui.Offset offset = ui.Offset(element.x, element.y);
130+
canvas.save();
131+
canvas.scale(element.scale, element.scale);
132+
var identity = ColorFilter.matrix(<double>[
133+
1, 0, 0, 0, 0,
134+
0, 1, 0, 0, 0,
135+
0, 0, 1, 0, 0,
136+
0, 0, 0, element.alpha, 0,
137+
]);
138+
_paint.colorFilter = identity;
143139
canvas.drawImage(image, offset, _paint);
140+
canvas.restore();
144141
});
145142
}
146-
canvas.restore();
147143
}
148144
}
149145

150146
void move(RainSnowParams params) {
151147
params.y = params.y + params.speed;
152-
if (params.y > 800 / _state.scale) {
148+
if (WeatherUtil.isSnow(_state.widget.weatherType)) {
149+
double offsetX = sin(params.y / (300 + 50 * params.alpha)) * (1 + 0.5 * params.alpha);
150+
params.x += offsetX;
151+
}
152+
if (params.y > 800 / params.scale) {
153153
params.y = 0;
154-
if (WeatherUtil.isRainy(_state.widget.weatherType) && _state._images.isNotEmpty && _state._images[0] != null) {
154+
if (WeatherUtil.isRainy(_state.widget.weatherType) &&
155+
_state._images.isNotEmpty &&
156+
_state._images[0] != null) {
155157
params.y = -_state._images[0].height.toDouble();
156158
}
159+
params.reset();
157160
}
158161
}
159162

160163
void drawSnow(Canvas canvas, Size size) {
161-
weatherPrint("开始绘制雪层 image:${_state._images?.length}, rains:${_state._rainSnows?.length}");
164+
weatherPrint(
165+
"开始绘制雪层 image:${_state._images?.length}, rains:${_state._rainSnows?.length}");
162166
if (_state._images != null && _state._images.length > 1) {
163167
ui.Image image = _state._images[1];
164-
canvas.save();
165-
canvas.scale(_state.scale, _state.scale);
166168
if (_state._rainSnows != null && _state._rainSnows.isNotEmpty) {
167169
_state._rainSnows.forEach((element) {
168170
move(element);
169171
ui.Offset offset = ui.Offset(element.x, element.y);
172+
canvas.save();
173+
canvas.scale(element.scale, element.scale);
174+
var identity = ColorFilter.matrix(<double>[
175+
1, 0, 0, 0, 0,
176+
0, 1, 0, 0, 0,
177+
0, 0, 1, 0, 0,
178+
0, 0, 0, element.alpha, 0,
179+
]);
180+
_paint.colorFilter = identity;
170181
canvas.drawImage(image, offset, _paint);
182+
canvas.restore();
171183
});
172184
}
173-
canvas.restore();
174185
}
175186
}
176187

@@ -184,6 +195,60 @@ class RainSnowParams {
184195
double x;
185196
double y;
186197
double speed;
198+
double scale;
199+
double width;
200+
double height;
201+
double alpha;
202+
WeatherType weatherType;
203+
204+
RainSnowParams(this.width, this.height, this.weatherType);
205+
206+
void init() {
207+
// 雨 0.1 雪 0.5
208+
reset();
209+
y = Random().nextInt(height ~/ scale).toDouble();
210+
}
187211

188-
RainSnowParams(this.x, this.y, this.speed);
212+
void reset() {
213+
double initScale = 0.1;
214+
double gapScale = 0.2;
215+
double initSpeed = 40;
216+
double gapSpeed = 40;
217+
if (weatherType == WeatherType.lightRainy) {
218+
initScale = 1.05;
219+
gapScale = 0.1;
220+
initSpeed = 15;
221+
gapSpeed = 10;
222+
} else if (weatherType == WeatherType.middleRainy) {
223+
initScale = 1.07;
224+
gapScale = 0.12;
225+
initSpeed = 20;
226+
gapSpeed = 20;
227+
} else if (weatherType == WeatherType.heavyRainy) {
228+
initScale = 1.09;
229+
gapScale = 0.15;
230+
initSpeed = 22;
231+
gapSpeed = 20;
232+
} else if (weatherType == WeatherType.lightSnow) {
233+
initScale = 0.45;
234+
gapScale = 0.05;
235+
initSpeed = 2;
236+
gapSpeed = 3;
237+
} else if (weatherType == WeatherType.middleSnow) {
238+
initScale = 0.4;
239+
gapScale = 0.15;
240+
initSpeed = 3;
241+
gapSpeed = 6;
242+
} else if (weatherType == WeatherType.heavySnow) {
243+
initScale = 0.45;
244+
gapScale = 0.2;
245+
initSpeed = 4;
246+
gapSpeed = 7;
247+
}
248+
double random = Random().nextDouble();
249+
this.scale = initScale + gapScale * random;
250+
this.speed = initSpeed + gapSpeed * (1 - random);
251+
this.alpha = 0.1 + 0.9 * random;
252+
x = Random().nextInt(width * 1.2 ~/ scale).toDouble() - width * 0.1 ~/ scale;
253+
}
189254
}

0 commit comments

Comments
 (0)