Skip to content

Commit 2cc2d52

Browse files
committed
Add fade between splash and app on web. Thanks eggp for the suggestion and example code. Closes #608. Add check of parameter names to catch user typos in the parameters.
1 parent 18027f5 commit 2cc2d52

8 files changed

Lines changed: 156 additions & 38 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## [2.3.6] - (2023-Nov-20)
2+
3+
- Add fade between splash and app on web. Thanks [eggp](https://github.com/eggp) for the suggestion and example code. Closes [#608](https://github.com/jonbhanson/flutter_native_splash/issues/608).
4+
- Add check of parameter names to catch user typos in the parameters.
5+
16
## [2.3.5] - (2023-Oct-29)
27

38
- Remove white flash on web. Thanks [eggp](https://github.com/eggp) for pointing out the problem and solution. Closes [#607](https://github.com/jonbhanson/flutter_native_splash/issues/607).

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ First, add `flutter_native_splash` as a dependency in your pubspec.yaml file.
2121

2222
```yaml
2323
dependencies:
24-
flutter_native_splash: ^2.3.5
24+
flutter_native_splash: ^2.3.6
2525
```
2626
2727
Don't forget to `flutter pub get`.
@@ -169,6 +169,10 @@ flutter_native_splash:
169169
# SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.bottom, SystemUiOverlay.top], );
170170
#fullscreen: true
171171
172+
# On web, the splash screen fades out in 250ms. This fade delay can be adjusted by changing
173+
# the web_splash_fade_time_ms parameter.
174+
#web_splash_fade_time_ms: 250
175+
172176
# If you have changed the name(s) of your info.plist file(s), you can specify the filename(s)
173177
# with the info_plist_files parameter. Remove only the # characters in the three lines below,
174178
# do not remove any spaces:

example/pubspec.lock

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
# Generated by pub
22
# See https://dart.dev/tools/pub/glossary#lockfile
33
packages:
4+
ansicolor:
5+
dependency: transitive
6+
description:
7+
name: ansicolor
8+
sha256: "8bf17a8ff6ea17499e40a2d2542c2f481cd7615760c6d34065cb22bfd22e6880"
9+
url: "https://pub.dev"
10+
source: hosted
11+
version: "2.0.2"
412
archive:
513
dependency: transitive
614
description:
@@ -116,7 +124,7 @@ packages:
116124
path: ".."
117125
relative: true
118126
source: path
119-
version: "2.3.5"
127+
version: "2.3.6"
120128
flutter_test:
121129
dependency: "direct dev"
122130
description: flutter

example/pubspec.yaml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ flutter_native_splash:
100100
# To restore Flutter's default white splash screen, run the following command in the terminal:
101101
# dart run flutter_native_splash:remove
102102

103+
# IMPORTANT NOTE: These parameter do not affect the configuration of Android 12 and later, which
104+
# handle splash screens differently that prior versions of Android. Android 12 and later must be
105+
# configured specifically in the android_12 section below.
106+
103107
# color or background_image is the only required parameter. Use color to set the background
104108
# of your splash screen to a solid color. Use background_image to set the background of your
105109
# splash screen to a png image. This is useful for gradients. The image will be stretch to the
@@ -180,8 +184,8 @@ flutter_native_splash:
180184
#image_dark_android: assets/splash-invert-android.png
181185
#image_ios: assets/splash-ios.png
182186
#image_dark_ios: assets/splash-invert-ios.png
183-
#image_web: assets/splash-web.png
184-
#image_dark_web: assets/splash-invert-web.png
187+
#image_web: assets/splash-web.gif
188+
#image_dark_web: assets/splash-invert-web.gif
185189
#background_image_android: "assets/background-android.png"
186190
#background_image_dark_android: "assets/dark-background-android.png"
187191
#background_image_ios: "assets/background-ios.png"
@@ -192,6 +196,8 @@ flutter_native_splash:
192196
#branding_dark_android: assets/dart_dark-android.png
193197
#branding_ios: assets/brand-ios.png
194198
#branding_dark_ios: assets/dart_dark-ios.png
199+
#branding_web: assets/brand-web.gif
200+
#branding_dark_web: assets/dart_dark-web.gif
195201

196202
# The position of the splash image can be set with android_gravity, ios_content_mode, and
197203
# web_image_mode parameters. All default to center.
@@ -221,8 +227,12 @@ flutter_native_splash:
221227
# NOTE: Unlike Android, iOS will not automatically show the notification bar when the app loads.
222228
# To show the notification bar, add the following code to your Flutter app:
223229
# WidgetsFlutterBinding.ensureInitialized();
224-
# SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom, SystemUiOverlay.top]);
225-
fullscreen: true
230+
# SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.bottom, SystemUiOverlay.top], );
231+
#fullscreen: true
232+
233+
# On web, the splash screen fades out in 250ms. This fade delay can be adjusted by changing
234+
# the web_splash_fade_time_ms parameter.
235+
#web_splash_fade_time_ms: 250
226236

227237
# If you have changed the name(s) of your info.plist file(s), you can specify the filename(s)
228238
# with the info_plist_files parameter. Remove only the # characters in the three lines below,

lib/cli_commands.dart

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ library flutter_native_splash_cli;
55

66
import 'dart:isolate';
77

8+
import 'package:ansicolor/ansicolor.dart';
89
import 'package:html/parser.dart' as html_parser;
910
import 'package:image/image.dart';
1011
import 'package:meta/meta.dart';
@@ -118,6 +119,7 @@ void createSplashByConfig(Map<String, dynamic> config) {
118119
final String iosContentMode =
119120
config[_Parameter.iosContentMode] as String? ?? 'center';
120121
final webImageMode = config[_Parameter.webImageMode] as String? ?? 'center';
122+
final fadeTimeMs = config[_Parameter.fadeTimeMs] as int? ?? 250;
121123
String? android12Image;
122124
String? android12DarkImage;
123125
String? android12IconBackgroundColor;
@@ -213,6 +215,7 @@ void createSplashByConfig(Map<String, dynamic> config) {
213215
darkColor: darkColorWeb ?? darkColor,
214216
imageMode: webImageMode,
215217
brandingMode: brandingGravity,
218+
fadeTimeMs: fadeTimeMs,
216219
);
217220
} else {
218221
print('Web folder not found, skipping web splash update...');
@@ -370,6 +373,13 @@ Map<String, dynamic> getConfig({
370373
Map<String, dynamic> _yamlToMap(YamlMap yamlMap) {
371374
final Map<String, dynamic> map = <String, dynamic>{};
372375
for (final MapEntry<dynamic, dynamic> entry in yamlMap.entries) {
376+
if (!_Parameter.all.contains(entry.key)) {
377+
AnsiPen pen = AnsiPen()..red(bold: true);
378+
print(pen("⚠️ The parameter \"${entry.key}\" was found "
379+
"in your flutter_native_splash config, but \"${entry.key}\" "
380+
"is not a valid flutter_native_splash parameter."));
381+
exit(0);
382+
}
373383
if (entry.value is YamlList) {
374384
final list = <String>[];
375385
for (final value in entry.value as YamlList) {
@@ -447,4 +457,54 @@ class _Parameter {
447457
static const plistFiles = 'info_plist_files';
448458
static const web = 'web';
449459
static const webImageMode = 'web_image_mode';
460+
static const fadeTimeMs = 'web_splash_fade_time_ms';
461+
462+
static List<String> all = [
463+
android,
464+
android12Section,
465+
androidScreenOrientation,
466+
backgroundImage,
467+
backgroundImageAndroid,
468+
backgroundImageIos,
469+
backgroundImageWeb,
470+
brandingDarkImage,
471+
brandingDarkImageAndroid,
472+
brandingDarkImageIos,
473+
brandingDarkImageWeb,
474+
brandingGravity,
475+
brandingImage,
476+
brandingImageAndroid,
477+
brandingImageIos,
478+
brandingImageWeb,
479+
color,
480+
colorAndroid,
481+
colorIos,
482+
colorWeb,
483+
darkBackgroundImage,
484+
darkBackgroundImageAndroid,
485+
darkBackgroundImageIos,
486+
darkBackgroundImageWeb,
487+
darkColor,
488+
darkColorAndroid,
489+
darkColorIos,
490+
darkColorWeb,
491+
darkImage,
492+
darkImageAndroid,
493+
darkImageIos,
494+
darkImageWeb,
495+
fullscreen,
496+
gravity,
497+
iconBackgroundColor,
498+
iconBackgroundColorDark,
499+
image,
500+
imageAndroid,
501+
imageIos,
502+
imageWeb,
503+
ios,
504+
iosContentMode,
505+
plistFiles,
506+
web,
507+
webImageMode,
508+
fadeTimeMs,
509+
];
450510
}

lib/templates.dart

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -407,19 +407,34 @@ const String _iOSBrandingRightBottomConstraints = '''
407407
/// Web related templates
408408
const String _webCss = '''
409409
<style id="splash-screen-style">
410-
html {
411-
height: 100%
410+
.flutter-loader {
411+
z-index: 999999;
412412
}
413-
414-
body {
415-
margin: 0;
416-
min-height: 100%;
417-
background-color: [LIGHTBACKGROUNDCOLOR];
418-
[LIGHTBACKGROUNDIMAGE]
419-
background-size: 100% 100%;
413+
414+
#splash {
415+
position: fixed;
416+
width: 100%;
417+
height: 100%;
418+
top: 0px;
419+
left: 0px;
420+
z-index: 999998;
421+
opacity: 1;
422+
/* animation type and duration */
423+
transition: opacity [FADETIME];
424+
background-color: [LIGHTBACKGROUNDCOLOR];
425+
[LIGHTBACKGROUNDIMAGE]
426+
-moz-osx-font-smoothing: grayscale;
427+
-webkit-font-smoothing: antialiased;
428+
}
429+
430+
#splash.remove {
431+
/* enable click through when run animation */
432+
pointer-events: none;
433+
/* start animation */
434+
opacity: 0;
420435
}
421436
422-
.center {
437+
#splash .center {
423438
margin: 0;
424439
position: absolute;
425440
top: 50%;
@@ -428,38 +443,38 @@ const String _webCss = '''
428443
transform: translate(-50%, -50%);
429444
}
430445
431-
.contain {
446+
#splash .contain {
432447
display:block;
433448
width:100%; height:100%;
434449
object-fit: contain;
435450
}
436451
437-
.stretch {
452+
#splash .stretch {
438453
display:block;
439454
width:100%; height:100%;
440455
}
441456
442-
.cover {
457+
#splash .cover {
443458
display:block;
444459
width:100%; height:100%;
445460
object-fit: cover;
446461
}
447462
448-
.bottom {
463+
#splash .bottom {
449464
position: absolute;
450465
bottom: 0;
451466
left: 50%;
452467
-ms-transform: translate(-50%, 0);
453468
transform: translate(-50%, 0);
454469
}
455470
456-
.bottomLeft {
471+
#splash .bottomLeft {
457472
position: absolute;
458473
bottom: 0;
459474
left: 0;
460475
}
461476
462-
.bottomRight {
477+
#splash .bottomRight {
463478
position: absolute;
464479
bottom: 0;
465480
right: 0;
@@ -469,7 +484,7 @@ const String _webCss = '''
469484
const String _webCssDark = '''
470485
471486
@media (prefers-color-scheme: dark) {
472-
body {
487+
#splash {
473488
background-color: [DARKBACKGROUNDCOLOR];
474489
[DARKBACKGROUNDIMAGE]
475490
}
@@ -478,11 +493,13 @@ const String _webCssDark = '''
478493

479494
// XML's insertBefore can't have a newline at the end:
480495
const String _indexHtmlPicture = '''
481-
<picture id="splash">
482-
<source srcset="splash/img/light-1x.[IMAGEEXTENSION] 1x, splash/img/light-2x.[IMAGEEXTENSION] 2x, splash/img/light-3x.[IMAGEEXTENSION] 3x, splash/img/light-4x.[IMAGEEXTENSION] 4x" media="(prefers-color-scheme: light)">
483-
<source srcset="splash/img/dark-1x.[IMAGEEXTENSION] 1x, splash/img/dark-2x.[IMAGEEXTENSION] 2x, splash/img/dark-3x.[IMAGEEXTENSION] 3x, splash/img/dark-4x.[IMAGEEXTENSION] 4x" media="(prefers-color-scheme: dark)">
484-
<img class="[IMAGEMODE]" aria-hidden="true" src="splash/img/light-1x.[IMAGEEXTENSION]" alt=""/>
485-
</picture>''';
496+
<div id="splash">
497+
<picture>
498+
<source srcset="splash/img/light-1x.[IMAGEEXTENSION] 1x, splash/img/light-2x.[IMAGEEXTENSION] 2x, splash/img/light-3x.[IMAGEEXTENSION] 3x, splash/img/light-4x.[IMAGEEXTENSION] 4x" media="(prefers-color-scheme: light)">
499+
<source srcset="splash/img/dark-1x.[IMAGEEXTENSION] 1x, splash/img/dark-2x.[IMAGEEXTENSION] 2x, splash/img/dark-3x.[IMAGEEXTENSION] 3x, splash/img/dark-4x.[IMAGEEXTENSION] 4x" media="(prefers-color-scheme: dark)">
500+
<img class="[IMAGEMODE]" aria-hidden="true" src="splash/img/light-1x.[IMAGEEXTENSION]" alt=""/>
501+
</picture>
502+
</div>''';
486503

487504
// XML's insertBefore can't have a newline at the end:
488505
const String _indexHtmlBrandingPicture = '''
@@ -495,9 +512,12 @@ const String _indexHtmlBrandingPicture = '''
495512
const String _webJS = '''
496513
<script id="splash-screen-script">
497514
function removeSplashFromWeb() {
498-
document.getElementById("splash")?.remove();
499-
document.getElementById("splash-branding")?.remove();
500-
document.body.style.background = "transparent";
515+
const splashElement = document.getElementById("splash");
516+
splashElement.classList.add("remove");
517+
setTimeout(function () {
518+
splashElement.remove();
519+
document.getElementById("splash-screen-script")?.remove();
520+
}, [FADETIME] /* animation time + wait rendering and others(500ms) */);
501521
}
502522
</script>
503523
''';

0 commit comments

Comments
 (0)