Skip to content

Commit

Permalink
[opt] 优化雨雪绘制逻辑和提升性能
Browse files Browse the repository at this point in the history
Signed-off-by: xiaweizi <[email protected]>
  • Loading branch information
xiaweizi committed Aug 31, 2020
1 parent edfbfd3 commit 52b5e2b
Show file tree
Hide file tree
Showing 13 changed files with 121 additions and 48 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

### 体验

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

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

Expand Down
Binary file modified assets/images/rain1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/qrcode.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/weather4.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/weather5.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/weather6.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions lib/app/res/analytics_constant.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ class AnalyticsConstant {
static const String bottomSheet = "bottom_sheet";
static const String aboutClick = "about_click";
static const String pageShow = "page_show";
static const String weatherType = "weather_type";

}
14 changes: 9 additions & 5 deletions lib/app/utils/print_utils.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@

import 'package:flutter/widgets.dart';

typedef WeatherPrint = void Function(String message, { int wrapWidth, String tag});
typedef WeatherPrint = void Function(String message,
{int wrapWidth, String tag});

const DEBUG = false;

WeatherPrint weatherPrint = debugPrintThrottled;

void debugPrintThrottled(String message, { int wrapWidth, String tag}) {
debugPrint("flutter-weather: $tag: $message", wrapWidth: wrapWidth);
}
void debugPrintThrottled(String message, {int wrapWidth, String tag}) {
if (DEBUG) {
debugPrint("flutter-weather: $tag: $message", wrapWidth: wrapWidth);
}
}
2 changes: 1 addition & 1 deletion lib/bloc/weather/weather_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class WeatherBloc extends Bloc<WeatherEvent, WeatherState> {
}
});
if (needRemoveKey != "") {
print('需要先移除定位城市 key: $needRemoveKey');
weatherPrint('需要先移除定位城市 key: $needRemoveKey');
allWeatherData.remove(needRemoveKey);
}
}
Expand Down
143 changes: 104 additions & 39 deletions lib/views/bg/weather_rain_snow_bg.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ class _WeatherRainSnowBgState extends State<WeatherRainSnowBg>
List<RainSnowParams> _rainSnows = [];
double width = 0;
double height = 0;
double scale = 0.0;
int count = 0;
double speed = 0;
double baseSpeed = 5;

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

Future<void> initParams() async {
if (width != 0 && height != 0 && _rainSnows.isEmpty) {
weatherPrint("开始雨参数初始化 ${_rainSnows.length}, weatherType: ${widget
.weatherType}, isRainy: ${WeatherUtil.isRainy(widget.weatherType)}");
weatherPrint(
"开始雨参数初始化 ${_rainSnows.length}, weatherType: ${widget.weatherType}, isRainy: ${WeatherUtil.isRainy(widget.weatherType)}");
if (WeatherUtil.isSnowRain(widget.weatherType)) {
if (widget.weatherType == WeatherType.lightRainy) {
scale = 0.1;
count = 50;
speed = 10;
baseSpeed = 80;
} else if (widget.weatherType == WeatherType.middleRainy) {
scale = 0.1;
count = 100;
speed = 20;
count = 80;
baseSpeed = 80;
} else if (widget.weatherType == WeatherType.heavyRainy) {
scale = 0.1;
count = 200;
speed = 40;
} else if (widget.weatherType == WeatherType.heavyRainy) {
count = 160;
baseSpeed = 80;
} else if (widget.weatherType == WeatherType.lightSnow) {
scale = 0.5;
count = 30;
speed = 10;
} else if (widget.weatherType == WeatherType.middleSnow) {
scale = 0.5;
count = 100;
speed = 15;
} else if (widget.weatherType == WeatherType.heavySnow) {
scale = 0.6;
} else if (widget.weatherType == WeatherType.heavySnow) {
count = 200;
speed = 15;
}
for (int i = 0; i < count; i++) {
double x = Random().nextInt(width ~/ scale).toDouble();
double y = Random().nextInt(height ~/ scale).toDouble();
_rainSnows.add(RainSnowParams(x, y, baseSpeed + Random().nextInt(speed.toInt()).toDouble()));
var rainSnow = RainSnowParams(width, height, widget.weatherType);
rainSnow.init();
_rainSnows.add(rainSnow);
}
weatherPrint("初始化雨参数成功 ${_rainSnows.length}");
setState(() {

});
setState(() {});
}
}
}



@override
void initState() {
_controller =
Expand All @@ -104,6 +86,12 @@ class _WeatherRainSnowBgState extends State<WeatherRainSnowBg>
super.initState();
}

