├── .gitignore
├── .metadata
├── .vscode
├── launch.json
└── settings.json
├── LICENSE
├── README.md
├── analysis_options.yaml
├── lib
└── main.dart
├── pubspec.lock
├── pubspec.yaml
├── test
└── widget_test.dart
└── web
├── favicon.png
├── flutter_bootstrap.js
├── icons
├── Icon-192.png
├── Icon-512.png
├── Icon-maskable-192.png
└── Icon-maskable-512.png
├── index.html
├── manifest.json
└── style.css
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 | migrate_working_dir/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
18 |
19 | # The .vscode folder contains launch configuration and tasks you configure in
20 | # VS Code which you may wish to be included in version control, so this line
21 | # is commented out by default.
22 | #.vscode/
23 |
24 | # Flutter/Dart/Pub related
25 | **/doc/api/
26 | **/ios/Flutter/.last_build_id
27 | .dart_tool/
28 | .flutter-plugins
29 | .flutter-plugins-dependencies
30 | .packages
31 | .pub-cache/
32 | .pub/
33 | /build/
34 |
35 | # Symbolication related
36 | app.*.symbols
37 |
38 | # Obfuscation related
39 | app.*.map.json
40 |
41 | # Android Studio will place build artifacts here
42 | /android/app/debug
43 | /android/app/profile
44 | /android/app/release
45 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: "367f9ea16bfae1ca451b9cc27c1366870b187ae2"
8 | channel: "stable"
9 |
10 | project_type: app
11 |
12 | # Tracks metadata for the flutter migrate command
13 | migration:
14 | platforms:
15 | - platform: root
16 | create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
17 | base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
18 | - platform: android
19 | create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
20 | base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
21 | - platform: ios
22 | create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
23 | base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
24 | - platform: linux
25 | create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
26 | base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
27 | - platform: macos
28 | create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
29 | base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
30 | - platform: web
31 | create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
32 | base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
33 | - platform: windows
34 | create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
35 | base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
36 |
37 | # User provided section
38 |
39 | # List of Local paths (relative to this file) that should be
40 | # ignored by the migrate tool.
41 | #
42 | # Files that are not part of the templates will be ignored by default.
43 | unmanaged_files:
44 | - 'lib/main.dart'
45 | - 'ios/Runner.xcodeproj/project.pbxproj'
46 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations":[
4 | {
5 | "name": "Flutter Web Loading Tips",
6 | "request": "launch",
7 | "type": "dart",
8 | "args":[
9 | "-d",
10 | "chrome",
11 | "--web-renderer",
12 | "canvaskit",
13 | ]
14 | }
15 | ]
16 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.codeActionsOnSave": {
3 | "source.fixAll": true,
4 | "source.organizeImports": true,
5 | }
6 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Daniel Coyula
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Flutter Web Loading Tips
2 |
3 | https://github.com/monster555/flutter_web_loading_tips/assets/32662133/83df94b8-fa19-4a89-a646-1ad55765a373
4 |
5 |
6 |
7 | ## Introduction
8 |
9 | User experience is essential in the software development world, and the loading process is a crucial aspect often overlooked. A slow or clunky loading experience can frustrate users and cause them to abandon your app before it even has a chance to load your Flutter Web app.
10 |
11 | ## Key Features
12 |
13 | - **Smooth Progress Bar**: Create an elegant progress bar that reflects the loading progress of your Flutter Web application.
14 | - **Graceful Fading**: Implement a graceful fading effect for the progress bar upon loading completion.
15 | - **Seamless Transition**: Ensure a seamless transition from the loading screen to displaying your Flutter content.
16 |
17 | ## Getting Started
18 |
19 | To get started with improving your Flutter Web loading experience, follow these steps:
20 |
21 | 1. **Clone the Repository**: Begin by cloning this repository to your local development environment.
22 |
23 | ```shell
24 | git clone https://github.com/monster555/flutter_web_loading_tips.git
25 | ```
26 |
27 | 2. Enhance Your App: Apply the techniques learned from the guide to your Flutter Web project, and watch as your loading experience becomes smoother and more professional.
28 |
29 | ## See How Smooth the Loading Experience is on FaceFolio
30 |
31 | This is one of my portfolio projects. To see the smooth loading experience in action, visit the [FaceFolio homepage](https://facefolio.dctech.dev).
32 |
33 | ## Step-by-Step
34 |
35 | Improving the loading experience in your Flutter Web application involves just a few steps. Follow each step closely to ensure proper implementation. The provided code snippets should be integrated into your project as described.
36 |
37 | ### Step 1: Adding Progress Bar Elements in index.html
38 |
39 | In your `index.html` file, add the following `
` elements to display the progress bar. These will visually represent the loading progress of the Flutter Engine.
40 |
41 | ```html
42 |
43 |
44 |
45 |
46 | ```
47 |
48 | ### Step 2: Adding the Script in `flutter_bootstrap.js`
49 |
50 | To ensure the proper initialization of your Flutter app using the new method available in Flutter 3.22 and later, you need to update the `web/flutter_bootstrap.js` file (not the `build/web/flutter_bootstrap.js`, which is auto-generated during the build process and will be overwritten).
51 |
52 | Below is an example of how your `web/flutter_bootstrap.js` file should look with the necessary changes in place:
53 |
54 | ```javascript
55 | /**
56 | * This function creates a delay of 500 milliseconds.
57 | *
58 | * @returns {Promise} A Promise that resolves after the delay.
59 | */
60 | function addDelay() {
61 | return new Promise((resolve) => setTimeout(resolve, 500));
62 | }
63 |
64 | // Get the progress and progressBar elements from the DOM
65 | const progress = document.getElementById("progress");
66 | const progressBar = document.getElementById("progressbar");
67 |
68 | // Initialize the width of the progress bar to 0%
69 | progress.style.width = `0%`;
70 |
71 | {{flutter_js}}
72 |
73 | progress.style.width = `33%`;
74 |
75 | {{flutter_build_config}}
76 |
77 | // Load the Flutter engine
78 | _flutter.loader.load({
79 | onEntrypointLoaded: async function(engineInitializer) {
80 | // Update the progress bar to 66% after the engine is loaded
81 | progressBar.style.width = `66%`;
82 |
83 | // Initialize the Flutter engine.
84 | const appRunner = await engineInitializer.initializeEngine();
85 |
86 | // Set progress to 100% before adding a delay.
87 | progressBar.style.width = `100%`;
88 |
89 | // Add a delay bofreo running the app to create a smooth crossfade effect.
90 | await addDelay();
91 |
92 | // Hide the progress bar by reducing its opacity.
93 | // This will create the fade out effect by animating the opacity.
94 | progress.style.opacity = 0;
95 |
96 | // Run the Flutter app.
97 | await appRunner.runApp();
98 |
99 | // Add a fade-in effect to the Flutter view element.
100 | document.querySelector("flutter-view").classList.add("fade-in");
101 | }
102 | });
103 | ```
104 |
105 | ### Step 3: Creating `style.css`
106 |
107 | Create a `style.css` file with the following content to style the progress bar and create the fade-in effect:
108 |
109 | ```css
110 | /* Styles for the body element */
111 | body {
112 | display: flex;
113 | justify-content: center;
114 | align-items: center;
115 | height: 100vh;
116 | margin: 0;
117 | background-color: #fff;
118 | }
119 |
120 | /* Styles for the progress bar container */
121 | .progress-container {
122 | width: 300px;
123 | height: 8px;
124 | background-color: #e0e0e0;
125 | border-radius: 10px;
126 | overflow: hidden;
127 | transition: opacity 0.25s ease-out;
128 | }
129 |
130 | /* Styles for the progress bar */
131 | .progress-bar {
132 | display: block;
133 | height: 100%;
134 | background-color: #6a6a6a;
135 | width: 0;
136 | transition: width 0.5s ease;
137 | }
138 |
139 | /* CSS for a fade-in animation */
140 | .fade-in {
141 | opacity: 0;
142 | animation: fadeIn 1s ease-in-out forwards;
143 | }
144 |
145 | /* Keyframes for the fadeIn animation */
146 | @keyframes fadeIn {
147 | 0% {
148 | opacity: 0;
149 | }
150 | 60% {
151 | opacity: 0;
152 | }
153 | 100% {
154 | opacity: 1;
155 | }
156 | }
157 | ```
158 |
159 | ### Step 4: Referencing `style.css`
160 |
161 | In your `index.html`, reference the `style.css` file to apply the defined styles:
162 |
163 | ```html
164 |
165 | ```
166 |
167 | By following these steps, you can implement a smooth loading experience in your Flutter Web application.
168 |
169 | ## License
170 |
171 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
172 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # This file configures the analyzer, which statically analyzes Dart code to
2 | # check for errors, warnings, and lints.
3 | #
4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6 | # invoked from the command line by running `flutter analyze`.
7 |
8 | # The following line activates a set of recommended lints for Flutter apps,
9 | # packages, and plugins designed to encourage good coding practices.
10 | include: package:flutter_lints/flutter.yaml
11 |
12 | linter:
13 | # The lint rules applied to this project can be customized in the
14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml`
15 | # included above or to enable additional rules. A list of all available lints
16 | # and their documentation is published at https://dart.dev/lints.
17 | #
18 | # Instead of disabling a lint rule for the entire project in the
19 | # section below, it can also be suppressed for a single line of code
20 | # or a specific dart file by using the `// ignore: name_of_lint` and
21 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file
22 | # producing the lint.
23 | rules:
24 | # avoid_print: false # Uncomment to disable the `avoid_print` rule
25 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
26 |
27 | # Additional information about this file can be found at
28 | # https://dart.dev/guides/language/analysis-options
29 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | void main() {
4 | runApp(const MyApp());
5 | }
6 |
7 | class MyApp extends StatelessWidget {
8 | const MyApp({super.key});
9 |
10 | @override
11 | Widget build(BuildContext context) {
12 | return MaterialApp(
13 | title: 'Flutter Web Loading Tips',
14 | theme: ThemeData(
15 | colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
16 | useMaterial3: true,
17 | ),
18 | home: const MyHomePage(title: 'Flutter Demo Home Page'),
19 | );
20 | }
21 | }
22 |
23 | class MyHomePage extends StatefulWidget {
24 | const MyHomePage({super.key, required this.title});
25 |
26 | final String title;
27 |
28 | @override
29 | State createState() => _MyHomePageState();
30 | }
31 |
32 | class _MyHomePageState extends State {
33 | int _counter = 0;
34 |
35 | void _incrementCounter() {
36 | setState(() {
37 | _counter++;
38 | });
39 | }
40 |
41 | @override
42 | Widget build(BuildContext context) {
43 | final theme = Theme.of(context);
44 |
45 | return Scaffold(
46 | appBar: AppBar(
47 | backgroundColor: theme.colorScheme.inversePrimary,
48 | title: Text(widget.title),
49 | ),
50 | body: Center(
51 | child: Column(
52 | mainAxisAlignment: MainAxisAlignment.center,
53 | children: [
54 | const Text(
55 | 'You have pushed the button this many times:',
56 | ),
57 | Text(
58 | '$_counter',
59 | style: theme.textTheme.headlineMedium,
60 | ),
61 | ],
62 | ),
63 | ),
64 | floatingActionButton: FloatingActionButton(
65 | onPressed: _incrementCounter,
66 | tooltip: 'Increment',
67 | child: const Icon(Icons.add),
68 | ),
69 | );
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | async:
5 | dependency: transitive
6 | description:
7 | name: async
8 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
9 | url: "https://pub.dev"
10 | source: hosted
11 | version: "2.11.0"
12 | boolean_selector:
13 | dependency: transitive
14 | description:
15 | name: boolean_selector
16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
17 | url: "https://pub.dev"
18 | source: hosted
19 | version: "2.1.1"
20 | characters:
21 | dependency: transitive
22 | description:
23 | name: characters
24 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
25 | url: "https://pub.dev"
26 | source: hosted
27 | version: "1.3.0"
28 | clock:
29 | dependency: transitive
30 | description:
31 | name: clock
32 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
33 | url: "https://pub.dev"
34 | source: hosted
35 | version: "1.1.1"
36 | collection:
37 | dependency: transitive
38 | description:
39 | name: collection
40 | sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
41 | url: "https://pub.dev"
42 | source: hosted
43 | version: "1.17.2"
44 | cupertino_icons:
45 | dependency: "direct main"
46 | description:
47 | name: cupertino_icons
48 | sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
49 | url: "https://pub.dev"
50 | source: hosted
51 | version: "1.0.6"
52 | fake_async:
53 | dependency: transitive
54 | description:
55 | name: fake_async
56 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
57 | url: "https://pub.dev"
58 | source: hosted
59 | version: "1.3.1"
60 | flutter:
61 | dependency: "direct main"
62 | description: flutter
63 | source: sdk
64 | version: "0.0.0"
65 | flutter_lints:
66 | dependency: "direct dev"
67 | description:
68 | name: flutter_lints
69 | sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
70 | url: "https://pub.dev"
71 | source: hosted
72 | version: "2.0.3"
73 | flutter_test:
74 | dependency: "direct dev"
75 | description: flutter
76 | source: sdk
77 | version: "0.0.0"
78 | lints:
79 | dependency: transitive
80 | description:
81 | name: lints
82 | sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
83 | url: "https://pub.dev"
84 | source: hosted
85 | version: "2.1.1"
86 | matcher:
87 | dependency: transitive
88 | description:
89 | name: matcher
90 | sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
91 | url: "https://pub.dev"
92 | source: hosted
93 | version: "0.12.16"
94 | material_color_utilities:
95 | dependency: transitive
96 | description:
97 | name: material_color_utilities
98 | sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
99 | url: "https://pub.dev"
100 | source: hosted
101 | version: "0.5.0"
102 | meta:
103 | dependency: transitive
104 | description:
105 | name: meta
106 | sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
107 | url: "https://pub.dev"
108 | source: hosted
109 | version: "1.9.1"
110 | path:
111 | dependency: transitive
112 | description:
113 | name: path
114 | sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
115 | url: "https://pub.dev"
116 | source: hosted
117 | version: "1.8.3"
118 | sky_engine:
119 | dependency: transitive
120 | description: flutter
121 | source: sdk
122 | version: "0.0.99"
123 | source_span:
124 | dependency: transitive
125 | description:
126 | name: source_span
127 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
128 | url: "https://pub.dev"
129 | source: hosted
130 | version: "1.10.0"
131 | stack_trace:
132 | dependency: transitive
133 | description:
134 | name: stack_trace
135 | sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
136 | url: "https://pub.dev"
137 | source: hosted
138 | version: "1.11.0"
139 | stream_channel:
140 | dependency: transitive
141 | description:
142 | name: stream_channel
143 | sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
144 | url: "https://pub.dev"
145 | source: hosted
146 | version: "2.1.1"
147 | string_scanner:
148 | dependency: transitive
149 | description:
150 | name: string_scanner
151 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
152 | url: "https://pub.dev"
153 | source: hosted
154 | version: "1.2.0"
155 | term_glyph:
156 | dependency: transitive
157 | description:
158 | name: term_glyph
159 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
160 | url: "https://pub.dev"
161 | source: hosted
162 | version: "1.2.1"
163 | test_api:
164 | dependency: transitive
165 | description:
166 | name: test_api
167 | sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
168 | url: "https://pub.dev"
169 | source: hosted
170 | version: "0.6.0"
171 | vector_math:
172 | dependency: transitive
173 | description:
174 | name: vector_math
175 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
176 | url: "https://pub.dev"
177 | source: hosted
178 | version: "2.1.4"
179 | web:
180 | dependency: transitive
181 | description:
182 | name: web
183 | sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
184 | url: "https://pub.dev"
185 | source: hosted
186 | version: "0.1.4-beta"
187 | sdks:
188 | dart: ">=3.1.2 <4.0.0"
189 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: flutter_web_loading_tips
2 | description: Flutter Web loading tips
3 |
4 | publish_to: 'none'
5 |
6 | version: 1.0.0+1
7 |
8 | environment:
9 | sdk: '>=3.1.2 <4.0.0'
10 |
11 | dependencies:
12 | flutter:
13 | sdk: flutter
14 |
15 | cupertino_icons: ^1.0.2
16 |
17 | dev_dependencies:
18 | flutter_test:
19 | sdk: flutter
20 |
21 | flutter_lints: ^2.0.0
22 |
23 | flutter:
24 | uses-material-design: true
25 |
--------------------------------------------------------------------------------
/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | //
3 | // To perform an interaction with a widget in your test, use the WidgetTester
4 | // utility in the flutter_test package. For example, you can send tap and scroll
5 | // gestures. You can also use WidgetTester to find child widgets in the widget
6 | // tree, read text, and verify that the values of widget properties are correct.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'package:flutter_web_loading_tips/main.dart';
12 |
13 | void main() {
14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async {
15 | // Build our app and trigger a frame.
16 | await tester.pumpWidget(const MyApp());
17 |
18 | // Verify that our counter starts at 0.
19 | expect(find.text('0'), findsOneWidget);
20 | expect(find.text('1'), findsNothing);
21 |
22 | // Tap the '+' icon and trigger a frame.
23 | await tester.tap(find.byIcon(Icons.add));
24 | await tester.pump();
25 |
26 | // Verify that our counter has incremented.
27 | expect(find.text('0'), findsNothing);
28 | expect(find.text('1'), findsOneWidget);
29 | });
30 | }
31 |
--------------------------------------------------------------------------------
/web/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monster555/flutter_web_loading_tips/d2a6b32ef69f4c1fe21c5f512976d15c0aa66a72/web/favicon.png
--------------------------------------------------------------------------------
/web/flutter_bootstrap.js:
--------------------------------------------------------------------------------
1 | /**
2 | * This function creates a delay of 500 milliseconds.
3 | *
4 | * @returns {Promise} A Promise that resolves after the delay.
5 | */
6 | function addDelay() {
7 | return new Promise((resolve) => setTimeout(resolve, 500));
8 | }
9 |
10 | // Get the progress and progressBar elements from the DOM
11 | const progress = document.getElementById("progress");
12 | const progressBar = document.getElementById("progressbar");
13 |
14 | // Initialize the width of the progress bar to 0%
15 | progress.style.width = `0%`;
16 |
17 | {{flutter_js}}
18 |
19 | progress.style.width = `33%`;
20 |
21 | {{flutter_build_config}}
22 |
23 | // Load the Flutter engine
24 | _flutter.loader.load({
25 | onEntrypointLoaded: async function(engineInitializer) {
26 | // Update the progress bar to 66% after the engine is loaded
27 | progressBar.style.width = `66%`;
28 |
29 | // Initialize the Flutter engine.
30 | const appRunner = await engineInitializer.initializeEngine();
31 |
32 | // Set progress to 100% before adding a delay.
33 | progressBar.style.width = `100%`;
34 |
35 | // Add a delay before running the app to create a smooth crossfade effect.
36 | await addDelay();
37 |
38 | // Hide the progress bar by reducing its opacity.
39 | // This will create the fade out effect by animating the opacity.
40 | progress.style.opacity = 0;
41 |
42 | // Run the Flutter app.
43 | await appRunner.runApp();
44 |
45 | // Add a fade-in effect to the Flutter view element.
46 | document.querySelector("flutter-view").classList.add("fade-in");
47 | }
48 | });
49 |
--------------------------------------------------------------------------------
/web/icons/Icon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monster555/flutter_web_loading_tips/d2a6b32ef69f4c1fe21c5f512976d15c0aa66a72/web/icons/Icon-192.png
--------------------------------------------------------------------------------
/web/icons/Icon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monster555/flutter_web_loading_tips/d2a6b32ef69f4c1fe21c5f512976d15c0aa66a72/web/icons/Icon-512.png
--------------------------------------------------------------------------------
/web/icons/Icon-maskable-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monster555/flutter_web_loading_tips/d2a6b32ef69f4c1fe21c5f512976d15c0aa66a72/web/icons/Icon-maskable-192.png
--------------------------------------------------------------------------------
/web/icons/Icon-maskable-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monster555/flutter_web_loading_tips/d2a6b32ef69f4c1fe21c5f512976d15c0aa66a72/web/icons/Icon-maskable-512.png
--------------------------------------------------------------------------------
/web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
17 |
18 |
19 |
20 |
21 |
22 | Flutter Web Loading Tips
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |