2. Flutter
Flutter is an open source framework by Google for building beautiful, natively compiled, multi-
platform applications from a single codebase.
It is used to develop cross-platform applications for Android, iOS, Linux, macOS, Windows,
Google Fuchsia, and the web from a single codebase.
It works on Dart.
4. Prerequisites
● Basic knowledge of Flutter development with Dart, as covered in the Your first Flutter app codelab
What you'll learn
● How to use flutter_animate to build expressive animations
● How to use Flutter's support for fragment shaders on desktop and the web
● How to add particle animations to your app with particle_field
What you need
● The Flutter SDK
● Android Studio / VS Code setup for Flutter and Dart
● Desktop support setup for Flutter for Windows, Linux, or macOS
● Web support setup for Flutter
Before you begin
5. Get started
Download the starter code
1. Navigate to https://github.com/eqrakhattak/next-gen-uis
2. Click Code > Download zip to download first step code for this codelab.
3. Unzip the downloaded zip file to unpack a next-gen-ui/ directory, which contains the step_01 folder,
which contains the source code that you build upon for the first step in this codelab.
4. Given with the code is a further-steps.txt file which contains the code for further step we will go through in
this codelab
If you get this error, upgrade to Flutter 3.3 or higher
6. Download the project dependencies
1. In Android Studio, click File > Open folder > next-gen-uis > step_01 to open the starter project.
2. Get packages/dependencies
3. If you don't see a prompt, download the required packages for the starter app, open your terminal, and then
navigate to the step_01 folder and run the flutter pub get command.
Run the starter app
1. Select the desktop operating system you are running or Chrome if you want to test your app in a web
browser.
2. Open the lib/main.dart file and click Start debugging.
The app launches on your desktop operating system or in a Chrome browser.
7. Explore the starter app
In the starter app, notice the following:
● The UI is ready for you to build.
● The assets directory has the art assets and two fragment shaders that you will use.
● The pubspec.yaml file already lists the assets and a collection of pub packages that you will be utilizing.
● The lib directory contains the obligatory main.dart file, an assets.dart file that lists the path of the
art assets and fragment shaders, and a styles.dart file that lists the TextStyles and Colors you will use.
● The lib directory also contains a common directory, which holds a handful of useful utilities that you will
use in this codelab, and the orb_shader directory, which contains a Widget that will be used to display
the orb with a vertex shader.
Here is what you will see once you start the app:
8. Paint the scene
Add assets to the scene
1. Create a title_screen directory in your lib directory, and then add a title_screen.dart file.
2. Add this code (step 1)
3. In main.dart, remove styles.dart import.
4. Add title_screen import
5. In home, put const TitleScreen() object
6. Run app
9. Add an image coloring utility
Add an image coloring utility by adding the following content to the title_screen.dart file: (Step 2)
This _LitImage utility widget recolors each of the art assets, depending on whether they are emitting or receiving light.
Paint in color
Paint in color by modifying the title_screen.dart file, as follows:
1. Add import styles.dart
2. Add attributes : final _finalReceiveLightAmt = 0.7; final _finalEmitLightAmt = 0.5; under constructor
3. Add final orbColor=AppColors.orbColors[0]; & emitColor attributes under build method
4. Call _LitImage() constructor for every asset (to tinted green)
5. Hot restart, instead of just a hot reload.
6. Refer to (step 3) on notes for the code and run!
10. Add a UI
Add a title
1. Create a title_screen_ui.dart file inside of the lib/title_screen directory and add this content to
the file: (step 4)
2. Update the lib/title_screen/title_screen.dart file
3. Import title_screen_ui.dart
4. Add TitileScreenUi() at the end of stack
5. Wrap it with Positioned.fill(..)
11. Add the difficulty buttons
1. Update title_screen_ui.dart by adding a new import for the focusable_control_builder
package:
2. To the TitleScreenUi widget, add the attribute difficulty, void functions onDifficultyPressed; &
onDifficultyFocused; with parameter difficulty
3. Add difficulty buttons on buttomLeft() of the stack
4. Add the following two widgets to implement the difficulty buttons: step 5 add difficulty buttons
5. Update the difficulty btns() widget with these parameters
6. Convert the TitleScreen widget from stateless to stateful,
7. add state to enable changing the color scheme based on difficulty: step 6: change color
8. Add attributes to widget TitleScreenUi()
9. Modifying the const TitleScreen and TitleScreenUi widgets requires a hot restart, instead of just a hot
reload.
10. Here is the UI at two different difficulty settings. Notice that the difficulty colors applied as masks to
grayscale images creates a realistic, reflective effect!
12. Add the start button
1. Update the title_screen_ui.dart file. To the TitleScreenUi widget, add the _startBtn() on the
bottom right corner
2. Create _StartBtn() class by adding (step 7) to ur code
3. Add some padding to bottom(20) & right(40)
13. Add animation
Fade in the title
In this step, you use multiple approaches to animate a Flutter app. One of the approaches is to use
flutter_animate. Animations powered by this package can automatically replay whenever you hot reload your
app in order to speed up development iterations.
1. Modify the code in lib/main.dart, as follows:
2. import flutter_animate package
3. Add Animate.restartOnHotReload = true; before runApp() function (automatically replay animations
whenever you hot reload your app in order to speed up development iterations.)
4. Hot restart since changes are made in main()
5. Add the import in lib/title_screen/title_screen_ui.dart
6. Animate the texts in TitleText() with .animate().fadeIn(delay: .8.seconds, duration: .7.seconds),
7. Press Reload to see the title fade in
14. Fade in the difficulty buttons
Add animation to the initial appearance of the difficulty buttons by editing the _DifficultyBtns widget, as
follows:
1. To each button, add .animate() .fadeIn(delay: 1.3.seconds, duration: .35.seconds) .slide(begin: const
Offset(0, .2)),
Fade in the start button
Add animation to the start button by editing the _StartBtnState state class, as follows:
1. Add animation code under stack() and sizedBox() (step 8)
2. Take care of the comma and semicolon
Animate the difficulty hover effect
Add animation to the difficulty buttons' hover state by editing the _DifficultyBtn state class, as follows:
1. In DifficultyBtn() class, wrap the container with AnimatedOpacity()
2. Set the opacity to opacity: (!selected && (state.isHovered || state.isFocused)) ? 1 : 0,
3. And duration to duration: .3.seconds,
15. Animate the color change
The background color change is instantaneous and harsh. It's better to animate the lit images between color
schemes.
1. Add flutter_animate to lib/title_screen/title_screen.dart:
2. Add an _AnimatedColors widget in lib/title_screen/title_screen.dart: (step 9)
3. Wrap Stack() with AnimatedColors() (to animate the colors of the lit images)
4. Add required fields
5. update the build method in _TitleScreenState, as builder: (_, orbColor, emitColor) { Stack(); }
6. Change the colors to new builder colors
7. Animate the stack with .animate().fadeIn(duration: 1.seconds, delay: .3.seconds)
With this final edit, you added animations to every element on the screen, and it looks so much better!
16. Add fragment shaders
Distorting the title with a fragment shader
With this change you introduce the provider package, which enables passing the compiled shaders down the
widget tree.
1. Modify the code in lib/main.dart, as follows:
2. Import provider and assets
3. Paste the fragment code inside runapp() (step 10)
4. Hot restart
To take advantage of the provider package, in title_screen_ui.dart,
1. Import provider, shader effect, ticking builder from common
2. By editing the _TitleText widget, modify Widget content = Column(); return;
3. Add return code (step 11)
17. Add the orb
Now add the orb at the center of the window. You need to add an onPressed callback to the start button. Modify
TitleScreenUi as follows:
1. Initialize final VoidCallback onStartPressed;
2. Add it in the constructor
3. Add it in the _startBtn(onPressed: OnStartPressed)
Now that you have modified the start button with a callback, you need to make massive modifications to the
lib/title_screen/title_screen.dart file.
1. Modify the imports, as dart:math, dart:ui, services, orb_shader_config & orb_shader_widget from orb_shder
2. Modify _TitleScreenState to match the following. Almost every part of the class is modified in some
way (step 12)
3. To remove errors, Modify _LitImage, as follows:
4. Declare final AnimationController pulseEffect;
5. Initialize in the constructor
6. Wrap Image.asset around ListenableBuilder()
7. In builder add builder: (context, child) { return Image.asset(); },
18. Add particle animations
Add particles everywhere
1. Create a new dart file lib/title_screen/particle_overlay.dart file
2. Add the following code (step 13)
3. Imports partcle_overlay in lib/title_screen/title_screen.dart,
4. Modify the build method of _TitleScreenState
5. Add the Particle overlay to the UI under Mg_Emit
6. Positioned to fill and ignorePointer to create a particleoverlay
7. Add required fields with non private orb color and private orbEnergy
The final result includes animations, fragment shaders, and particle effects—on multiple platforms!
19. Add particles everywhere—even the web
Flutter for web has two alternate rendering engines:
1. CanvasKit engine, which is used by default on desktop class browsers
2. HTML DOM renderer, which is used by default for mobile devices.
The issue is that the HTML DOM renderer doesn't support fragment shaders. The fix is to configure the web
experience to use the CanvasKit engine everywhere.
Modify web/index.html, by using initializeEngine({ renderer: 'canvaskit' })
All of your hard work, shown this time in a Chrome browser.
20. Thanks for listening!
Learn more
● Check out the flutter_animate package
● Review the Flutter support for Fragment Shaders documentation
● The Book of Shaders by Patricio Gonzalez Vivo and Jen Lowe
● Shader toy, a collaborative shader playground
● simple_shader, a simple Flutter fragment shaders sample project
Next Gen UIs Codelab
● https://codelabs.developers.google.com/codelabs/flutter-next-gen-uis
Notes de l'éditeur
In this step you place all of the background art assets on the screen in layers. Expect it to appear oddly monochrome at first, but you add colors to the scene at the end of this step.
HSLcolor: we decide how much we want to receive the light and how much we want to emit
In this step you place a user interface over the scene created in the previous step. This includes the title, the difficulty-selector buttons, and the all-important Start button.
In this step you animate the user interface and the color transitions for the art assets.
In this step you add fragment shaders to the app. First, you use a shader to modify the title to give it a more dystopian feel. Then, you add a second shader to create an orb that serves as the central focal point of the page.
In this step, you add particle animations to create a subtle pulsing movement to the app.
There is one slight problem with the code as it stands. When Flutter runs on the web, there are two alternate rendering engines that can be used: CanvasKit & HTML DOM