@override
void dispose() {
_controller.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
width = MediaQuery.of(context).size.width;
Expand Down Expand Up @@ -131,46 +119,69 @@ class RainSnowPainter extends CustomPainter {
}

void drawRain(Canvas canvas, Size size) {
weatherPrint("开始绘制雨层 image:${_state._images?.length}, rains:${_state._rainSnows?.length}");
weatherPrint(
"开始绘制雨层 image:${_state._images?.length}, rains:${_state._rainSnows?.length}");
if (_state._images != null && _state._images.length > 1) {
ui.Image image = _state._images[0];
canvas.save();
canvas.scale(_state.scale, _state.scale);
if (_state._rainSnows != null && _state._rainSnows.isNotEmpty) {
_state._rainSnows.forEach((element) {
move(element);
ui.Offset offset = ui.Offset(element.x, element.y);
canvas.save();
canvas.scale(element.scale, element.scale);
var identity = ColorFilter.matrix(<double>[
1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 1, 0, 0,
0, 0, 0, element.alpha, 0,
]);
_paint.colorFilter = identity;
canvas.drawImage(image, offset, _paint);
canvas.restore();
});
}
canvas.restore();
}
}

void move(RainSnowParams params) {
params.y = params.y + params.speed;
if (params.y > 800 / _state.scale) {
if (WeatherUtil.isSnow(_state.widget.weatherType)) {
double offsetX = sin(params.y / (300 + 50 * params.alpha)) * (1 + 0.5 * params.alpha);
params.x += offsetX;
}
if (params.y > 800 / params.scale) {
params.y = 0;
if (WeatherUtil.isRainy(_state.widget.weatherType) && _state._images.isNotEmpty && _state._images[0] != null) {
if (WeatherUtil.isRainy(_state.widget.weatherType) &&
_state._images.isNotEmpty &&
_state._images[0] != null) {
params.y = -_state._images[0].height.toDouble();
}
params.reset();
}
}

void drawSnow(Canvas canvas, Size size) {
weatherPrint("开始绘制雪层 image:${_state._images?.length}, rains:${_state._rainSnows?.length}");
weatherPrint(
"开始绘制雪层 image:${_state._images?.length}, rains:${_state._rainSnows?.length}");
if (_state._images != null && _state._images.length > 1) {
ui.Image image = _state._images[1];
canvas.save();
canvas.scale(_state.scale, _state.scale);
if (_state._rainSnows != null && _state._rainSnows.isNotEmpty) {
_state._rainSnows.forEach((element) {
move(element);
ui.Offset offset = ui.Offset(element.x, element.y);
canvas.save();
canvas.scale(element.scale, element.scale);
var identity = ColorFilter.matrix(<double>[
1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 1, 0, 0,
0, 0, 0, element.alpha, 0,
]);
_paint.colorFilter = identity;
canvas.drawImage(image, offset, _paint);
canvas.restore();
});
}
canvas.restore();
}
}

Expand All @@ -184,6 +195,60 @@ class RainSnowParams {
double x;
double y;
double speed;
double scale;
double width;
double height;
double alpha;
WeatherType weatherType;

RainSnowParams(this.width, this.height, this.weatherType);

void init() {
// 雨 0.1 雪 0.5
reset();
y = Random().nextInt(height ~/ scale).toDouble();
}

RainSnowParams(this.x, this.y, this.speed);
void reset() {
double initScale = 0.1;
double gapScale = 0.2;
double initSpeed = 40;
double gapSpeed = 40;
if (weatherType == WeatherType.lightRainy) {
initScale = 1.05;
gapScale = 0.1;
initSpeed = 15;
gapSpeed = 10;
} else if (weatherType == WeatherType.middleRainy) {
initScale = 1.07;
gapScale = 0.12;
initSpeed = 20;
gapSpeed = 20;
} else if (weatherType == WeatherType.heavyRainy) {
initScale = 1.09;
gapScale = 0.15;
initSpeed = 22;
gapSpeed = 20;
} else if (weatherType == WeatherType.lightSnow) {
initScale = 0.45;
gapScale = 0.05;
initSpeed = 2;
gapSpeed = 3;
} else if (weatherType == WeatherType.middleSnow) {
initScale = 0.4;
gapScale = 0.15;
initSpeed = 3;
gapSpeed = 6;
} else if (weatherType == WeatherType.heavySnow) {
initScale = 0.45;
gapScale = 0.2;
initSpeed = 4;
gapSpeed = 7;
}
double random = Random().nextDouble();
this.scale = initScale + gapScale * random;
this.speed = initSpeed + gapSpeed * (1 - random);
this.alpha = 0.1 + 0.9 * random;
x = Random().nextInt(width * 1.2 ~/ scale).toDouble() - width * 0.1 ~/ scale;
}
}
2 changes: 1 addition & 1 deletion lib/views/pages/about/about_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ class _AboutPageState extends State<AboutPage> {
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(_appName,
Text(_appName == null ? "" : _appName,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
Expand Down
3 changes: 3 additions & 0 deletions lib/views/pages/home/real_time.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_dynamic_weather/app/res/analytics_constant.dart';
import 'package:flutter_dynamic_weather/app/res/dimen_constant.dart';
import 'package:flutter_dynamic_weather/app/res/weather_type.dart';
import 'package:flutter_dynamic_weather/app/utils/print_utils.dart';
import 'package:flutter_dynamic_weather/model/weather_model_entity.dart';
import 'package:umeng_analytics_plugin/umeng_analytics_plugin.dart';

class RealtimeView extends StatelessWidget {
final WeatherModelEntity entity;
Expand All @@ -29,6 +31,7 @@ class RealtimeView extends StatelessWidget {
if (entity != null &&
entity.result != null &&
entity.result.realtime != null) {
UmengAnalyticsPlugin.event(AnalyticsConstant.weatherType, label: WeatherUtil.convertDesc(entity.result.realtime.skycon));
child = Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.7.0+7
version: 2.0.0+20

environment:
sdk: ">=2.7.0 <3.0.0"
Expand Down

0 comments on commit 52b5e2b

Please sign in to comment.