├── .gitignore
├── .metadata
├── README.md
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── toly1994
│ │ │ │ └── ianim
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable-v21
│ │ │ └── launch_background.xml
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── values-night
│ │ │ └── styles.xml
│ │ │ └── values
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── assets
├── font
│ └── CHOPS.TTF
└── images
│ ├── icon_8.jpg
│ ├── icon_head.jpg
│ ├── icon_head.png
│ └── wy_300x200.jpg
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
└── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-App-1024x1024@1x.png
│ │ ├── Icon-App-20x20@1x.png
│ │ ├── Icon-App-20x20@2x.png
│ │ ├── Icon-App-20x20@3x.png
│ │ ├── Icon-App-29x29@1x.png
│ │ ├── Icon-App-29x29@2x.png
│ │ ├── Icon-App-29x29@3x.png
│ │ ├── Icon-App-40x40@1x.png
│ │ ├── Icon-App-40x40@2x.png
│ │ ├── Icon-App-40x40@3x.png
│ │ ├── Icon-App-60x60@2x.png
│ │ ├── Icon-App-60x60@3x.png
│ │ ├── Icon-App-76x76@1x.png
│ │ ├── Icon-App-76x76@2x.png
│ │ └── Icon-App-83.5x83.5@2x.png
│ └── LaunchImage.imageset
│ │ ├── Contents.json
│ │ ├── LaunchImage.png
│ │ ├── LaunchImage@2x.png
│ │ ├── LaunchImage@3x.png
│ │ └── README.md
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ └── Runner-Bridging-Header.h
├── lib
├── 14
│ └── debug
│ │ ├── circle_anim.dart
│ │ └── main.dart
├── 01_text
│ ├── 01_color
│ │ ├── 01_static
│ │ │ ├── color_text.dart
│ │ │ └── main.dart
│ │ └── 02_anim
│ │ │ ├── color_text.dart
│ │ │ └── main.dart
│ ├── 02_skew_shadow
│ │ ├── 01_static
│ │ │ ├── main.dart
│ │ │ └── skew_show_text.dart
│ │ └── 02_anim
│ │ │ ├── main.dart
│ │ │ └── skew_show_text.dart
│ └── 03_typer
│ │ ├── 01_timer_test
│ │ └── timer_test.dart
│ │ └── 02_anim
│ │ ├── main.dart
│ │ └── text_typer.dart
├── 02
│ ├── 01_attr
│ │ ├── 01_value_duration
│ │ │ ├── circle_anim.dart
│ │ │ └── main.dart
│ │ └── 02_bound
│ │ │ ├── circle_anim.dart
│ │ │ └── main.dart
│ ├── 02_function
│ │ ├── 01_forward
│ │ │ ├── anim_painter.dart
│ │ │ ├── anim_panel.dart
│ │ │ ├── main.dart
│ │ │ └── point_data.dart
│ │ ├── 02_reverse
│ │ │ ├── anim_painter.dart
│ │ │ ├── anim_panel.dart
│ │ │ ├── main.dart
│ │ │ └── point_data.dart
│ │ ├── 03_repeat
│ │ │ ├── anim_painter.dart
│ │ │ ├── anim_panel.dart
│ │ │ ├── main.dart
│ │ │ └── point_data.dart
│ │ ├── 04_stop
│ │ │ ├── anim_painter.dart
│ │ │ ├── anim_panel.dart
│ │ │ ├── main.dart
│ │ │ └── point_data.dart
│ │ ├── 05_fling
│ │ │ ├── anim_painter.dart
│ │ │ ├── anim_panel.dart
│ │ │ ├── main.dart
│ │ │ └── point_data.dart
│ │ └── 06_fling_spring
│ │ │ ├── anim_painter.dart
│ │ │ ├── anim_panel.dart
│ │ │ ├── main.dart
│ │ │ ├── point_data.dart
│ │ │ └── spring_painter.dart
│ └── 03_status
│ │ ├── anim_painter.dart
│ │ ├── anim_panel.dart
│ │ ├── main.dart
│ │ └── point_data.dart
├── 03_curve
│ ├── 01
│ │ ├── anim_painter.dart
│ │ ├── anim_panel.dart
│ │ ├── main.dart
│ │ └── point_data.dart
│ ├── 02
│ │ ├── anim_painter.dart
│ │ ├── anim_panel.dart
│ │ ├── main.dart
│ │ └── point_data.dart
│ ├── 03
│ │ ├── anim_painter.dart
│ │ ├── anim_panel.dart
│ │ ├── main.dart
│ │ └── point_data.dart
│ └── 04
│ │ ├── anim_painter.dart
│ │ ├── anim_panel.dart
│ │ ├── main.dart
│ │ ├── point_data.dart
│ │ └── toly_curve.dart
├── 04_tween
│ ├── 01_color
│ │ ├── circle_anim.dart
│ │ └── main.dart
│ ├── 02_color_tween
│ │ ├── circle_anim.dart
│ │ └── main.dart
│ ├── 03_tween_evaluate
│ │ ├── circle_anim.dart
│ │ └── main.dart
│ ├── 04_animate
│ │ ├── circle_anim.dart
│ │ └── main.dart
│ ├── 05_curve_tween
│ │ ├── anim_painter.dart
│ │ ├── anim_panel.dart
│ │ ├── main.dart
│ │ └── point_data.dart
│ ├── 06_tween_sequence
│ │ ├── anim_painter.dart
│ │ ├── anim_panel.dart
│ │ ├── main.dart
│ │ └── point_data.dart
│ ├── 07_text_style_tween
│ │ ├── circle.dart
│ │ ├── circle_anim.dart
│ │ └── main.dart
│ └── 08_circle_color_tween
│ │ ├── circle.dart
│ │ ├── circle_anim.dart
│ │ └── main.dart
├── 05_simple
│ ├── 01_shine_static
│ │ ├── circle_shine_image.dart
│ │ └── main.dart
│ ├── 02_shine_anim
│ │ ├── circle_shine_image.dart
│ │ └── main.dart
│ ├── 03_toggle_rotate
│ │ ├── main.dart
│ │ └── toggle_rotate.dart
│ ├── 04_compare
│ │ ├── main.dart
│ │ └── toggle_rotate.dart
│ ├── 05_burst_static
│ │ ├── burst_menu.dart
│ │ └── main.dart
│ ├── 06_burst_static_angle
│ │ ├── burst_menu.dart
│ │ └── main.dart
│ ├── 07_burst_anim_01
│ │ ├── burst_menu.dart
│ │ └── main.dart
│ └── 08_burst_anim_last
│ │ ├── burst_menu.dart
│ │ └── main.dart
├── 06_loading
│ ├── 01_halo_circle
│ │ ├── 01_circle_static
│ │ │ ├── circle_halo.dart
│ │ │ └── main.dart
│ │ ├── 02_light_static
│ │ │ ├── circle_halo.dart
│ │ │ └── main.dart
│ │ ├── 03_circle_anim
│ │ │ ├── circle_halo.dart
│ │ │ └── main.dart
│ │ ├── 04_light_anim
│ │ │ ├── circle_halo.dart
│ │ │ └── main.dart
│ │ └── 05_circle_halo_last
│ │ │ ├── circle_halo.dart
│ │ │ └── main.dart
│ ├── 02_rotate
│ │ ├── 01_static
│ │ │ ├── main.dart
│ │ │ └── rotate_loading.dart
│ │ ├── 02_anim_01
│ │ │ ├── main.dart
│ │ │ └── rotate_loading.dart
│ │ └── 03_anim_last
│ │ │ ├── main.dart
│ │ │ └── rotate_loading.dart
│ ├── 03_cross
│ │ ├── 01_cross_single
│ │ │ ├── cross_loading.dart
│ │ │ └── main.dart
│ │ ├── 02_cross_static
│ │ │ ├── cross_loading.dart
│ │ │ └── main.dart
│ │ └── 03_cross_anim
│ │ │ ├── cross_loading.dart
│ │ │ └── main.dart
│ └── 04_ovel
│ │ ├── 01_oval_single
│ │ ├── main.dart
│ │ └── oval_loading.dart
│ │ ├── 02_sin_single
│ │ ├── main.dart
│ │ └── oval_loading.dart
│ │ └── 03_oval_last
│ │ ├── main.dart
│ │ └── oval_loading.dart
├── 07_animated_widget
│ ├── 01_RotationTransition
│ │ └── main.dart
│ ├── 02_ScaleTransition
│ │ └── main.dart
│ ├── 03_SlideTransition
│ │ └── main.dart
│ ├── 04_AlignTransition
│ │ └── main.dart
│ └── 05_DecoratedBoxTransition
│ │ └── main.dart
├── 09_implicitly_animated_widget
│ ├── 01_AnimatedOpacity
│ │ └── main.dart
│ ├── 02_AnimatedDefaultTextStyle
│ │ └── main.dart
│ ├── 03_AnimatedAlign
│ │ └── main.dart
│ ├── 04_AnimatedContainer
│ │ └── main.dart
│ └── 05_TweenAnimationBuilder
│ │ └── main.dart
├── 10_implicitly_debug
│ └── main.dart
├── 11_other
│ ├── 01_painter
│ │ ├── 01_AnimatedIcon
│ │ │ └── main.dart
│ │ └── 02_CupertinoActivityIndicator
│ │ │ └── main.dart
│ ├── 02_other
│ │ ├── 01_AnimatedCrossFade
│ │ │ └── main.dart
│ │ └── 02_AnimatedSwitcher
│ │ │ └── main.dart
│ └── 04_router
│ │ ├── 01_common
│ │ └── main.dart
│ │ └── 02_anim
│ │ └── main.dart
├── 15_ticker
│ ├── ticker
│ │ ├── main.dart
│ │ └── ticker_demo.dart
│ ├── ticker_muted
│ │ ├── main.dart
│ │ └── ticker_demo.dart
│ └── ticker_provider
│ │ ├── main.dart
│ │ └── ticker_demo.dart
└── 16_clock
│ ├── 01
│ ├── clock_widget.dart
│ └── main.dart
│ ├── 02
│ ├── clock_widget.dart
│ └── main.dart
│ ├── 03
│ ├── clock_widget.dart
│ └── main.dart
│ ├── 04_stack
│ ├── clock_widget.dart
│ └── main.dart
│ ├── 05_last
│ ├── clock_widget.dart
│ └── main.dart
│ └── 06_lizi
│ ├── 01
│ ├── clock_fx.dart
│ ├── clock_widget.dart
│ ├── main.dart
│ ├── particle.dart
│ ├── particle_clock_fx.dart
│ └── utils
│ │ └── rnd.dart
│ ├── 02
│ ├── clock_fx.dart
│ ├── clock_widget.dart
│ ├── main.dart
│ ├── particle.dart
│ └── utils
│ │ └── rnd.dart
│ ├── 03
│ ├── clock_fx.dart
│ ├── clock_widget.dart
│ ├── main.dart
│ ├── particle.dart
│ └── utils
│ │ └── rnd.dart
│ └── 04
│ ├── clock_fx.dart
│ ├── clock_widget.dart
│ ├── main.dart
│ ├── particle.dart
│ └── utils
│ └── rnd.dart
├── pubspec.lock
└── pubspec.yaml
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | **/ios/Flutter/.last_build_id
26 | .dart_tool/
27 | .flutter-plugins
28 | .flutter-plugins-dependencies
29 | .packages
30 | .pub-cache/
31 | .pub/
32 | /build/
33 |
34 | # Web related
35 | lib/generated_plugin_registrant.dart
36 |
37 | # Symbolication related
38 | app.*.symbols
39 |
40 | # Obfuscation related
41 | app.*.map.json
42 |
43 | # Android Studio will place build artifacts here
44 | /android/app/debug
45 | /android/app/profile
46 | /android/app/release
47 |
--------------------------------------------------------------------------------
/.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: 1d9032c7e1d867f071f2277eb1673e8f9b0274e3
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ianim
2 |
3 | A new Flutter application.
4 |
5 | ## Getting Started
6 |
7 | This project is a starting point for a Flutter application.
8 |
9 | A few resources to get you started if this is your first Flutter project:
10 |
11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
13 |
14 | For help getting started with Flutter, view our
15 | [online documentation](https://flutter.dev/docs), which offers tutorials,
16 | samples, guidance on mobile development, and a full API reference.
17 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | android {
29 | compileSdkVersion 30
30 |
31 | sourceSets {
32 | main.java.srcDirs += 'src/main/kotlin'
33 | }
34 |
35 | defaultConfig {
36 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
37 | applicationId "com.toly1994.ianim"
38 | minSdkVersion 16
39 | targetSdkVersion 30
40 | versionCode flutterVersionCode.toInteger()
41 | versionName flutterVersionName
42 | }
43 |
44 | buildTypes {
45 | release {
46 | // TODO: Add your own signing config for the release build.
47 | // Signing with the debug keys for now, so `flutter run --release` works.
48 | signingConfig signingConfigs.debug
49 | }
50 | }
51 | }
52 |
53 | flutter {
54 | source '../..'
55 | }
56 |
57 | dependencies {
58 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
59 | }
60 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
13 |
17 |
21 |
26 |
30 |
31 |
32 |
33 |
34 |
35 |
37 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/toly1994/ianim/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.toly1994.ianim
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.3.50'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:4.1.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | jcenter()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | }
25 | subprojects {
26 | project.evaluationDependsOn(':app')
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
7 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
4 | def properties = new Properties()
5 |
6 | assert localPropertiesFile.exists()
7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
8 |
9 | def flutterSdkPath = properties.getProperty("flutter.sdk")
10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
12 |
--------------------------------------------------------------------------------
/assets/font/CHOPS.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/assets/font/CHOPS.TTF
--------------------------------------------------------------------------------
/assets/images/icon_8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/assets/images/icon_8.jpg
--------------------------------------------------------------------------------
/assets/images/icon_head.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/assets/images/icon_head.jpg
--------------------------------------------------------------------------------
/assets/images/icon_head.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/assets/images/icon_head.png
--------------------------------------------------------------------------------
/assets/images/wy_300x200.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/assets/images/wy_300x200.jpg
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1v3
2 | *.mode2v3
3 | *.moved-aside
4 | *.pbxuser
5 | *.perspectivev3
6 | **/*sync/
7 | .sconsign.dblite
8 | .tags*
9 | **/.vagrant/
10 | **/DerivedData/
11 | Icon?
12 | **/Pods/
13 | **/.symlinks/
14 | profile
15 | xcuserdata
16 | **/.generated/
17 | Flutter/App.framework
18 | Flutter/Flutter.framework
19 | Flutter/Flutter.podspec
20 | Flutter/Generated.xcconfig
21 | Flutter/app.flx
22 | Flutter/app.zip
23 | Flutter/flutter_assets/
24 | Flutter/flutter_export_environment.sh
25 | ServiceDefinitions.json
26 | Runner/GeneratedPluginRegistrant.*
27 |
28 | # Exceptions to above rules.
29 | !default.mode1v3
30 | !default.mode2v3
31 | !default.pbxuser
32 | !default.perspectivev3
33 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toly1994328/ianim/6a0ae1a16cda233c0df19191da5c3d8721381a30/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ianim
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/lib/01_text/01_color/01_static/color_text.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 | import 'dart:ui' as ui;
3 |
4 | import 'package:flutter/material.dart';
5 |
6 | class AnimText extends StatelessWidget {
7 | final String text = "张风捷特烈";
8 |
9 | final List colors = [
10 | Color(0xFFF60C0C),
11 | Color(0xFFF3B913),
12 | Color(0xFFE7F716),
13 | Color(0xFF3DF30B),
14 | Color(0xFF0DF6EF),
15 | Color(0xFF0829FB),
16 | Color(0xFFB709F4),
17 | ];
18 |
19 | final List pos = [
20 | 1.0 / 7, 2.0 / 7, 3.0 / 7,
21 | 4.0 / 7, 5.0 / 7, 6.0 / 7, 1.0 ];
22 |
23 | Paint getPaint() {
24 | Paint paint = Paint();
25 | paint
26 | ..style = PaintingStyle.stroke
27 | ..strokeWidth = 2;
28 | paint.shader = ui.Gradient.linear(
29 | const Offset(0, 0),
30 | const Offset(100, 0),
31 | colors,
32 | pos,
33 | TileMode.mirror,
34 | Matrix4.rotationZ(pi / 6).storage,
35 | );
36 | paint.maskFilter = MaskFilter.blur(BlurStyle.solid, 10);
37 | return paint;
38 | }
39 |
40 | @override
41 | Widget build(BuildContext context) {
42 | return Text(
43 | text,
44 | style: TextStyle(fontSize: 60, foreground: getPaint()),
45 | );
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/lib/01_text/01_color/01_static/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'color_text.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: AnimText(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/01_text/01_color/02_anim/color_text.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 | import 'dart:ui' as ui;
3 |
4 | import 'package:flutter/material.dart';
5 |
6 | class AnimText extends StatefulWidget {
7 | @override
8 | _AnimTextState createState() => _AnimTextState();
9 | }
10 |
11 | class _AnimTextState extends State
12 | with SingleTickerProviderStateMixin {
13 |
14 | // 1.混入 mixin
15 | // 1. 声明动画器对象
16 | AnimationController _ctrl;
17 |
18 | final Duration animDuration = const Duration(milliseconds: 1000); // 动画时长
19 |
20 | @override
21 | void initState() {
22 | super.initState();
23 | // 1. 声明动画器对象
24 | _ctrl = AnimationController(vsync: this, duration: animDuration);
25 | }
26 |
27 | final List colors = [
28 | Color(0xFFF60C0C),
29 | Color(0xFFF3B913),
30 | Color(0xFFE7F716),
31 | Color(0xFF3DF30B),
32 | Color(0xFF0DF6EF),
33 | Color(0xFF0829FB),
34 | Color(0xFFB709F4),
35 | ];
36 |
37 | final List pos = [
38 | 1.0 / 7,
39 | 2.0 / 7,
40 | 3.0 / 7,
41 | 4.0 / 7,
42 | 5.0 / 7,
43 | 6.0 / 7,
44 | 1.0
45 | ];
46 |
47 | Paint getPaint() {
48 | Paint paint = Paint()
49 | ..style = PaintingStyle.stroke
50 | ..strokeWidth = 2;
51 | paint.shader = ui.Gradient.linear(
52 | const Offset(0, 0),
53 | const Offset(100, 0),
54 | colors,
55 | pos,
56 | TileMode.mirror,
57 | Matrix4.rotationZ(pi / 6).storage,
58 | );
59 | paint.maskFilter = MaskFilter.blur(BlurStyle.solid, 15 * _ctrl.value);
60 | return paint;
61 | }
62 |
63 |
64 |
65 | @override
66 | void dispose() {
67 | // 2. 销毁动画器
68 | _ctrl.dispose();
69 | super.dispose();
70 | }
71 |
72 | @override
73 | Widget build(BuildContext context) {
74 | return GestureDetector(
75 | onTap: _startAnim,
76 | child: AnimatedBuilder( // 4.通过 AnimatedBuilder 监听动画器构建组件
77 | animation: _ctrl,
78 | builder: _buildByAnim,
79 | ),
80 | );
81 | }
82 |
83 | Widget _buildByAnim(BuildContext context, Widget child) {
84 | return Text(
85 | "张风捷特烈",
86 | style: TextStyle(fontSize: 60, foreground: getPaint()),
87 | );
88 | }
89 |
90 | void _startAnim() {
91 | // 3. 启动动画器
92 | _ctrl.forward(from: 0);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/lib/01_text/01_color/02_anim/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | import 'color_text.dart';
5 |
6 | void main() {
7 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
8 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
9 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
10 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
11 | runApp(MyApp());
12 | }
13 |
14 | class MyApp extends StatelessWidget {
15 | @override
16 | Widget build(BuildContext context) {
17 | return MaterialApp(
18 | debugShowCheckedModeBanner: false,
19 | title: 'Flutter Demo',
20 | theme: ThemeData(
21 | primarySwatch: Colors.blue,
22 | ),
23 | home: Scaffold(
24 | body: Center(
25 | // Center is a layout widget. It takes a single child and positions it
26 | // in the middle of the parent.
27 | child: AnimText(),
28 | )));
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/01_text/02_skew_shadow/01_static/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | import 'skew_show_text.dart';
5 |
6 | void main() {
7 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
8 | SystemChrome.setPreferredOrientations(// 使设备横屏显示
9 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
10 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
11 | runApp(MyApp());
12 | }
13 |
14 | class MyApp extends StatelessWidget {
15 | @override
16 | Widget build(BuildContext context) {
17 | return MaterialApp(
18 | title: 'Flutter Demo',
19 | debugShowCheckedModeBanner: false,
20 | theme: ThemeData(
21 | primarySwatch: Colors.blue,
22 | ),
23 | home: Scaffold(
24 | body: Center(
25 | child: SkewShadowText(),
26 | )));
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/01_text/02_skew_shadow/01_static/skew_show_text.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | class SkewShadowText extends StatelessWidget{
6 |
7 | final TextStyle commonStyle = TextStyle(fontSize: 60, color: Colors.blue);
8 | final TextStyle shadowStyle = TextStyle(fontSize: 60, color: Colors.blue.withAlpha(88));
9 | final String text = '张风捷特烈';
10 | @override
11 | Widget build(BuildContext context) {
12 | Matrix4 matrix4 = Matrix4.skewX(4*pi/180);
13 | return Stack(
14 | children: [
15 | Text(
16 | text,
17 | style: commonStyle,
18 | ),
19 | Transform(
20 | transform: matrix4,
21 | child: Text(
22 | text,
23 | style: shadowStyle,
24 | ),
25 | ),
26 | ],
27 | );
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lib/01_text/02_skew_shadow/02_anim/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'skew_show_text.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: SkewShadowText(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/01_text/02_skew_shadow/02_anim/skew_show_text.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | class SkewShadowText extends StatefulWidget {
6 | @override
7 | _SkewShadowTextState createState() => _SkewShadowTextState();
8 | }
9 |
10 | class _SkewShadowTextState extends State
11 | with SingleTickerProviderStateMixin {
12 | AnimationController _ctrl;
13 |
14 | final Duration animDuration = const Duration(milliseconds: 800);
15 |
16 | final TextStyle commonStyle = TextStyle(fontSize: 60, color: Colors.blue);
17 | final TextStyle shadowStyle =
18 | TextStyle(fontSize: 60, color: Colors.blue.withAlpha(88));
19 | String text = "张风捷特烈";
20 |
21 |
22 | @override
23 | void initState() {
24 | super.initState();
25 | _ctrl = AnimationController(vsync: this, duration: animDuration);
26 | }
27 |
28 | @override
29 | void dispose() {
30 | _ctrl.dispose();
31 | super.dispose();
32 | }
33 |
34 | @override
35 | Widget build(BuildContext context) {
36 | return GestureDetector(
37 | onTap: _startAnim,
38 | child: Stack(
39 | children: [
40 | Text(text, style: commonStyle,),
41 | AnimatedBuilder(
42 | animation: _ctrl,
43 | builder: _buildByAnim,
44 | ),
45 | ],
46 | ));
47 | }
48 |
49 | double get rad => 6 * (_ctrl.value) / 180 * pi;
50 |
51 | Widget _buildByAnim(_, __) => Transform(
52 | transform: Matrix4.skewX(rad),
53 | child: Text(
54 | text,
55 | style: shadowStyle,
56 | ),
57 | );
58 |
59 | void _startAnim() {
60 | _ctrl.forward(from: 0);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/lib/01_text/03_typer/01_timer_test/timer_test.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | int count = 0;
4 |
5 | main() {
6 | Timer.periodic(Duration(seconds: 1), _callback);
7 | }
8 |
9 | void _callback(Timer timer) {
10 | count++;
11 | print("------${DateTime.now().toIso8601String()}---------");
12 | if (count >= 10) {
13 | timer.cancel();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/lib/01_text/03_typer/02_anim/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | import 'text_typer.dart';
5 |
6 | void main() {
7 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
8 | SystemChrome.setPreferredOrientations(// 使设备横屏显示
9 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
10 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
11 | runApp(MyApp());
12 | }
13 |
14 | class MyApp extends StatelessWidget {
15 | @override
16 | Widget build(BuildContext context) {
17 | return MaterialApp(
18 | debugShowCheckedModeBanner: false,
19 | title: 'Flutter Demo',
20 | theme: ThemeData(
21 | primarySwatch: Colors.blue,
22 | ),
23 | home: Scaffold(
24 | body: Center(
25 | child: TextTyper(),
26 | )));
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/01_text/03_typer/02_anim/text_typer.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | class TextTyper extends StatefulWidget {
6 | @override
7 | _TextTyperState createState() => _TextTyperState();
8 | }
9 |
10 | class _TextTyperState extends State {
11 |
12 | final Duration animDuration = const Duration(milliseconds: 200);
13 |
14 | final String text = '桃树、杏树、梨树,你不让我,我不让你,都开满了花赶趟儿。'
15 | '红的像火,粉的像霞,白的像雪。花里带着甜味,闭了眼,'
16 | '树上仿佛已经满是桃儿、杏儿、梨儿。';
17 |
18 | final ValueNotifier data = ValueNotifier("");
19 |
20 | Timer _timer;
21 |
22 | @override
23 | void initState() {
24 | super.initState();
25 | _startAnim();
26 | }
27 |
28 | int currentIndex = 0;
29 |
30 | String get currentText =>text.substring(0,currentIndex);
31 |
32 | void _type(Timer timer) {
33 | if (currentIndex < text.length) {
34 | currentIndex++;
35 | data.value= currentText;
36 | }else{
37 | _timer?.cancel();
38 | _timer=null;
39 | }
40 | }
41 |
42 | @override
43 | void dispose() {
44 | _timer?.cancel();
45 | data.dispose();
46 | super.dispose();
47 | }
48 |
49 | @override
50 | Widget build(BuildContext context) {
51 | return GestureDetector(
52 | onTap: _startAnim,
53 | child: SizedBox(
54 | width: 300,
55 | child: AnimatedBuilder(
56 | animation: data,
57 | builder: _buildByAnim,
58 | ),
59 | ),
60 | );
61 | }
62 |
63 | Widget _buildByAnim(_, __) => Text(
64 | data.value,
65 | style: const TextStyle(color: Colors.blue),
66 | );
67 |
68 | void _startAnim() {
69 | _timer?.cancel();
70 | data.value = '';
71 | currentIndex = 0;
72 | _timer = Timer.periodic(animDuration, _type);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/lib/02/01_attr/01_value_duration/circle_anim.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class CircleAnim extends StatefulWidget {
4 | @override
5 | _CircleAnimState createState() => _CircleAnimState();
6 | }
7 |
8 | class _CircleAnimState extends State
9 | with SingleTickerProviderStateMixin {
10 | AnimationController _ctrl;
11 |
12 | final Duration animDuration = const Duration(milliseconds:2000);
13 |
14 | @override
15 | void initState() {
16 | super.initState();
17 | _ctrl = AnimationController(
18 | value: 0.4,
19 | vsync: this,
20 | duration: animDuration,
21 | );
22 | }
23 |
24 | @override
25 | void dispose() {
26 | _ctrl.dispose();
27 | super.dispose();
28 | }
29 |
30 | @override
31 | Widget build(BuildContext context) {
32 | return GestureDetector(
33 | onTap: _startAnim,
34 | child: AnimatedBuilder(
35 | animation: _ctrl,
36 | builder: _buildByAnim,
37 | ));
38 | }
39 |
40 | double get radius => 80*_ctrl.value ;
41 |
42 | Widget _buildByAnim(_, __) => Container(
43 | width: radius * 2,
44 | height: radius * 2,
45 | decoration:
46 | BoxDecoration(color: Colors.blue, shape: BoxShape.circle),
47 | );
48 |
49 | void _startAnim() {
50 | _ctrl.forward();
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/lib/02/01_attr/01_value_duration/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'circle_anim.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: CircleAnim(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/02/01_attr/02_bound/circle_anim.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class CircleAnim extends StatefulWidget {
4 | @override
5 | _CircleAnimState createState() => _CircleAnimState();
6 | }
7 |
8 | class _CircleAnimState extends State
9 | with SingleTickerProviderStateMixin {
10 | AnimationController _ctrl;
11 |
12 | final Duration animDuration = const Duration(milliseconds:1000);
13 |
14 | @override
15 | void initState() {
16 | super.initState();
17 | _ctrl = AnimationController(
18 | lowerBound: 32,
19 | upperBound: 80,
20 | vsync: this,
21 | duration: animDuration,
22 | );
23 | }
24 |
25 | @override
26 | void dispose() {
27 | _ctrl.dispose();
28 | super.dispose();
29 | }
30 |
31 | @override
32 | Widget build(BuildContext context) {
33 | return GestureDetector(
34 | onTap: _startAnim,
35 | child: AnimatedBuilder(
36 | animation: _ctrl,
37 | builder: _buildByAnim,
38 | ));
39 | }
40 |
41 | double get radius => _ctrl.value ;
42 |
43 | Widget _buildByAnim(_, __) => Container(
44 | width: radius * 2,
45 | height: radius * 2,
46 | decoration:
47 | BoxDecoration(color: Colors.blue, shape: BoxShape.circle),
48 | );
49 |
50 | void _startAnim() {
51 | _ctrl.forward();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/lib/02/01_attr/02_bound/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'circle_anim.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: CircleAnim(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/02/02_function/01_forward/anim_panel.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | import 'anim_painter.dart';
6 | import 'point_data.dart';
7 |
8 | class AnimPanel extends StatefulWidget {
9 | @override
10 | _AnimPanelState createState() => _AnimPanelState();
11 | }
12 |
13 | class _AnimPanelState extends State
14 | with SingleTickerProviderStateMixin {
15 | PointData points = PointData();
16 |
17 | AnimationController _ctrl;
18 |
19 | final Duration animDuration = const Duration(milliseconds: 1000);
20 |
21 | // Animation curve;
22 |
23 | @override
24 | void initState() {
25 | super.initState();
26 | _ctrl = AnimationController(
27 | vsync: this,
28 | duration: animDuration,
29 | )..addListener(_collectPoint);
30 | // curve = CurvedAnimation(parent: _ctrl, curve: Curves.bounceOut);
31 | }
32 |
33 | @override
34 | void dispose() {
35 | _ctrl.dispose();
36 | points.dispose();
37 | super.dispose();
38 | }
39 |
40 | void _collectPoint() {
41 | points.push(_ctrl.value);
42 | }
43 |
44 | void _startAnim() async{
45 | points.clear();
46 | print('start!---${DateTime.now().toIso8601String()}----------');
47 | // await _ctrl.forward(from: 0);
48 | await _ctrl.forward(from: 0.4);
49 | print('done!---${DateTime.now().toIso8601String()}----------');
50 | }
51 |
52 | @override
53 | Widget build(BuildContext context) {
54 | return GestureDetector(
55 | onTap: _startAnim,
56 | child: CustomPaint(
57 | painter: AnimPainter(points),
58 | size: const Size(
59 | 200,
60 | 200,
61 | ),
62 | ),
63 | );
64 | }
65 | }
66 |
67 |
68 |
--------------------------------------------------------------------------------
/lib/02/02_function/01_forward/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'anim_panel.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: AnimPanel(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/02/02_function/01_forward/point_data.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 |
3 | class PointData extends ChangeNotifier {
4 | final List values = [];
5 |
6 | void push(double value) {
7 | values.add(value);
8 | notifyListeners();
9 | }
10 |
11 |
12 | void clear() {
13 | values.clear();
14 | notifyListeners();
15 | }
16 | }
--------------------------------------------------------------------------------
/lib/02/02_function/02_reverse/anim_panel.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | import 'anim_painter.dart';
6 | import 'point_data.dart';
7 |
8 | class AnimPanel extends StatefulWidget {
9 | @override
10 | _AnimPanelState createState() => _AnimPanelState();
11 | }
12 |
13 | class _AnimPanelState extends State
14 | with SingleTickerProviderStateMixin {
15 |
16 | PointData points = PointData();
17 | AnimationController _ctrl;
18 | final Duration animDuration = const Duration(milliseconds: 1000);
19 |
20 | @override
21 | void initState() {
22 | super.initState();
23 | _ctrl = AnimationController(
24 | vsync: this,
25 | duration: animDuration,
26 | )..addListener(_collectPoint);
27 | // curve = CurvedAnimation(parent: _ctrl, curve: Curves.bounceOut);
28 | }
29 |
30 | @override
31 | void dispose() {
32 | _ctrl.dispose();
33 | points.dispose();
34 | super.dispose();
35 | }
36 |
37 | void _collectPoint() {
38 | points.push(_ctrl.value);
39 | }
40 |
41 | void _startAnim() async{
42 | points.clear();
43 | print('start!---${DateTime.now().toIso8601String()}----------');
44 | await _ctrl.reverse(from: 1);
45 | print('done!---${DateTime.now().toIso8601String()}----------');
46 | }
47 |
48 | @override
49 | Widget build(BuildContext context) {
50 | return GestureDetector(
51 | onTap: _startAnim,
52 | child: CustomPaint(
53 | painter: AnimPainter(points),
54 | size: const Size(
55 | 200,
56 | 200,
57 | ),
58 | ),
59 | );
60 | }
61 | }
62 |
63 |
64 |
--------------------------------------------------------------------------------
/lib/02/02_function/02_reverse/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'anim_panel.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: AnimPanel(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/02/02_function/02_reverse/point_data.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 |
3 | class PointData extends ChangeNotifier {
4 | final List values = [];
5 |
6 | void push(double value) {
7 | values.add(value);
8 | notifyListeners();
9 | }
10 |
11 |
12 | void clear() {
13 | values.clear();
14 | notifyListeners();
15 | }
16 | }
--------------------------------------------------------------------------------
/lib/02/02_function/03_repeat/anim_panel.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:ui';
3 |
4 | import 'package:flutter/material.dart';
5 |
6 | import 'anim_painter.dart';
7 | import 'point_data.dart';
8 |
9 | class AnimPanel extends StatefulWidget {
10 | @override
11 | _AnimPanelState createState() => _AnimPanelState();
12 | }
13 |
14 | class _AnimPanelState extends State
15 | with SingleTickerProviderStateMixin {
16 |
17 | PointData points = PointData();
18 | AnimationController _ctrl;
19 | final Duration animDuration = const Duration(milliseconds: 1000);
20 |
21 | @override
22 | void initState() {
23 | super.initState();
24 | _ctrl = AnimationController(
25 | vsync: this,
26 | duration: animDuration,
27 | )..addListener(_collectPoint)..addStatusListener(_listenStatus);
28 | // curve = CurvedAnimation(parent: _ctrl, curve: Curves.bounceOut);
29 | }
30 |
31 | @override
32 | void dispose() {
33 | _ctrl.dispose();
34 | points.dispose();
35 | super.dispose();
36 | }
37 |
38 | void _collectPoint() {
39 | points.push(_ctrl.value);
40 | }
41 |
42 | void _listenStatus(AnimationStatus status){
43 | // print(status);
44 | // if(status == AnimationStatus.reverse){
45 | // points.clear();
46 | // }
47 | }
48 |
49 | void _startAnim() async{
50 | points.clear();
51 | Timer(Duration(seconds: 4),_stop);
52 | print('start!---${DateTime.now().toIso8601String()}----------');
53 | await _ctrl.repeat(reverse: true);
54 | print('done!---${DateTime.now().toIso8601String()}----------');
55 |
56 | }
57 |
58 | @override
59 | Widget build(BuildContext context) {
60 | return GestureDetector(
61 | onTap: _startAnim,
62 | child: CustomPaint(
63 | painter: AnimPainter(points),
64 | size: const Size(
65 | 600,
66 | 200,
67 | ),
68 | ),
69 | );
70 | }
71 |
72 | void _stop() {
73 | _ctrl.stop();
74 | }
75 | }
76 |
77 |
78 |
--------------------------------------------------------------------------------
/lib/02/02_function/03_repeat/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'anim_panel.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: AnimPanel(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/02/02_function/03_repeat/point_data.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 |
3 | class PointData extends ChangeNotifier {
4 | final List values = [];
5 |
6 | void push(double value) {
7 | values.add(value);
8 | notifyListeners();
9 | }
10 |
11 |
12 | void clear() {
13 | values.clear();
14 | notifyListeners();
15 | }
16 | }
--------------------------------------------------------------------------------
/lib/02/02_function/04_stop/anim_panel.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:ui';
3 |
4 | import 'package:flutter/material.dart';
5 |
6 | import 'anim_painter.dart';
7 | import 'point_data.dart';
8 |
9 | class AnimPanel extends StatefulWidget {
10 | @override
11 | _AnimPanelState createState() => _AnimPanelState();
12 | }
13 |
14 | class _AnimPanelState extends State
15 | with SingleTickerProviderStateMixin {
16 |
17 | PointData points = PointData();
18 | AnimationController _ctrl;
19 | final Duration animDuration = const Duration(milliseconds: 1000);
20 |
21 | @override
22 | void initState() {
23 | super.initState();
24 | _ctrl = AnimationController(
25 | vsync: this,
26 | duration: animDuration,
27 | )..addListener(_collectPoint)..addStatusListener(_listenStatus);
28 | // curve = CurvedAnimation(parent: _ctrl, curve: Curves.bounceOut);
29 | }
30 |
31 | @override
32 | void dispose() {
33 | _ctrl.dispose();
34 | points.dispose();
35 | super.dispose();
36 | }
37 |
38 | void _collectPoint() {
39 | points.push(_ctrl.value);
40 | }
41 |
42 | void _listenStatus(AnimationStatus status){
43 | // print(status);
44 | // if(status == AnimationStatus.reverse){
45 | // points.clear();
46 | // }
47 | }
48 |
49 | void _startAnim() async{
50 | points.clear();
51 | Timer(Duration(milliseconds: 1500),_stop);
52 | print('start!---${DateTime.now().toIso8601String()}----------');
53 | _ctrl.repeat(reverse: true).orCancel.then((v) {
54 | print('cancel!---${DateTime.now().toIso8601String()}----------');
55 | },onError: (e){
56 | print('cancel!---$e----------');
57 | });
58 | }
59 |
60 | @override
61 | Widget build(BuildContext context) {
62 | return GestureDetector(
63 | onTap: _startAnim,
64 | onDoubleTap: _restartAnim,
65 | child: CustomPaint(
66 | painter: AnimPainter(points),
67 | size: const Size(
68 | 400,
69 | 200,
70 | ),
71 | ),
72 | );
73 | }
74 |
75 | void _stop() {
76 | _ctrl.stop(canceled: true);
77 | }
78 |
79 | void _restartAnim() {
80 | _ctrl.reverse();
81 | }
82 | }
83 |
84 |
85 |
--------------------------------------------------------------------------------
/lib/02/02_function/04_stop/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'anim_panel.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: AnimPanel(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/02/02_function/04_stop/point_data.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 |
3 | class PointData extends ChangeNotifier {
4 | final List values = [];
5 |
6 | void push(double value) {
7 | values.add(value);
8 | notifyListeners();
9 | }
10 |
11 |
12 | void clear() {
13 | values.clear();
14 | notifyListeners();
15 | }
16 | }
--------------------------------------------------------------------------------
/lib/02/02_function/05_fling/anim_panel.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:ui';
3 |
4 | import 'package:flutter/material.dart';
5 | import 'package:flutter/physics.dart';
6 |
7 | import 'anim_painter.dart';
8 | import 'point_data.dart';
9 |
10 | class AnimPanel extends StatefulWidget {
11 | @override
12 | _AnimPanelState createState() => _AnimPanelState();
13 | }
14 |
15 | class _AnimPanelState extends State
16 | with SingleTickerProviderStateMixin {
17 |
18 | PointData points = PointData();
19 | AnimationController _ctrl;
20 | final Duration animDuration = const Duration(milliseconds: 1000);
21 |
22 | @override
23 | void initState() {
24 | super.initState();
25 | _ctrl = AnimationController(
26 | vsync: this,
27 | duration: animDuration,
28 | )..addListener(_collectPoint);
29 | // curve = CurvedAnimation(parent: _ctrl, curve: Curves.bounceOut);
30 | }
31 |
32 | @override
33 | void dispose() {
34 | _ctrl.dispose();
35 | points.dispose();
36 | super.dispose();
37 | }
38 |
39 | void _collectPoint() {
40 | points.push(_ctrl.value);
41 | }
42 |
43 |
44 | void _startAnim() async{
45 | points.clear();
46 | _ctrl.reset();
47 | print('fling start!---${DateTime.now().toIso8601String()}----------');
48 | await _ctrl.fling(
49 | velocity: 10,
50 | springDescription: SpringDescription.withDampingRatio(
51 | mass: 1.0,
52 | stiffness: 500.0,
53 | ratio: 3.0,
54 | )
55 | );
56 | print('fling end!---${DateTime.now().toIso8601String()}----------');
57 |
58 | }
59 |
60 | @override
61 | Widget build(BuildContext context) {
62 | return GestureDetector(
63 | onTap: _startAnim,
64 | child: CustomPaint(
65 | painter: AnimPainter(points),
66 | size: const Size(
67 | 200,
68 | 200,
69 | ),
70 | ),
71 | );
72 | }
73 | }
74 |
75 |
76 |
--------------------------------------------------------------------------------
/lib/02/02_function/05_fling/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'anim_panel.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: AnimPanel(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/02/02_function/05_fling/point_data.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 |
3 | class PointData extends ChangeNotifier {
4 | final List values = [];
5 |
6 | void push(double value) {
7 | values.add(value);
8 | notifyListeners();
9 | }
10 |
11 |
12 | void clear() {
13 | values.clear();
14 | notifyListeners();
15 | }
16 | }
--------------------------------------------------------------------------------
/lib/02/02_function/06_fling_spring/anim_panel.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:ui';
3 |
4 | import 'package:flutter/material.dart';
5 | import 'package:flutter/physics.dart';
6 | import 'package:ianim/02/02_function/06_fling_spring/spring_painter.dart';
7 |
8 | import 'anim_painter.dart';
9 | import 'point_data.dart';
10 |
11 | class AnimPanel extends StatefulWidget {
12 | @override
13 | _AnimPanelState createState() => _AnimPanelState();
14 | }
15 |
16 | class _AnimPanelState extends State
17 | with SingleTickerProviderStateMixin {
18 |
19 | PointData points = PointData();
20 | AnimationController _ctrl;
21 | final Duration animDuration = const Duration(milliseconds: 1000);
22 |
23 | @override
24 | void initState() {
25 | super.initState();
26 | _ctrl = AnimationController(
27 | vsync: this,
28 | duration: animDuration,
29 | upperBound: 100,
30 | lowerBound: 50
31 | )..addListener(_collectPoint);
32 | // curve = CurvedAnimation(parent: _ctrl, curve: Curves.bounceOut);
33 | }
34 |
35 | @override
36 | void dispose() {
37 | _ctrl.dispose();
38 | points.dispose();
39 | super.dispose();
40 | }
41 |
42 | void _collectPoint() {
43 | points.push(_ctrl.value);
44 | }
45 |
46 |
47 | void _startAnim() async{
48 | points.clear();
49 | _ctrl.reset();
50 | print('fling start!---${DateTime.now().toIso8601String()}----------');
51 | await _ctrl.fling(
52 | velocity: 10,
53 | springDescription: SpringDescription.withDampingRatio(
54 | mass: 1.0,
55 | stiffness: 1000.0,
56 | ratio: 3.0,
57 | )
58 | );
59 | print('fling end!---${DateTime.now().toIso8601String()}----------');
60 |
61 | }
62 |
63 | @override
64 | Widget build(BuildContext context) {
65 | return GestureDetector(
66 | onTap: _startAnim,
67 | child: Container(
68 | width: 200,
69 | height: 200,
70 | color: Colors.grey.withAlpha(11),
71 | child: CustomPaint(
72 | painter: SpringPainter(height: _ctrl)),
73 | ),
74 | );
75 | }
76 | }
77 |
78 |
79 |
--------------------------------------------------------------------------------
/lib/02/02_function/06_fling_spring/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'anim_panel.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: AnimPanel(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/02/02_function/06_fling_spring/point_data.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 |
3 | class PointData extends ChangeNotifier {
4 | final List values = [];
5 |
6 | void push(double value) {
7 | values.add(value);
8 | notifyListeners();
9 | }
10 |
11 |
12 | void clear() {
13 | values.clear();
14 | notifyListeners();
15 | }
16 | }
--------------------------------------------------------------------------------
/lib/02/02_function/06_fling_spring/spring_painter.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/foundation.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | const double _kSpringWidth = 30;
5 |
6 | class SpringPainter extends CustomPainter {
7 | final int count;
8 | final ValueListenable height;
9 |
10 | SpringPainter({this.count = 20, @required this.height}):super(repaint: height);
11 |
12 | Paint _paint = Paint()
13 | ..style = PaintingStyle.stroke
14 | ..strokeWidth = 1;
15 |
16 | @override
17 | void paint(Canvas canvas, Size size) {
18 | canvas.translate(size.width / 2+_kSpringWidth / 2, size.height);
19 | Path springPath = Path();
20 | springPath.relativeLineTo(-_kSpringWidth, 0);
21 | double space = height.value/(count+1);
22 |
23 | for (int i = 1; i < count; i++) {
24 | if (i % 2 == 1) {
25 | springPath.relativeLineTo(_kSpringWidth, -space);
26 | } else {
27 | springPath.relativeLineTo(-_kSpringWidth, -space);
28 | }
29 | }
30 |
31 | if(count.isOdd){
32 | springPath.relativeLineTo(_kSpringWidth, 0);
33 | }else{
34 | springPath.relativeLineTo(-_kSpringWidth, 0);
35 | }
36 |
37 | canvas.drawPath(springPath, _paint);
38 | }
39 |
40 | @override
41 | bool shouldRepaint(covariant SpringPainter oldDelegate) =>
42 | oldDelegate.count != count || oldDelegate.height != height;
43 | }
44 |
--------------------------------------------------------------------------------
/lib/02/03_status/anim_panel.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | import 'anim_painter.dart';
6 | import 'point_data.dart';
7 |
8 | class AnimPanel extends StatefulWidget {
9 | @override
10 | _AnimPanelState createState() => _AnimPanelState();
11 | }
12 |
13 | class _AnimPanelState extends State
14 | with SingleTickerProviderStateMixin {
15 | PointData points = PointData();
16 |
17 | AnimationController _ctrl;
18 |
19 | final Duration animDuration = const Duration(milliseconds: 1000);
20 |
21 | // Animation curve;
22 |
23 | @override
24 | void initState() {
25 | super.initState();
26 | _ctrl = AnimationController(
27 | vsync: this,
28 | duration: animDuration,
29 | )..addListener(_collectPoint)..addStatusListener(_listenStatus);
30 | // curve = CurvedAnimation(parent: _ctrl, curve: Curves.bounceOut);
31 | }
32 |
33 | void _listenStatus(AnimationStatus status) {
34 | print(status);
35 | }
36 |
37 | @override
38 | void dispose() {
39 | _ctrl.dispose();
40 | points.dispose();
41 | super.dispose();
42 | }
43 |
44 | void _collectPoint() {
45 | points.push(_ctrl.value);
46 | }
47 |
48 | void _startAnim() async{
49 | points.clear();
50 | print('start!---${DateTime.now().toIso8601String()}----------');
51 | // await _ctrl.forward();
52 | await _ctrl.reverse(from: 0.5);
53 | print('done!---${DateTime.now().toIso8601String()}----------');
54 | }
55 |
56 | @override
57 | Widget build(BuildContext context) {
58 | return GestureDetector(
59 | onTap: _startAnim,
60 | child: CustomPaint(
61 | painter: AnimPainter(points),
62 | size: const Size(
63 | 200,
64 | 200,
65 | ),
66 | ),
67 | );
68 | }
69 |
70 |
71 | }
72 |
73 |
74 |
--------------------------------------------------------------------------------
/lib/02/03_status/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'anim_panel.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: AnimPanel(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/02/03_status/point_data.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 |
3 | class PointData extends ChangeNotifier {
4 | final List values = [];
5 |
6 | void push(double value) {
7 | values.add(value);
8 | notifyListeners();
9 | }
10 |
11 |
12 | void clear() {
13 | values.clear();
14 | notifyListeners();
15 | }
16 | }
--------------------------------------------------------------------------------
/lib/03_curve/01/anim_panel.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | import 'anim_painter.dart';
6 | import 'point_data.dart';
7 |
8 | class AnimPanel extends StatefulWidget {
9 | @override
10 | _AnimPanelState createState() => _AnimPanelState();
11 | }
12 |
13 | class _AnimPanelState extends State
14 | with SingleTickerProviderStateMixin {
15 | PointData points = PointData();
16 |
17 | AnimationController _ctrl;
18 |
19 | final Duration animDuration = const Duration(milliseconds: 1000);
20 |
21 | Animation curveAnim;
22 |
23 | @override
24 | void initState() {
25 | super.initState();
26 | _ctrl = AnimationController(
27 | vsync: this,
28 | duration: animDuration,
29 | )..addListener(_collectPoint);
30 | curveAnim = CurvedAnimation(parent: _ctrl, curve: Curves.bounceOut);
31 | }
32 |
33 | @override
34 | void dispose() {
35 | _ctrl.dispose();
36 | points.dispose();
37 | super.dispose();
38 | }
39 |
40 | void _collectPoint() {
41 | points.push(curveAnim.value);
42 | }
43 |
44 | void _startAnim() async{
45 | points.clear();
46 | print('start!---${DateTime.now().toIso8601String()}----------');
47 | // await _ctrl.forward(from: 0);
48 | await _ctrl.forward(from: 0);
49 | print('done!---${DateTime.now().toIso8601String()}----------');
50 | }
51 |
52 | @override
53 | Widget build(BuildContext context) {
54 | return GestureDetector(
55 | onTap: _startAnim,
56 | child: CustomPaint(
57 | painter: AnimPainter(points),
58 | size: const Size(
59 | 200,
60 | 200,
61 | ),
62 | ),
63 | );
64 | }
65 | }
66 |
67 |
68 |
--------------------------------------------------------------------------------
/lib/03_curve/01/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'anim_panel.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: AnimPanel(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/03_curve/01/point_data.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 |
3 | class PointData extends ChangeNotifier {
4 | final List values = [];
5 |
6 | void push(double value) {
7 | values.add(value);
8 | notifyListeners();
9 | }
10 |
11 |
12 | void clear() {
13 | values.clear();
14 | notifyListeners();
15 | }
16 | }
--------------------------------------------------------------------------------
/lib/03_curve/02/anim_panel.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | import 'anim_painter.dart';
6 | import 'point_data.dart';
7 |
8 | class AnimPanel extends StatefulWidget {
9 | @override
10 | _AnimPanelState createState() => _AnimPanelState();
11 | }
12 |
13 | class _AnimPanelState extends State
14 | with SingleTickerProviderStateMixin {
15 | PointData points = PointData();
16 |
17 | AnimationController _ctrl;
18 |
19 | final Duration animDuration = const Duration(milliseconds: 1000);
20 |
21 | Animation curveAnim;
22 |
23 | @override
24 | void initState() {
25 | super.initState();
26 | _ctrl = AnimationController(
27 | vsync: this,
28 | duration: animDuration,
29 | )..addListener(_collectPoint);
30 | // curveAnim = CurvedAnimation(parent: _ctrl, curve: Curves.bounceOut);
31 | // curveAnim = CurvedAnimation(parent: _ctrl, curve: Curves.ease);
32 | // curveAnim = CurvedAnimation(parent: _ctrl, curve: Curves.decelerate);
33 | // curveAnim = CurvedAnimation(parent: _ctrl, curve: Curves.elasticOut);
34 | curveAnim = CurvedAnimation(parent: _ctrl, curve: const SawTooth(3));
35 | }
36 |
37 | @override
38 | void dispose() {
39 | _ctrl.dispose();
40 | points.dispose();
41 | super.dispose();
42 | }
43 |
44 | void _collectPoint() {
45 | points.push(curveAnim.value);
46 | }
47 |
48 | void _startAnim() async{
49 | points.clear();
50 | print('start!---${DateTime.now().toIso8601String()}----------');
51 | // await _ctrl.forward(from: 0);
52 | await _ctrl.forward(from: 0);
53 | print('done!---${DateTime.now().toIso8601String()}----------');
54 | }
55 |
56 | @override
57 | Widget build(BuildContext context) {
58 | return GestureDetector(
59 | onTap: _startAnim,
60 | child: CustomPaint(
61 | painter: AnimPainter(points),
62 | size: const Size(
63 | 200,
64 | 200,
65 | ),
66 | ),
67 | );
68 | }
69 | }
70 |
71 |
72 |
--------------------------------------------------------------------------------
/lib/03_curve/02/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'anim_panel.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: AnimPanel(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/03_curve/02/point_data.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 |
3 | class PointData extends ChangeNotifier {
4 | final List values = [];
5 |
6 | void push(double value) {
7 | values.add(value);
8 | notifyListeners();
9 | }
10 |
11 |
12 | void clear() {
13 | values.clear();
14 | notifyListeners();
15 | }
16 | }
--------------------------------------------------------------------------------
/lib/03_curve/03/anim_panel.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | import 'anim_painter.dart';
6 | import 'point_data.dart';
7 |
8 | class AnimPanel extends StatefulWidget {
9 | @override
10 | _AnimPanelState createState() => _AnimPanelState();
11 | }
12 |
13 | class _AnimPanelState extends State
14 | with SingleTickerProviderStateMixin {
15 | PointData points = PointData();
16 |
17 | AnimationController _ctrl;
18 |
19 | final Duration animDuration = const Duration(milliseconds: 1000);
20 |
21 | // Animation curveAnim;
22 |
23 | @override
24 | void initState() {
25 | super.initState();
26 | _ctrl = AnimationController(
27 | vsync: this,
28 | duration: animDuration,
29 | )..addListener(_collectPoint);
30 | }
31 |
32 | @override
33 | void dispose() {
34 | _ctrl.dispose();
35 | points.dispose();
36 | super.dispose();
37 | }
38 |
39 | void _collectPoint() {
40 | points.push(Curves.decelerate.transform(_ctrl.value));
41 | }
42 |
43 | void _startAnim() async{
44 | points.clear();
45 | print('start!---${DateTime.now().toIso8601String()}----------');
46 | // await _ctrl.forward(from: 0);
47 | await _ctrl.forward(from: 0);
48 | print('done!---${DateTime.now().toIso8601String()}----------');
49 | }
50 |
51 | @override
52 | Widget build(BuildContext context) {
53 | return GestureDetector(
54 | onTap: _startAnim,
55 | child: CustomPaint(
56 | painter: AnimPainter(points),
57 | size: const Size(
58 | 200,
59 | 200,
60 | ),
61 | ),
62 | );
63 | }
64 | }
65 |
66 |
67 |
--------------------------------------------------------------------------------
/lib/03_curve/03/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'anim_panel.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: AnimPanel(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/03_curve/03/point_data.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 |
3 | class PointData extends ChangeNotifier {
4 | final List values = [];
5 |
6 | void push(double value) {
7 | values.add(value);
8 | notifyListeners();
9 | }
10 |
11 |
12 | void clear() {
13 | values.clear();
14 | notifyListeners();
15 | }
16 | }
--------------------------------------------------------------------------------
/lib/03_curve/04/anim_panel.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | import 'anim_painter.dart';
6 | import 'point_data.dart';
7 | import 'toly_curve.dart';
8 |
9 | class AnimPanel extends StatefulWidget {
10 | @override
11 | _AnimPanelState createState() => _AnimPanelState();
12 | }
13 |
14 | class _AnimPanelState extends State
15 | with SingleTickerProviderStateMixin {
16 | PointData points = PointData();
17 |
18 | AnimationController _ctrl;
19 |
20 | final Duration animDuration = const Duration(milliseconds: 1000);
21 |
22 | Animation curveAnim;
23 |
24 | @override
25 | void initState() {
26 | super.initState();
27 | _ctrl = AnimationController(
28 | vsync: this,
29 | duration: animDuration,
30 | )..addListener(_collectPoint);
31 | // curveAnim = CurvedAnimation(parent: _ctrl, curve: const X2Curve());
32 | curveAnim = CurvedAnimation(parent: _ctrl, curve: const DampingCurve());
33 |
34 | }
35 |
36 | @override
37 | void dispose() {
38 | _ctrl.dispose();
39 | points.dispose();
40 | super.dispose();
41 | }
42 |
43 | void _collectPoint() {
44 | points.push(curveAnim.value);
45 | }
46 |
47 | void _startAnim() async{
48 | points.clear();
49 | print('start!---${DateTime.now().toIso8601String()}----------');
50 | // await _ctrl.forward(from: 0);
51 | await _ctrl.forward(from: 0);
52 | print('done!---${DateTime.now().toIso8601String()}----------');
53 | }
54 |
55 | @override
56 | Widget build(BuildContext context) {
57 | return GestureDetector(
58 | onTap: _startAnim,
59 | child: CustomPaint(
60 | painter: AnimPainter(points),
61 | size: const Size(
62 | 200,
63 | 200,
64 | ),
65 | ),
66 | );
67 | }
68 | }
69 |
70 |
71 |
--------------------------------------------------------------------------------
/lib/03_curve/04/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'anim_panel.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: AnimPanel(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/03_curve/04/point_data.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 |
3 | class PointData extends ChangeNotifier {
4 | final List values = [];
5 |
6 | void push(double value) {
7 | values.add(value);
8 | notifyListeners();
9 | }
10 |
11 |
12 | void clear() {
13 | values.clear();
14 | notifyListeners();
15 | }
16 | }
--------------------------------------------------------------------------------
/lib/03_curve/04/toly_curve.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | class X2Curve extends Curve{
6 |
7 | const X2Curve();
8 |
9 |
10 | @override
11 | double transformInternal(double t) {
12 | return t*t;
13 | }
14 |
15 | }
16 |
17 | class DampingCurve extends Curve {
18 | const DampingCurve();
19 |
20 | @override
21 | double transformInternal(double t) {
22 | t = t - 1.0;
23 | return t * t * t * t * t + 1.0;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/lib/04_tween/01_color/circle_anim.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class CircleAnim extends StatefulWidget {
4 | @override
5 | _CircleAnimState createState() => _CircleAnimState();
6 | }
7 |
8 | class _CircleAnimState extends State
9 | with SingleTickerProviderStateMixin {
10 | AnimationController _ctrl;
11 |
12 | final Duration animDuration = const Duration(milliseconds: 1000);
13 |
14 | @override
15 | void initState() {
16 | super.initState();
17 | _ctrl = AnimationController(
18 | vsync: this,
19 | duration: animDuration,
20 | );
21 | }
22 |
23 | @override
24 | void dispose() {
25 | _ctrl.dispose();
26 | super.dispose();
27 | }
28 |
29 | @override
30 | Widget build(BuildContext context) {
31 | return GestureDetector(
32 | onTap: _startAnim,
33 | child: AnimatedBuilder(
34 | animation: _ctrl,
35 | builder: _buildByAnim,
36 | ));
37 | }
38 |
39 | Color get color => Color.lerp(Colors.blue, Colors.red, _ctrl.value);
40 |
41 | Widget _buildByAnim(_, __) => Container(
42 | width: 80,
43 | height: 80,
44 | decoration: BoxDecoration(color: color, shape: BoxShape.circle),
45 | );
46 |
47 | void _startAnim() {
48 | _ctrl.forward(from: 0);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/lib/04_tween/01_color/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'circle_anim.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: CircleAnim(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/04_tween/02_color_tween/circle_anim.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class CircleAnim extends StatefulWidget {
4 | @override
5 | _CircleAnimState createState() => _CircleAnimState();
6 | }
7 |
8 | class _CircleAnimState extends State
9 | with SingleTickerProviderStateMixin {
10 | AnimationController _ctrl;
11 |
12 | final Duration animDuration = const Duration(milliseconds: 1000);
13 |
14 | final ColorTween tween = ColorTween(begin: Colors.blue,end: Colors.red);
15 |
16 | @override
17 | void initState() {
18 | super.initState();
19 | _ctrl = AnimationController(
20 | vsync: this,
21 | duration: animDuration,
22 | );
23 | }
24 |
25 | @override
26 | void dispose() {
27 | _ctrl.dispose();
28 | super.dispose();
29 | }
30 |
31 | @override
32 | Widget build(BuildContext context) {
33 | return GestureDetector(
34 | onTap: _startAnim,
35 | child: AnimatedBuilder(
36 | animation: _ctrl,
37 | builder: _buildByAnim,
38 | ));
39 | }
40 |
41 | Color get color => tween.transform(_ctrl.value);
42 |
43 | Widget _buildByAnim(_, __) => Container(
44 | width: 80,
45 | height: 80,
46 | decoration: BoxDecoration(color: color, shape: BoxShape.circle),
47 | );
48 |
49 | void _startAnim() {
50 | _ctrl.forward(from: 0);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/lib/04_tween/02_color_tween/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'circle_anim.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: CircleAnim(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/04_tween/03_tween_evaluate/circle_anim.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class CircleAnim extends StatefulWidget {
4 | @override
5 | _CircleAnimState createState() => _CircleAnimState();
6 | }
7 |
8 | class _CircleAnimState extends State
9 | with SingleTickerProviderStateMixin {
10 | AnimationController _ctrl;
11 |
12 | final Duration animDuration = const Duration(milliseconds: 1000);
13 |
14 | final ColorTween tween = ColorTween(begin: Colors.blue,end: Colors.red);
15 |
16 | @override
17 | void initState() {
18 | super.initState();
19 | _ctrl = AnimationController(
20 | vsync: this,
21 | duration: animDuration,
22 | );
23 | }
24 |
25 | @override
26 | void dispose() {
27 | _ctrl.dispose();
28 | super.dispose();
29 | }
30 |
31 | @override
32 | Widget build(BuildContext context) {
33 | return GestureDetector(
34 | onTap: _startAnim,
35 | child: AnimatedBuilder(
36 | animation: _ctrl,
37 | builder: _buildByAnim,
38 | ));
39 | }
40 |
41 | Color get color => tween.evaluate(_ctrl);
42 |
43 | Widget _buildByAnim(_, __) => Container(
44 | width: 80,
45 | height: 80,
46 | decoration: BoxDecoration(color: color, shape: BoxShape.circle),
47 | );
48 |
49 | void _startAnim() {
50 | _ctrl.forward(from: 0);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/lib/04_tween/03_tween_evaluate/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'circle_anim.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: CircleAnim(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/04_tween/04_animate/circle_anim.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class CircleAnim extends StatefulWidget {
4 | @override
5 | _CircleAnimState createState() => _CircleAnimState();
6 | }
7 |
8 | class _CircleAnimState extends State
9 | with SingleTickerProviderStateMixin {
10 | AnimationController _ctrl;
11 |
12 | final Duration animDuration = const Duration(milliseconds: 1000);
13 |
14 | final ColorTween tween = ColorTween(begin: Colors.blue,end: Colors.red);
15 | Animation colorAnima;
16 |
17 | @override
18 | void initState() {
19 | super.initState();
20 | _ctrl = AnimationController(
21 | vsync: this,
22 | duration: animDuration,
23 | );
24 | colorAnima = tween.animate(_ctrl);
25 | }
26 |
27 | @override
28 | void dispose() {
29 | _ctrl.dispose();
30 | super.dispose();
31 | }
32 |
33 | @override
34 | Widget build(BuildContext context) {
35 | return GestureDetector(
36 | onTap: _startAnim,
37 | child: AnimatedBuilder(
38 | animation: _ctrl,
39 | builder: _buildByAnim,
40 | ));
41 | }
42 |
43 | Color get color => colorAnima.value;
44 |
45 | Widget _buildByAnim(_, __) => Container(
46 | width: 80,
47 | height: 80,
48 | decoration: BoxDecoration(color: color, shape: BoxShape.circle),
49 | );
50 |
51 | void _startAnim() {
52 | _ctrl.forward(from: 0);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/lib/04_tween/04_animate/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'circle_anim.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: CircleAnim(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/04_tween/05_curve_tween/anim_panel.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | import 'anim_painter.dart';
6 | import 'point_data.dart';
7 |
8 | class AnimPanel extends StatefulWidget {
9 | @override
10 | _AnimPanelState createState() => _AnimPanelState();
11 | }
12 |
13 | class _AnimPanelState extends State
14 | with SingleTickerProviderStateMixin {
15 | PointData points = PointData();
16 |
17 | AnimationController _ctrl;
18 |
19 | final Duration animDuration = const Duration(milliseconds: 1000);
20 |
21 | Animation curveAnim;
22 |
23 | @override
24 | void initState() {
25 | super.initState();
26 | _ctrl = AnimationController(
27 | vsync: this,
28 | duration: animDuration,
29 | )..addListener(_collectPoint);
30 | curveAnim = CurveTween(curve: Curves.bounceOut).animate(_ctrl);
31 |
32 |
33 |
34 | }
35 |
36 | @override
37 | void dispose() {
38 | _ctrl.dispose();
39 | points.dispose();
40 | super.dispose();
41 | }
42 |
43 | void _collectPoint() {
44 | points.push(curveAnim.value);
45 | }
46 |
47 | void _startAnim() async{
48 | points.clear();
49 | print('start!---${DateTime.now().toIso8601String()}----------');
50 | // await _ctrl.forward(from: 0);
51 | await _ctrl.forward(from: 0);
52 | print('done!---${DateTime.now().toIso8601String()}----------');
53 | }
54 |
55 | @override
56 | Widget build(BuildContext context) {
57 | return GestureDetector(
58 | onTap: _startAnim,
59 | child: CustomPaint(
60 | painter: AnimPainter(points),
61 | size: const Size(
62 | 200,
63 | 200,
64 | ),
65 | ),
66 | );
67 | }
68 | }
69 |
70 |
71 |
--------------------------------------------------------------------------------
/lib/04_tween/05_curve_tween/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'anim_panel.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: AnimPanel(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/04_tween/05_curve_tween/point_data.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 |
3 | class PointData extends ChangeNotifier {
4 | final List values = [];
5 |
6 | void push(double value) {
7 | values.add(value);
8 | notifyListeners();
9 | }
10 |
11 |
12 | void clear() {
13 | values.clear();
14 | notifyListeners();
15 | }
16 | }
--------------------------------------------------------------------------------
/lib/04_tween/06_tween_sequence/anim_panel.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | import 'anim_painter.dart';
6 | import 'point_data.dart';
7 |
8 | class AnimPanel extends StatefulWidget {
9 | @override
10 | _AnimPanelState createState() => _AnimPanelState();
11 | }
12 |
13 | class _AnimPanelState extends State
14 | with SingleTickerProviderStateMixin {
15 | PointData points = PointData();
16 |
17 | AnimationController _ctrl;
18 |
19 | final Duration animDuration = const Duration(milliseconds: 1000);
20 |
21 | Animation sequenceAnim;
22 |
23 | @override
24 | void initState() {
25 | super.initState();
26 | _ctrl = AnimationController(
27 | vsync: this,
28 | duration: animDuration,
29 | )..addListener(_collectPoint);
30 |
31 | sequenceAnim = TweenSequence(
32 | >[
33 | TweenSequenceItem(
34 | tween: Tween(begin: 0,end: 0.5).chain(CurveTween(curve: Curves.ease)),
35 | weight: 4.0,
36 | ),
37 | TweenSequenceItem(
38 | tween: ConstantTween(0.5),
39 | weight: 2.0,
40 | ),
41 | TweenSequenceItem(
42 | tween: Tween(begin: 0.5,end: 1.0).chain(CurveTween(curve: Curves.decelerate)),
43 | weight: 4.0,
44 | ),
45 | ],
46 | ).animate(_ctrl);
47 | }
48 |
49 | @override
50 | void dispose() {
51 | _ctrl.dispose();
52 | points.dispose();
53 | super.dispose();
54 | }
55 |
56 | void _collectPoint() {
57 | points.push(sequenceAnim.value);
58 | }
59 |
60 | void _startAnim() async{
61 | points.clear();
62 | print('start!---${DateTime.now().toIso8601String()}----------');
63 | // await _ctrl.forward(from: 0);
64 | await _ctrl.forward(from: 0);
65 | print('done!---${DateTime.now().toIso8601String()}----------');
66 | }
67 |
68 | @override
69 | Widget build(BuildContext context) {
70 | return GestureDetector(
71 | onTap: _startAnim,
72 | child: CustomPaint(
73 | painter: AnimPainter(points),
74 | size: const Size(
75 | 200,
76 | 200,
77 | ),
78 | ),
79 | );
80 | }
81 | }
82 |
83 |
84 |
--------------------------------------------------------------------------------
/lib/04_tween/06_tween_sequence/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'anim_panel.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: AnimPanel(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/04_tween/06_tween_sequence/point_data.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 |
3 | class PointData extends ChangeNotifier {
4 | final List values = [];
5 |
6 | void push(double value) {
7 | values.add(value);
8 | notifyListeners();
9 | }
10 |
11 |
12 | void clear() {
13 | values.clear();
14 | notifyListeners();
15 | }
16 | }
--------------------------------------------------------------------------------
/lib/04_tween/07_text_style_tween/circle.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 |
3 | class Circle {
4 | final Color color;
5 | final double radius;
6 | final Offset center;
7 |
8 | Circle({this.color, this.radius, this.center});
9 | }
10 |
11 | class CircleTween extends Tween {
12 | CircleTween({Circle begin, Circle end}) : super(begin: begin, end: end);
13 |
14 | @override
15 | Circle lerp(double t) {
16 | return Circle(
17 | color: Color.lerp(begin.color, end.color, t),
18 | radius: (begin.radius + (end.radius - begin.radius) * t),
19 | center: Offset.lerp(begin.center, end.center, t));
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/lib/04_tween/07_text_style_tween/circle_anim.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import 'circle.dart';
4 |
5 | class CircleAnim extends StatefulWidget {
6 | @override
7 | _CircleAnimState createState() => _CircleAnimState();
8 | }
9 |
10 | class _CircleAnimState extends State
11 | with SingleTickerProviderStateMixin {
12 | AnimationController _ctrl;
13 |
14 | final Duration animDuration = const Duration(milliseconds: 500);
15 |
16 | final TextStyleTween tween = TextStyleTween(
17 | begin: TextStyle(color: Colors.blue, fontSize: 14, letterSpacing: 4,),
18 | end: TextStyle(color: Colors.purple, fontSize: 40, letterSpacing: 10,));
19 |
20 | Animation textAnimation;
21 |
22 | @override
23 | void initState() {
24 | super.initState();
25 | _ctrl = AnimationController(
26 | vsync: this,
27 | duration: animDuration,
28 | );
29 | textAnimation = tween.animate(_ctrl);
30 | }
31 |
32 | @override
33 | void dispose() {
34 | _ctrl.dispose();
35 | super.dispose();
36 | }
37 |
38 | @override
39 | Widget build(BuildContext context) {
40 | return GestureDetector(
41 | behavior: HitTestBehavior.opaque,
42 | onTap: _startAnim,
43 | child: Center(
44 | child: AnimatedBuilder(
45 | animation: _ctrl,
46 | builder: _buildByAnim,
47 | ),
48 | ));
49 | }
50 |
51 | Widget _buildByAnim(_, __) => Text(
52 | "张风捷特烈",style: textAnimation.value,
53 | );
54 |
55 | void _startAnim() {
56 | _ctrl.forward(from: 0);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/lib/04_tween/07_text_style_tween/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'circle_anim.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: CircleAnim(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/04_tween/08_circle_color_tween/circle.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 |
3 | class Circle {
4 | final Color color;
5 | final double radius;
6 | final Offset center;
7 |
8 | Circle({this.color, this.radius, this.center});
9 | }
10 |
11 | class CircleTween extends Tween {
12 | CircleTween({Circle begin, Circle end}) : super(begin: begin, end: end);
13 |
14 | @override
15 | Circle lerp(double t) {
16 | return Circle(
17 | color: Color.lerp(begin.color, end.color, t),
18 | radius: (begin.radius + (end.radius - begin.radius) * t),
19 | center: Offset.lerp(begin.center, end.center, t));
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/lib/04_tween/08_circle_color_tween/circle_anim.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import 'circle.dart';
4 |
5 | class CircleAnim extends StatefulWidget {
6 | @override
7 | _CircleAnimState createState() => _CircleAnimState();
8 | }
9 |
10 | class _CircleAnimState extends State
11 | with SingleTickerProviderStateMixin {
12 | AnimationController _ctrl;
13 |
14 | final Duration animDuration = const Duration(milliseconds: 1000);
15 |
16 | final CircleTween tween = CircleTween(
17 | begin: Circle(center: Offset.zero, radius: 25, color: Colors.blue),
18 | end: Circle(center: Offset(100, 0), radius: 50, color: Colors.red));
19 |
20 | Animation circleAnimation;
21 |
22 | @override
23 | void initState() {
24 | super.initState();
25 | _ctrl = AnimationController(
26 | vsync: this,
27 | duration: animDuration,
28 | );
29 | circleAnimation = tween.animate(_ctrl);
30 | }
31 |
32 | @override
33 | void dispose() {
34 | _ctrl.dispose();
35 | super.dispose();
36 | }
37 |
38 | @override
39 | Widget build(BuildContext context) {
40 | return GestureDetector(
41 | behavior: HitTestBehavior.opaque,
42 | onTap: _startAnim,
43 | child: AnimatedBuilder(
44 | animation: _ctrl,
45 | builder: _buildByAnim,
46 | ));
47 | }
48 |
49 | Widget _buildByAnim(_, __) =>CircleWidget(
50 | circle: circleAnimation.value,
51 | );
52 |
53 | void _startAnim() {
54 | _ctrl.forward(from: 0);
55 | }
56 | }
57 |
58 | class CircleWidget extends StatelessWidget {
59 | final Circle circle;
60 | const CircleWidget({Key key,@required this.circle}) : super(key: key);
61 |
62 | @override
63 | Widget build(BuildContext context) {
64 | return Container(
65 | transform: Matrix4.translationValues(circle.center.dx,
66 | circle.center.dy, 0),
67 | width: circle.radius * 2,
68 | height: circle.radius * 2,
69 | decoration: BoxDecoration(
70 | color: circle.color, shape: BoxShape.circle),
71 | );
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/lib/04_tween/08_circle_color_tween/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'circle_anim.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: CircleAnim(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/05_simple/01_shine_static/circle_shine_image.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class CircleShineImage extends StatefulWidget {
4 | final double maxBlurRadius;
5 | final Color color;
6 | final Duration duration;
7 | final Curve curve;
8 | final ImageProvider image;
9 | final double radius;
10 |
11 | const CircleShineImage(
12 | {Key key,
13 | this.maxBlurRadius = 10,
14 | this.color = Colors.purple,
15 | this.duration = const Duration(milliseconds: 2000),
16 | this.curve = Curves.ease,
17 | this.radius = 30,
18 | @required this.image})
19 | : super(key: key);
20 |
21 | @override
22 | _CircleShineImageState createState() => _CircleShineImageState();
23 | }
24 |
25 | class _CircleShineImageState extends State {
26 |
27 | @override
28 | Widget build(BuildContext context) {
29 | return Container(
30 | height: widget.radius * 2,
31 | width: widget.radius * 2,
32 | decoration: BoxDecoration(
33 | image: DecorationImage(image: widget.image, fit: BoxFit.cover),
34 | shape: BoxShape.circle,
35 | boxShadow: [
36 | BoxShadow(
37 | color: widget.color,
38 | blurRadius: widget.maxBlurRadius,
39 | spreadRadius: 0)
40 | ]),
41 | );
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/lib/05_simple/01_shine_static/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'circle_shine_image.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | // backgroundColor: Colors.black,
24 | body: Center(
25 | child: Wrap(
26 | spacing: 50,
27 | children:[
28 | CircleShineImage(
29 | image: AssetImage('assets/images/icon_head.png'),
30 | color: Colors.blue,
31 | maxBlurRadius: 4,
32 | curve: Curves.decelerate,
33 | ),
34 | CircleShineImage(
35 | image: AssetImage('assets/images/icon_head.png'),
36 | color: Colors.red,
37 | maxBlurRadius: 6,
38 | duration: Duration(seconds: 1),
39 | curve: Curves.easeIn,
40 | ),
41 | CircleShineImage(
42 | image: AssetImage('assets/images/icon_head.png'),
43 | color: Colors.purple,
44 | maxBlurRadius: 8,
45 | curve: Curves.ease,
46 | ),
47 |
48 | ] ,
49 | ),
50 | ))
51 | );
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/lib/05_simple/02_shine_anim/circle_shine_image.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class CircleShineImage extends StatefulWidget {
4 | final double maxBlurRadius;
5 | final Color color;
6 | final Duration duration;
7 | final Curve curve;
8 | final ImageProvider image;
9 | final double radius;
10 |
11 | const CircleShineImage(
12 | {Key key,
13 | this.maxBlurRadius = 10,
14 | this.color = Colors.purple,
15 | this.duration = const Duration(milliseconds: 2000),
16 | this.curve = Curves.ease,
17 | this.radius = 30,
18 | @required this.image})
19 | : super(key: key);
20 |
21 | @override
22 | _CircleShineImageState createState() => _CircleShineImageState();
23 | }
24 |
25 | class _CircleShineImageState extends State
26 | with SingleTickerProviderStateMixin {
27 | AnimationController _ctrl;
28 | Animation blurRadiusAnim;
29 |
30 | @override
31 | void initState() {
32 | super.initState();
33 | _ctrl = AnimationController(
34 | vsync: this,
35 | duration: widget.duration,
36 | )..addListener(_handleAnimationChanged);
37 |
38 | blurRadiusAnim = Tween(begin: 0, end: widget.maxBlurRadius)
39 | .chain(CurveTween(curve: widget.curve))
40 | .animate(_ctrl);
41 |
42 | _ctrl.repeat(reverse: true);
43 | }
44 |
45 | @override
46 | void dispose() {
47 | _ctrl.dispose();
48 | super.dispose();
49 | }
50 |
51 | @override
52 | Widget build(BuildContext context) {
53 | return Container(
54 | height: widget.radius * 2,
55 | width: widget.radius * 2,
56 | decoration: BoxDecoration(
57 | image: DecorationImage(image: widget.image, fit: BoxFit.cover),
58 | shape: BoxShape.circle,
59 | boxShadow: [
60 | BoxShadow(
61 | color: widget.color,
62 | blurRadius: blurRadiusAnim.value,
63 | spreadRadius: 0)
64 | ]),
65 | );
66 | }
67 |
68 | void _handleAnimationChanged() {
69 | setState(() {});
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/lib/05_simple/02_shine_anim/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'circle_shine_image.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | // backgroundColor: Colors.black,
24 | body: Center(
25 | child: Wrap(
26 | spacing: 50,
27 | children:[
28 | CircleShineImage(
29 | image: AssetImage('assets/images/wy_300x200.jpg'),
30 | color: Colors.red,
31 | maxBlurRadius: 6,
32 | duration: Duration(seconds: 1),
33 | curve: Curves.easeIn,
34 | ),
35 | CircleShineImage(
36 | image: AssetImage('assets/images/icon_head.png'),
37 | color: Colors.purple,
38 | maxBlurRadius: 8,
39 | curve: Curves.ease,
40 | ),
41 | CircleShineImage(
42 | image: AssetImage('assets/images/icon_8.jpg'),
43 | color: Colors.blue,
44 | maxBlurRadius: 4,
45 | curve: Curves.decelerate,
46 | )
47 | ] ,
48 | ),
49 | ))
50 | );
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/lib/05_simple/04_compare/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | import 'toggle_rotate.dart';
5 |
6 | void main() {
7 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
8 | SystemChrome.setPreferredOrientations(// 使设备横屏显示
9 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
10 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
11 | runApp(MyApp());
12 | }
13 |
14 | class MyApp extends StatelessWidget {
15 | @override
16 | Widget build(BuildContext context) {
17 | return MaterialApp(
18 | debugShowCheckedModeBanner: false,
19 | title: 'Flutter Demo',
20 | theme: ThemeData(
21 | primarySwatch: Colors.blue,
22 | ),
23 | home: HomePage());
24 | }
25 | }
26 |
27 | class HomePage extends StatefulWidget {
28 | const HomePage({Key key}) : super(key: key);
29 |
30 | @override
31 | _HomePageState createState() => _HomePageState();
32 | }
33 |
34 | class _HomePageState extends State {
35 | ValueNotifier angle = ValueNotifier(90);
36 |
37 | @override
38 | Widget build(BuildContext context) {
39 | return Scaffold(
40 | // backgroundColor: Colors.black,
41 | body: Center(
42 | child: Container(
43 | width: 300,
44 | child: ValueListenableBuilder(
45 | valueListenable: angle,
46 | builder: (_, value, __) => Wrap(
47 | alignment: WrapAlignment.center,
48 | children: [
49 | Slider(
50 | value: value,
51 | min: 0,
52 | max: 360,
53 | onChanged: (v) {
54 | angle.value = v;
55 | }),
56 | ToggleRotate(
57 | beginAngle: 0,
58 | endAngle: value,
59 | curve: Curves.ease,
60 | child: Image(
61 | width: 60,
62 | height: 60,
63 | image: AssetImage("assets/images/icon_head.jpg")),
64 | onEnd: (v) {
65 | print("---expanded---:$v-------");
66 | },
67 | onTap: () {
68 | print("---tap----------");
69 | },
70 | )
71 | ],
72 | )),
73 | ),
74 | ));
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/lib/05_simple/05_burst_static/burst_menu.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | /// create by 张风捷特烈 on 2020/11/17
6 | /// contact me by email 1981462002@qq.com
7 | /// 说明:
8 |
9 | class BurstMenu extends StatefulWidget {
10 | final List menus;
11 | final Widget center;
12 |
13 | BurstMenu({Key key, @required this.menus, @required this.center})
14 | : super(key: key);
15 |
16 | @override
17 | BurstMenuState createState() => BurstMenuState();
18 | }
19 |
20 | class BurstMenuState extends State {
21 | @override
22 | Widget build(BuildContext context) {
23 | return Flow(
24 | delegate: _CircleFlowDelegate(),
25 | children: [...widget.menus, widget.center],
26 | );
27 | }
28 | }
29 |
30 | class _CircleFlowDelegate extends FlowDelegate {
31 | //绘制孩子的方法
32 | @override
33 | void paintChildren(FlowPaintingContext context) {
34 |
35 | double radius = context.size.shortestSide / 2;
36 |
37 | final int count = context.childCount - 1;
38 | final double perRad = 2 * pi / count;
39 |
40 | for (int i = 0; i < count; i++) {
41 | final double cSizeX = context.getChildSize(i).width / 2;
42 | final double cSizeY = context.getChildSize(i).height / 2;
43 |
44 | final double offsetX = (radius - cSizeX) * cos(i * perRad) + radius;
45 | final double offsetY = (radius - cSizeY) * sin(i * perRad) + radius;
46 |
47 | context.paintChild(
48 | i,
49 | transform: Matrix4.translationValues(
50 | offsetX - cSizeX,
51 | offsetY - cSizeY,
52 | 0.0,
53 | ),
54 | );
55 | }
56 |
57 | context.paintChild(
58 | context.childCount - 1,
59 | transform: Matrix4.translationValues(
60 | radius - context.getChildSize(context.childCount - 1).width / 2,
61 | radius - context.getChildSize(context.childCount - 1).height / 2,
62 | 0.0,
63 | ),
64 | );
65 | }
66 |
67 | @override
68 | bool shouldRepaint(FlowDelegate oldDelegate) => false;
69 | }
70 |
--------------------------------------------------------------------------------
/lib/05_simple/06_burst_static_angle/burst_menu.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | /// create by 张风捷特烈 on 2020/11/17
6 | /// contact me by email 1981462002@qq.com
7 | /// 说明:
8 |
9 | class BurstMenu extends StatefulWidget {
10 | final List menus;
11 | final Widget center;
12 |
13 | BurstMenu({Key key, @required this.menus, @required this.center})
14 | : super(key: key);
15 |
16 | @override
17 | BurstMenuState createState() => BurstMenuState();
18 | }
19 |
20 | class BurstMenuState extends State {
21 | @override
22 | Widget build(BuildContext context) {
23 | return Flow(
24 | delegate: _CircleFlowDelegate(),
25 | children: [...widget.menus, widget.center],
26 | );
27 | }
28 | }
29 |
30 | class _CircleFlowDelegate extends FlowDelegate {
31 | // 菜单圆弧的扫描角度
32 | final double swapAngle;
33 |
34 | // 菜单圆弧的起始角度
35 | final double startAngle;
36 |
37 | _CircleFlowDelegate({
38 | this.swapAngle = 120,
39 | this.startAngle = -60,
40 | });
41 |
42 | //绘制孩子的方法
43 | @override
44 | void paintChildren(FlowPaintingContext context) {
45 | double radius = context.size.shortestSide / 2;
46 | final int count = context.childCount - 1;
47 |
48 | final double perRad = swapAngle / 180 * pi / (count - 1);
49 | double rotate = startAngle / 180 * pi;
50 |
51 | for (int i = 0; i < count; i++) {
52 | final double cSizeX = context.getChildSize(i).width / 2;
53 | final double cSizeY = context.getChildSize(i).height / 2;
54 |
55 | final double offsetX =
56 | (radius - cSizeX) * cos(i * perRad + rotate) + radius;
57 | final double offsetY =
58 | (radius - cSizeY) * sin(i * perRad + rotate) + radius;
59 |
60 | context.paintChild(
61 | i,
62 | transform: Matrix4.translationValues(
63 | offsetX - cSizeX,
64 | offsetY - cSizeY,
65 | 0.0,
66 | ),
67 | );
68 | }
69 |
70 | context.paintChild(
71 | context.childCount - 1,
72 | transform: Matrix4.translationValues(
73 | radius - context.getChildSize(context.childCount - 1).width / 2,
74 | radius - context.getChildSize(context.childCount - 1).height / 2,
75 | 0.0,
76 | ),
77 | );
78 | }
79 |
80 | @override
81 | bool shouldRepaint(_CircleFlowDelegate oldDelegate) =>
82 | swapAngle != oldDelegate.swapAngle ||
83 | startAngle != oldDelegate.startAngle;
84 | }
85 |
--------------------------------------------------------------------------------
/lib/06_loading/01_halo_circle/01_circle_static/circle_halo.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 | import 'dart:ui' as ui;
3 |
4 | import 'package:flutter/material.dart';
5 |
6 | class CircleHalo extends StatefulWidget {
7 | const CircleHalo({Key key}) : super(key: key);
8 |
9 | @override
10 | _CircleHaloState createState() => _CircleHaloState();
11 | }
12 |
13 | class _CircleHaloState extends State {
14 | @override
15 | Widget build(BuildContext context) {
16 | return CustomPaint(
17 | size: Size(200, 200),
18 | painter: CircleHaloPainter(),
19 | );
20 | }
21 | }
22 |
23 | class CircleHaloPainter extends CustomPainter {
24 | @override
25 | void paint(Canvas canvas, Size size) {
26 | canvas.translate(size.width / 2, size.height / 2);
27 | final Paint paint = Paint()
28 | ..style = PaintingStyle.stroke
29 | ..strokeWidth = 1;
30 |
31 | List colors = [
32 | Color(0xFFF60C0C),
33 | Color(0xFFF3B913),
34 | Color(0xFFE7F716),
35 | Color(0xFF3DF30B),
36 | Color(0xFF0DF6EF),
37 | Color(0xFF0829FB),
38 | Color(0xFFB709F4),
39 | ];
40 | colors.addAll(colors.reversed.toList());
41 | final List pos = List.generate(colors.length, (index) => index / colors.length);
42 |
43 | paint.shader =
44 | ui.Gradient.sweep(Offset.zero, colors, pos, TileMode.clamp, 0, 2 * pi);
45 |
46 | paint.maskFilter = MaskFilter.blur(BlurStyle.solid, 4);
47 |
48 | final Path circlePath = Path();
49 |
50 | circlePath.addOval(
51 | Rect.fromCenter(center: Offset(0, 0), width: 100, height: 100));
52 |
53 | canvas.drawPath(circlePath, paint);
54 | }
55 |
56 | @override
57 | bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
58 | }
59 |
--------------------------------------------------------------------------------
/lib/06_loading/01_halo_circle/01_circle_static/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'circle_halo.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | // backgroundColor: Colors.black,
24 | body: Center(
25 | child: Wrap(
26 | spacing: 50,
27 | children:[
28 | CircleHalo()
29 | ] ,
30 | ),
31 | ))
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/06_loading/01_halo_circle/02_light_static/circle_halo.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 | import 'dart:ui' as ui;
3 |
4 | import 'package:flutter/material.dart';
5 |
6 | class CircleHalo extends StatefulWidget {
7 | const CircleHalo({Key key}) : super(key: key);
8 |
9 | @override
10 | _CircleHaloState createState() => _CircleHaloState();
11 | }
12 |
13 | class _CircleHaloState extends State {
14 | @override
15 | Widget build(BuildContext context) {
16 | return CustomPaint(
17 | size: Size(200, 200),
18 | painter: CircleHaloPainter(),
19 | );
20 | }
21 | }
22 |
23 | class CircleHaloPainter extends CustomPainter {
24 | @override
25 | void paint(Canvas canvas, Size size) {
26 | canvas.translate(size.width / 2, size.height / 2);
27 | final Paint paint = Paint()
28 | ..style = PaintingStyle.stroke;
29 |
30 | paint.maskFilter = MaskFilter.blur(BlurStyle.solid, 4);
31 |
32 | final Path circlePath = Path()..addOval(
33 | Rect.fromCenter(center: Offset(0, 0), width: 100, height: 100));
34 |
35 | Path circlePath2 = Path()..addOval(
36 | Rect.fromCenter(center: Offset(-1, 0), width: 100, height: 100));
37 |
38 | Path result = Path.combine(PathOperation.difference, circlePath, circlePath2);
39 | paint.shader =null;
40 | paint..style = PaintingStyle.fill..color = Color(0xff00abf2);
41 |
42 | canvas.drawPath(result, paint);
43 | }
44 |
45 | @override
46 | bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
47 | }
48 |
--------------------------------------------------------------------------------
/lib/06_loading/01_halo_circle/02_light_static/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'circle_halo.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | // backgroundColor: Colors.black,
24 | body: Center(
25 | child: Wrap(
26 | spacing: 50,
27 | children:[
28 | CircleHalo()
29 | ] ,
30 | ),
31 | ))
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/06_loading/01_halo_circle/03_circle_anim/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'circle_halo.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | // backgroundColor: Colors.black,
24 | body: Center(
25 | child: Wrap(
26 | spacing: 50,
27 | children:[
28 | CircleHalo()
29 | ] ,
30 | ),
31 | ))
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/06_loading/01_halo_circle/04_light_anim/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'circle_halo.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | // backgroundColor: Colors.black,
24 | body: Center(
25 | child: Wrap(
26 | spacing: 50,
27 | children:[
28 | CircleHalo()
29 | ] ,
30 | ),
31 | ))
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/06_loading/01_halo_circle/05_circle_halo_last/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'circle_halo.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | // backgroundColor: Colors.black,
24 | body: Center(
25 | child: Wrap(
26 | spacing: 50,
27 | children:[
28 | CircleHalo()
29 | ] ,
30 | ),
31 | ))
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/06_loading/02_rotate/01_static/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'rotate_loading.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | // backgroundColor: Colors.black,
24 | body: Center(
25 | child: Wrap(
26 | spacing: 50,
27 | children:[
28 | RotateLoading()
29 | ] ,
30 | ),
31 | ))
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/06_loading/02_rotate/01_static/rotate_loading.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class RotateLoading extends StatefulWidget {
4 | final double size;
5 |
6 | const RotateLoading({Key key, this.size = 100}) : super(key: key);
7 |
8 | @override
9 | _RotateLoadingState createState() => _RotateLoadingState();
10 | }
11 |
12 | class _RotateLoadingState extends State {
13 | @override
14 | Widget build(BuildContext context) {
15 | return CustomPaint(
16 | size: Size(widget.size, widget.size),
17 | painter: RotateLoadingPainter(),
18 | );
19 | }
20 | }
21 |
22 | class RotateLoadingPainter extends CustomPainter {
23 | final double itemWidth;
24 |
25 | RotateLoadingPainter({this.itemWidth = 33});
26 |
27 | final List colors = const [
28 | Color(0xffF44336),
29 | Color(0xff5C6BC0),
30 | Color(0xffFFB74D),
31 | Color(0xff8BC34A)
32 | ];
33 |
34 | final Paint _paint = Paint();
35 | final double span = 16;
36 |
37 | @override
38 | void paint(Canvas canvas, Size size) {
39 | canvas.translate(size.width / 2, size.height / 2);
40 | final double len = itemWidth / 2 + span / 2;
41 |
42 | // 绘制红色
43 | Offset centerA = Offset(-len, -len);
44 | drawItem(canvas, centerA, colors[0]);
45 |
46 | // 绘制蓝色
47 | Offset centerB = Offset(len, len);
48 | drawItem(canvas, centerB, colors[1]);
49 |
50 | // 绘制橙色
51 | Offset centerC = Offset(len, -len);
52 | drawItem(canvas, centerC, colors[2]);
53 |
54 | // 绘制绿色
55 | Offset centerD = Offset(-len, len);
56 | drawItem(canvas, centerD, colors[3]);
57 | }
58 |
59 | void drawItem(
60 | Canvas canvas,
61 | Offset center,
62 | Color color,
63 | ) {
64 | Rect rect =
65 | Rect.fromCenter(center: center, width: itemWidth, height: itemWidth);
66 | canvas.drawRRect(
67 | RRect.fromRectAndRadius(rect, const Radius.circular(5)),
68 | _paint..color = color,
69 | );
70 | }
71 |
72 | @override
73 | bool shouldRepaint(covariant RotateLoadingPainter oldDelegate) =>
74 | oldDelegate.itemWidth != itemWidth;
75 | }
76 |
--------------------------------------------------------------------------------
/lib/06_loading/02_rotate/02_anim_01/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'rotate_loading.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | // backgroundColor: Colors.black,
24 | body: Center(
25 | child: Wrap(
26 | spacing: 50,
27 | children:[
28 | RotateLoading()
29 | ] ,
30 | ),
31 | ))
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/06_loading/02_rotate/03_anim_last/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'rotate_loading.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | // backgroundColor: Colors.black,
24 | body: Center(
25 | child: Wrap(
26 | spacing: 50,
27 | children:[
28 | RotateLoading()
29 | ] ,
30 | ),
31 | ))
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/06_loading/03_cross/01_cross_single/cross_loading.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | class CrossLoading extends StatefulWidget {
6 | final double size;
7 |
8 | const CrossLoading({Key key, this.size = 100}) : super(key: key);
9 |
10 | @override
11 | _CrossLoadingState createState() => _CrossLoadingState();
12 | }
13 |
14 | class _CrossLoadingState extends State
15 | with SingleTickerProviderStateMixin {
16 | @override
17 | Widget build(BuildContext context) {
18 | return CustomPaint(
19 | size: Size(widget.size, widget.size),
20 | painter: CrossLoadingPainter(),
21 | );
22 | }
23 | }
24 |
25 | class CrossLoadingPainter extends CustomPainter {
26 | CrossLoadingPainter({this.itemWidth = 33});
27 |
28 | final double itemWidth;
29 | final Paint _paint = Paint();
30 |
31 | @override
32 | void paint(Canvas canvas, Size size) {
33 | canvas.drawRect(
34 | Offset.zero & size, Paint()..color = Colors.grey.withAlpha(11));
35 | canvas.translate(size.width / 2, size.height / 2);
36 |
37 | final double offset = -size.height / 2 + itemWidth / sqrt(2);
38 | drawDiamond(canvas, offset,Color(0xffF44336));
39 | }
40 |
41 | void drawDiamond(Canvas canvas,double offset, Color color) {
42 | canvas.save();
43 | canvas.translate(0, offset);
44 | canvas.rotate(45 / 180 * pi);
45 |
46 | canvas.drawRect(
47 | Rect.fromCenter(
48 | center: Offset.zero, width: itemWidth, height: itemWidth),
49 | _paint..color = color);
50 | canvas.restore();
51 | }
52 |
53 | @override
54 | bool shouldRepaint(covariant CrossLoadingPainter oldDelegate) =>
55 | oldDelegate.itemWidth != itemWidth;
56 | }
57 |
--------------------------------------------------------------------------------
/lib/06_loading/03_cross/01_cross_single/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'cross_loading.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | // backgroundColor: Colors.black,
24 | body: Center(
25 | child: Wrap(
26 | spacing: 50,
27 | children:[
28 | CrossLoading()
29 | ] ,
30 | ),
31 | ))
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/06_loading/03_cross/02_cross_static/cross_loading.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | class CrossLoading extends StatefulWidget {
6 | final double size;
7 |
8 | const CrossLoading({Key key, this.size = 100}) : super(key: key);
9 |
10 | @override
11 | _CrossLoadingState createState() => _CrossLoadingState();
12 | }
13 |
14 | class _CrossLoadingState extends State
15 | with SingleTickerProviderStateMixin {
16 | @override
17 | Widget build(BuildContext context) {
18 | return CustomPaint(
19 | size: Size(widget.size, widget.size),
20 | painter: CrossLoadingPainter(),
21 | );
22 | }
23 | }
24 |
25 | class CrossLoadingPainter extends CustomPainter {
26 | CrossLoadingPainter({this.itemWidth = 33});
27 |
28 | final List colors = const [
29 | Color(0xffF44336), Color(0xff5C6BC0), Color(0xffFFB74D), Color(0xff8BC34A),
30 | ];
31 |
32 | final double itemWidth;
33 | final Paint _paint = Paint();
34 |
35 | @override
36 | void paint(Canvas canvas, Size size) {
37 | canvas.drawRect(
38 | Offset.zero & size, Paint()..color = Colors.grey.withAlpha(11));
39 | canvas.translate(size.width / 2, size.height / 2);
40 |
41 | final double offset = -size.height / 2 + itemWidth / sqrt(2);
42 |
43 | drawDiamond(canvas, offset, colors[0], true);
44 | drawDiamond(canvas, -offset, colors[1], true);
45 | drawDiamond(canvas, -offset, colors[2], false);
46 | drawDiamond(canvas, offset, colors[3], false);
47 | }
48 |
49 | void drawDiamond(Canvas canvas, double offset,Color color,bool vertical,) {
50 | canvas.save();
51 | if (vertical) {
52 | canvas.translate(0, offset);
53 | } else {
54 | canvas.translate(offset, 0);
55 | }
56 | canvas.rotate(45 / 180 * pi);
57 | canvas.drawRect(
58 | Rect.fromCenter(center: Offset.zero, width: itemWidth, height: itemWidth),
59 | _paint..color = color);
60 | canvas.restore();
61 | }
62 |
63 | @override
64 | bool shouldRepaint(covariant CrossLoadingPainter oldDelegate) =>
65 | oldDelegate.itemWidth != itemWidth;
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/lib/06_loading/03_cross/02_cross_static/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'cross_loading.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | // backgroundColor: Colors.black,
24 | body: Center(
25 | child: Wrap(
26 | spacing: 50,
27 | children:[
28 | CrossLoading()
29 | ] ,
30 | ),
31 | ))
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/06_loading/03_cross/03_cross_anim/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'cross_loading.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | // backgroundColor: Colors.black,
24 | body: Center(
25 | child: Wrap(
26 | spacing: 50,
27 | children:[
28 | CrossLoading()
29 | ] ,
30 | ),
31 | ))
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/06_loading/04_ovel/01_oval_single/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'oval_loading.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | // backgroundColor: Colors.black,
24 | body: Center(
25 | child: Wrap(
26 | spacing: 50,
27 | children:[
28 | OvalLoading()
29 | ] ,
30 | ),
31 | ))
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/06_loading/04_ovel/01_oval_single/oval_loading.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | class OvalLoading extends StatefulWidget {
6 | final double size;
7 |
8 | const OvalLoading({Key key, this.size = 150}) : super(key: key);
9 |
10 | @override
11 | _OvalLoadingState createState() => _OvalLoadingState();
12 | }
13 |
14 | class _OvalLoadingState extends State
15 | with SingleTickerProviderStateMixin {
16 | AnimationController _ctrl;
17 | Animation animation;
18 |
19 | @override
20 | void initState() {
21 | super.initState();
22 | _ctrl = AnimationController(
23 | vsync: this,
24 | duration: Duration(seconds: 2),
25 | );
26 | animation = Tween(begin: -pi, end: pi).animate(_ctrl);
27 | }
28 |
29 | @override
30 | void dispose() {
31 | _ctrl.dispose();
32 | super.dispose();
33 | }
34 |
35 | @override
36 | Widget build(BuildContext context) {
37 | return GestureDetector(
38 | onTap: () => _ctrl.repeat(),
39 | child: CustomPaint(
40 | size: Size(widget.size, widget.size),
41 | painter: OvalLoadingPainter(animation),
42 | ),
43 | );
44 | }
45 | }
46 |
47 | class OvalLoadingPainter extends CustomPainter {
48 | Animation animation;
49 |
50 | OvalLoadingPainter(this.animation, {this.radius = 15, this.a = 0.4})
51 | : super(repaint: animation);
52 |
53 | final Paint _paint = Paint();
54 | final double radius;
55 | final double a;
56 |
57 | @override
58 | void paint(Canvas canvas, Size size) {
59 | canvas.drawRect(
60 | Offset.zero & size, Paint()..color = Colors.grey.withAlpha(11));
61 |
62 | double zoneSize = size.shortestSide / 2;
63 | canvas.translate(size.width / 2, size.height / 2);
64 |
65 | canvas.drawOval(
66 | Rect.fromCenter(
67 | center: Offset.zero,
68 | width: zoneSize * 2 - radius,
69 | height: zoneSize * a * 2 - radius),
70 | Paint()..style = PaintingStyle.stroke,
71 | );
72 |
73 | double x = (zoneSize - radius) * f(animation.value);
74 | double y = (zoneSize - radius) * g(animation.value);
75 |
76 | canvas.drawCircle(Offset(x, y), radius, _paint..color = Color(0xffF44336));
77 | }
78 |
79 | double f(double t) => cos(t);
80 |
81 | double g(double t) => a * sin(t);
82 |
83 | @override
84 | bool shouldRepaint(covariant OvalLoadingPainter oldDelegate) =>
85 | oldDelegate.a != a || oldDelegate.animation != animation;
86 | }
87 |
--------------------------------------------------------------------------------
/lib/06_loading/04_ovel/02_sin_single/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'oval_loading.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | // backgroundColor: Colors.black,
24 | body: Center(
25 | child: Wrap(
26 | spacing: 50,
27 | children:[
28 | OvalLoading()
29 | ] ,
30 | ),
31 | ))
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/06_loading/04_ovel/02_sin_single/oval_loading.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | class OvalLoading extends StatefulWidget {
6 | final double size;
7 |
8 | const OvalLoading({Key key, this.size = 150}) : super(key: key);
9 |
10 | @override
11 | _OvalLoadingState createState() => _OvalLoadingState();
12 | }
13 |
14 | class _OvalLoadingState extends State
15 | with SingleTickerProviderStateMixin {
16 | AnimationController _ctrl;
17 | Animation animation;
18 |
19 | @override
20 | void initState() {
21 | super.initState();
22 | _ctrl = AnimationController(
23 | vsync: this,
24 | duration: Duration(seconds: 2),
25 | );
26 | animation = Tween(begin: -pi, end: pi).animate(_ctrl);
27 | }
28 |
29 | @override
30 | void dispose() {
31 | _ctrl.dispose();
32 | super.dispose();
33 | }
34 |
35 | @override
36 | Widget build(BuildContext context) {
37 | return GestureDetector(
38 | onTap: () => _ctrl.repeat(reverse: true),
39 | child: CustomPaint(
40 | size: Size(widget.size, widget.size),
41 | painter: OvalLoadingPainter(animation),
42 | ),
43 | );
44 | }
45 | }
46 |
47 | class OvalLoadingPainter extends CustomPainter {
48 | Animation animation;
49 |
50 | OvalLoadingPainter(this.animation, {this.radius = 15, this.a = 0.4})
51 | : super(repaint: animation);
52 |
53 | final Paint _paint = Paint();
54 | final double radius;
55 | final double a;
56 |
57 | @override
58 | void paint(Canvas canvas, Size size) {
59 | canvas.drawRect(
60 | Offset.zero & size, Paint()..color = Colors.grey.withAlpha(11));
61 |
62 | double zoneSize = size.shortestSide / 2;
63 | canvas.translate(size.width / 2, size.height / 2);
64 |
65 | double x = (zoneSize - radius)/pi * f(animation.value);
66 | double y = (zoneSize - radius)/2 * g(animation.value);
67 |
68 | canvas.drawCircle(Offset(x, y), radius, _paint..color = Color(0xffF44336));
69 | }
70 |
71 | double f(double t) => t;
72 | double g(double t) => sin(t);
73 |
74 | @override
75 | bool shouldRepaint(covariant OvalLoadingPainter oldDelegate) =>
76 | oldDelegate.a != a || oldDelegate.animation != animation;
77 | }
78 |
--------------------------------------------------------------------------------
/lib/06_loading/04_ovel/03_oval_last/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'oval_loading.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | // backgroundColor: Colors.black,
24 | body: Center(
25 | child: Wrap(
26 | spacing: 50,
27 | children:[
28 | OvalLoading()
29 | ] ,
30 | ),
31 | ))
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/07_animated_widget/01_RotationTransition/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | void main() {
5 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
6 | SystemChrome.setPreferredOrientations(// 使设备横屏显示
7 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
8 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
9 | runApp(MyApp());
10 | }
11 |
12 | class MyApp extends StatelessWidget {
13 | @override
14 | Widget build(BuildContext context) {
15 | return MaterialApp(
16 | debugShowCheckedModeBanner: false,
17 | title: 'Flutter Demo',
18 | theme: ThemeData(
19 | primarySwatch: Colors.blue,
20 | ),
21 | home: Scaffold(
22 | body: Center(
23 | child: AnimDemo(),
24 | )));
25 | }
26 | }
27 |
28 | class AnimDemo extends StatefulWidget {
29 | @override
30 | _AnimDemoState createState() => _AnimDemoState();
31 | }
32 |
33 | class _AnimDemoState extends State
34 | with SingleTickerProviderStateMixin {
35 | AnimationController _ctrl;
36 | Animation animation;
37 |
38 | @override
39 | void initState() {
40 | super.initState();
41 | _ctrl = AnimationController(
42 | vsync: this,
43 | duration: const Duration(seconds: 2),
44 | );
45 | animation = CurveTween(curve: Curves.linear).animate(_ctrl);
46 | }
47 |
48 | @override
49 | void dispose() {
50 | _ctrl.dispose();
51 | super.dispose();
52 | }
53 |
54 | @override
55 | Widget build(BuildContext context) {
56 | return GestureDetector(
57 | onTap: () => _ctrl.forward(from: 0),
58 | child: Container(
59 | color: Colors.grey.withAlpha(22),
60 | width: 100,
61 | height: 100,
62 | child: RotationTransition(
63 | turns: animation,
64 | child: _buildChild(),
65 | ),
66 | ),
67 | );
68 | }
69 |
70 | Widget _buildChild() => const Icon(
71 | Icons.camera_outlined,
72 | color: Colors.green,
73 | size: 60,
74 | );
75 | }
76 |
--------------------------------------------------------------------------------
/lib/07_animated_widget/02_ScaleTransition/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | void main() {
5 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
6 | SystemChrome.setPreferredOrientations(// 使设备横屏显示
7 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
8 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
9 | runApp(MyApp());
10 | }
11 |
12 | class MyApp extends StatelessWidget {
13 | @override
14 | Widget build(BuildContext context) {
15 | return MaterialApp(
16 | debugShowCheckedModeBanner: false,
17 | title: 'Flutter Demo',
18 | theme: ThemeData(
19 | primarySwatch: Colors.blue,
20 | ),
21 | home: Scaffold(
22 | body: Center(
23 | child: AnimDemo(),
24 | )));
25 | }
26 | }
27 |
28 | class AnimDemo extends StatefulWidget {
29 | @override
30 | _AnimDemoState createState() => _AnimDemoState();
31 | }
32 |
33 | class _AnimDemoState extends State
34 | with SingleTickerProviderStateMixin {
35 | AnimationController _ctrl;
36 | Animation animation;
37 |
38 | @override
39 | void initState() {
40 | super.initState();
41 | _ctrl = AnimationController(
42 | vsync: this,
43 | duration: const Duration(seconds: 2),
44 | );
45 | animation = Tween(begin: 0.3, end: 1.0)
46 | .chain(CurveTween(curve: Curves.ease))
47 | .animate(_ctrl);
48 | }
49 |
50 | @override
51 | void dispose() {
52 | _ctrl.dispose();
53 | super.dispose();
54 | }
55 |
56 | @override
57 | Widget build(BuildContext context) {
58 | return GestureDetector(
59 | onTap: () => _ctrl.forward(from: 0),
60 | child: Container(
61 | color: Colors.grey.withAlpha(22),
62 | width: 100,
63 | height: 100,
64 | child: ScaleTransition(
65 | scale: animation,
66 | child: _buildChild(),
67 | ),
68 | ));
69 | }
70 |
71 | Widget _buildChild() => const Icon(
72 | Icons.camera_outlined,
73 | color: Colors.green,
74 | size: 60,
75 | );
76 | }
77 |
--------------------------------------------------------------------------------
/lib/07_animated_widget/04_AlignTransition/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | void main() {
5 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
6 | SystemChrome.setPreferredOrientations(// 使设备横屏显示
7 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
8 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
9 | runApp(MyApp());
10 | }
11 |
12 | class MyApp extends StatelessWidget {
13 | @override
14 | Widget build(BuildContext context) {
15 | return MaterialApp(
16 | debugShowCheckedModeBanner: false,
17 | title: 'Flutter Demo',
18 | theme: ThemeData(
19 | primarySwatch: Colors.blue,
20 | ),
21 | home: Scaffold(
22 | body: Center(
23 | child: AnimDemo(),
24 | )));
25 | }
26 | }
27 |
28 | class AnimDemo extends StatefulWidget {
29 | @override
30 | _AnimDemoState createState() => _AnimDemoState();
31 | }
32 |
33 | class _AnimDemoState extends State
34 | with SingleTickerProviderStateMixin {
35 | AnimationController _ctrl;
36 | Animation animation;
37 |
38 | @override
39 | void initState() {
40 | super.initState();
41 | _ctrl = AnimationController(
42 | vsync: this,
43 | duration: const Duration(seconds: 2),
44 | );
45 |
46 | animation = AlignmentTween(
47 | begin: Alignment.center,
48 | end: Alignment.bottomRight,
49 | ).chain(CurveTween(curve: Curves.ease)).animate(_ctrl);
50 | }
51 |
52 | @override
53 | void dispose() {
54 | _ctrl.dispose();
55 | super.dispose();
56 | }
57 |
58 | @override
59 | Widget build(BuildContext context) {
60 | return GestureDetector(
61 | onTap: () => _ctrl.forward(from: 0),
62 | child: Container(
63 | color: Colors.grey.withAlpha(22),
64 | width: 200,
65 | height: 100,
66 | child: AlignTransition(
67 | alignment: animation,
68 | child: _buildChild(),
69 | ),
70 | ));
71 | }
72 |
73 | Widget _buildChild() => const Icon(
74 | Icons.accessible_forward_sharp,
75 | color: Colors.green,
76 | size: 25,
77 | );
78 | }
--------------------------------------------------------------------------------
/lib/09_implicitly_animated_widget/01_AnimatedOpacity/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | void main() {
5 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
6 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
7 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
8 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
9 | runApp(MyApp());
10 | }
11 |
12 | class MyApp extends StatelessWidget {
13 | @override
14 | Widget build(BuildContext context) {
15 | return MaterialApp(
16 | debugShowCheckedModeBanner: false,
17 | title: 'Flutter Demo',
18 | theme: ThemeData(
19 | primarySwatch: Colors.blue,
20 | ),
21 | home: Scaffold(
22 | body: Center(
23 | child: AnimDemo(),
24 | )));
25 | }
26 | }
27 |
28 | class AnimDemo extends StatefulWidget {
29 | @override
30 | _AnimDemoState createState() => _AnimDemoState();
31 | }
32 |
33 | class _AnimDemoState extends State {
34 | final double beginOpacity = 1.0;
35 | final double endOpacity = 0;
36 |
37 | double _opacity;
38 |
39 | @override
40 | void initState() {
41 | super.initState();
42 | _opacity = beginOpacity;
43 | }
44 |
45 | bool get selected => _opacity == 0;
46 |
47 | @override
48 | Widget build(BuildContext context) {
49 | return Wrap(
50 | direction: Axis.vertical,
51 | crossAxisAlignment: WrapCrossAlignment.center,
52 | children: [
53 | Switch(
54 | value: selected,
55 | onChanged: onChanged,
56 | ),
57 | Container(
58 | color: Colors.grey.withAlpha(22),
59 | width: 100,
60 | height: 100,
61 | child: buildAnimatedOpacity(),
62 | ),
63 | ],
64 | );
65 | }
66 |
67 | Widget buildAnimatedOpacity() =>
68 | AnimatedOpacity(
69 | duration: const Duration(seconds: 1),
70 | curve: Curves.fastOutSlowIn,
71 | opacity: _opacity,
72 | onEnd: onEnd,
73 | child: _buildChild(),
74 | );
75 |
76 | void onChanged(bool value) {
77 | setState(() {
78 | _opacity = value ? endOpacity : beginOpacity;
79 | });
80 | }
81 |
82 | void onEnd() {
83 | print('End');
84 | }
85 |
86 | Widget _buildChild() =>
87 | const Icon(
88 | Icons.camera_outlined,
89 | color: Colors.green,
90 | size: 60,
91 | );
92 | }
93 |
--------------------------------------------------------------------------------
/lib/09_implicitly_animated_widget/03_AnimatedAlign/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | void main() {
5 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
6 | SystemChrome.setPreferredOrientations(// 使设备横屏显示
7 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
8 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
9 | runApp(MyApp());
10 | }
11 |
12 | class MyApp extends StatelessWidget {
13 | @override
14 | Widget build(BuildContext context) {
15 | return MaterialApp(
16 | debugShowCheckedModeBanner: false,
17 | title: 'Flutter Demo',
18 | theme: ThemeData(
19 | primarySwatch: Colors.blue,
20 | ),
21 | home: Scaffold(
22 | body: Center(
23 | child: AnimDemo(),
24 | )));
25 | }
26 | }
27 |
28 | class AnimDemo extends StatefulWidget {
29 | @override
30 | _AnimDemoState createState() => _AnimDemoState();
31 | }
32 |
33 | class _AnimDemoState extends State {
34 | final Alignment startAlignment = Alignment.center;
35 | final Alignment endAlignment = Alignment.bottomRight;
36 |
37 | Alignment _alignment;
38 |
39 | @override
40 | void initState() {
41 | super.initState();
42 | _alignment = startAlignment;
43 | }
44 |
45 | bool get selected => _alignment == endAlignment;
46 |
47 | @override
48 | Widget build(BuildContext context) {
49 | return Wrap(
50 | direction: Axis.vertical,
51 | crossAxisAlignment: WrapCrossAlignment.center,
52 | children: [
53 | Switch(
54 | value: selected,
55 | onChanged: onChanged,
56 | ),
57 | Container(
58 | width: 200,
59 | height: 100,
60 | alignment: Alignment.center,
61 | color: Colors.grey.withAlpha(22),
62 | child: buildAnim())
63 | ],
64 | );
65 | }
66 |
67 | Widget buildAnim() => AnimatedAlign(
68 | duration: Duration(seconds: 1),
69 | curve: Curves.fastOutSlowIn,
70 | alignment: _alignment,
71 | onEnd: onEnd,
72 | child: const Icon(
73 | Icons.accessible_forward_sharp,
74 | color: Colors.green,
75 | size: 25,
76 | ),
77 | );
78 |
79 |
80 | void onChanged(bool value) {
81 | setState(() {
82 | _alignment = value ? endAlignment : startAlignment;
83 | });
84 | }
85 |
86 | void onEnd() {
87 | print('End');
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/lib/09_implicitly_animated_widget/05_TweenAnimationBuilder/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | void main() {
5 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
6 | SystemChrome.setPreferredOrientations(// 使设备横屏显示
7 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
8 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
9 | runApp(MyApp());
10 | }
11 |
12 | class MyApp extends StatelessWidget {
13 | @override
14 | Widget build(BuildContext context) {
15 | return MaterialApp(
16 | debugShowCheckedModeBanner: false,
17 | title: 'Flutter Demo',
18 | theme: ThemeData(
19 | primarySwatch: Colors.blue,
20 | ),
21 | home: Scaffold(
22 | body: Center(
23 | child: AnimDemo(),
24 | )));
25 | }
26 | }
27 |
28 | class AnimDemo extends StatefulWidget {
29 | @override
30 | _AnimDemoState createState() => _AnimDemoState();
31 | }
32 |
33 | class _AnimDemoState extends State {
34 | bool _selected = false;
35 |
36 | Color color1 = Colors.red;
37 | Color color2 = Colors.orange;
38 |
39 | @override
40 | Widget build(BuildContext context) {
41 | return Wrap(
42 | direction: Axis.vertical,
43 | crossAxisAlignment: WrapCrossAlignment.center,
44 | children: [
45 | Switch(
46 | value: _selected,
47 | onChanged: onChanged,
48 | ),
49 | buildAnim()
50 | ],
51 | );
52 | }
53 |
54 | Widget buildAnim() => TweenAnimationBuilder(
55 | tween: ColorTween(begin: Colors.blue, end: _selected?color1:color2),
56 | duration: Duration(seconds: 1),
57 | builder: (_, Color color, Widget child) => Container(
58 | width: 60,
59 | height: 60,
60 | child: child,
61 | decoration: BoxDecoration(
62 | color: color,
63 | borderRadius: BorderRadius.circular(8),
64 | ),
65 | ),
66 | child: _buildChild(),
67 | );
68 |
69 | Widget _buildChild() => const Icon(
70 | Icons.camera_outlined,
71 | size: 30,
72 | color: Colors.white,
73 | );
74 |
75 | void onChanged(bool value) {
76 | setState(() {
77 | _selected = !_selected;
78 | });
79 | }
80 |
81 | void onEnd() {
82 | print('End');
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/lib/11_other/01_painter/01_AnimatedIcon/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | void main() {
5 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
6 | SystemChrome.setPreferredOrientations(// 使设备横屏显示
7 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
8 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
9 | runApp(MyApp());
10 | }
11 |
12 | class MyApp extends StatelessWidget {
13 | @override
14 | Widget build(BuildContext context) {
15 | return MaterialApp(
16 | debugShowCheckedModeBanner: false,
17 | title: 'Flutter Demo',
18 | theme: ThemeData(
19 | primarySwatch: Colors.blue,
20 | ),
21 | home: Scaffold(
22 | body: Center(
23 | child: AnimDemo(),
24 | )));
25 | }
26 | }
27 |
28 | class AnimDemo extends StatefulWidget {
29 | @override
30 | _AnimDemoState createState() => _AnimDemoState();
31 | }
32 |
33 | class _AnimDemoState extends State with SingleTickerProviderStateMixin{
34 | AnimationController _ctrl;
35 |
36 | @override
37 | void initState() {
38 | super.initState();
39 | _ctrl = AnimationController(
40 | vsync: this,
41 | duration: const Duration(seconds: 1),
42 | );
43 | }
44 |
45 | @override
46 | void dispose() {
47 | _ctrl.dispose();
48 | super.dispose();
49 | }
50 |
51 | @override
52 | Widget build(BuildContext context) {
53 | return GestureDetector(
54 | onTap: () => _ctrl.forward(from: 0),
55 | child: AnimatedIcon(
56 | size: 50,
57 | color: Colors.green,
58 | icon: AnimatedIcons.arrow_menu,
59 | progress: _ctrl,
60 | ),
61 | );
62 | }
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/lib/11_other/01_painter/02_CupertinoActivityIndicator/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter/services.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations(// 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: AnimDemo(),
25 | )));
26 | }
27 | }
28 |
29 | class AnimDemo extends StatefulWidget {
30 | @override
31 | _AnimDemoState createState() => _AnimDemoState();
32 | }
33 |
34 | class _AnimDemoState extends State with SingleTickerProviderStateMixin{
35 | bool _animating = true;
36 |
37 | @override
38 | Widget build(BuildContext context) {
39 | return Wrap(
40 | direction: Axis.vertical,
41 | crossAxisAlignment: WrapCrossAlignment.center,
42 | children: [
43 | Switch(
44 | value: _animating,
45 | onChanged: onChanged,
46 | ),
47 | CupertinoActivityIndicator(
48 | animating: _animating,
49 | radius: 20,
50 | ),
51 | ],
52 | );
53 | }
54 |
55 | void onChanged(bool value) {
56 | setState(() {
57 | _animating = !_animating;
58 | });
59 | }
60 | }
61 |
62 |
--------------------------------------------------------------------------------
/lib/11_other/02_other/01_AnimatedCrossFade/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | void main() {
5 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
6 | SystemChrome.setPreferredOrientations(// 使设备横屏显示
7 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
8 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
9 | runApp(MyApp());
10 | }
11 |
12 | class MyApp extends StatelessWidget {
13 | @override
14 | Widget build(BuildContext context) {
15 | return MaterialApp(
16 | debugShowCheckedModeBanner: false,
17 | title: 'Flutter Demo',
18 | theme: ThemeData(
19 | primarySwatch: Colors.blue,
20 | ),
21 | home: Scaffold(
22 | body: Center(
23 | child: AnimDemo(),
24 | )));
25 | }
26 | }
27 |
28 | class AnimDemo extends StatefulWidget {
29 | @override
30 | _AnimDemoState createState() => _AnimDemoState();
31 | }
32 |
33 | class _AnimDemoState extends State {
34 | var _crossFadeState = CrossFadeState.showFirst;
35 |
36 | bool get isFirst => _crossFadeState == CrossFadeState.showFirst;
37 |
38 | @override
39 | Widget build(BuildContext context) {
40 | return Wrap(
41 | direction: Axis.vertical,
42 | crossAxisAlignment: WrapCrossAlignment.center,
43 | children: [
44 | Switch(
45 | value: isFirst,
46 | onChanged: _onChanged,
47 | ),
48 | AnimatedCrossFade(
49 | firstCurve: Curves.easeInCirc,
50 | secondCurve: Curves.easeInToLinear,
51 | sizeCurve: Curves.bounceOut,
52 | firstChild: buildFirstChild(),
53 | secondChild: buildSecondChild(),
54 | duration: Duration(milliseconds: 1000),
55 | crossFadeState: _crossFadeState,
56 | ),
57 | ],
58 | );
59 | }
60 |
61 | Widget buildFirstChild() => Container(
62 | height: 60,
63 | width: 60,
64 | color: Colors.grey.withAlpha(22),
65 | alignment: Alignment.center,
66 | child: const FlutterLogo(
67 | size: 40,
68 | ),
69 | );
70 |
71 | Widget buildSecondChild() => Image.asset(
72 | "assets/images/icon_head.jpg",
73 | height: 100,
74 | width: 100,
75 | );
76 |
77 | void _onChanged(bool value) {
78 | setState(() {
79 | _crossFadeState =
80 | value ? CrossFadeState.showFirst : CrossFadeState.showSecond;
81 | });
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/lib/11_other/04_router/01_common/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | void main() {
4 | runApp(MyApp());
5 | }
6 |
7 | class MyApp extends StatelessWidget {
8 | @override
9 | Widget build(BuildContext context) {
10 | return MaterialApp(
11 | debugShowCheckedModeBanner: false,
12 | title: 'Flutter Demo',
13 | theme: ThemeData(
14 | primarySwatch: Colors.blue,
15 | ),
16 | home: GreenPage());
17 | }
18 | }
19 |
20 | class GreenPage extends StatelessWidget {
21 | const GreenPage({Key key}) : super(key: key);
22 |
23 | @override
24 | Widget build(BuildContext context) {
25 | return Scaffold(
26 | backgroundColor: Colors.green,
27 | appBar: AppBar(
28 | title: const Text('GreenPage'),
29 | actions: [
30 | IconButton(
31 | onPressed: () => _toRed(context),
32 | icon: Icon(Icons.navigate_next),
33 | )
34 | ],
35 | ),
36 | );
37 | }
38 |
39 | void _toRed(BuildContext context) {
40 | Navigator.of(context).push(
41 | MaterialPageRoute(builder: (ctx) => RedPage()),
42 | );
43 | }
44 | }
45 |
46 | class RedPage extends StatelessWidget {
47 | const RedPage({Key key}) : super(key: key);
48 |
49 | @override
50 | Widget build(BuildContext context) {
51 | return Scaffold(
52 | backgroundColor: Colors.red,
53 | appBar: AppBar(
54 | title: const Text('RedPage'),
55 | ),
56 | );
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/lib/11_other/04_router/02_anim/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | void main() {
4 | runApp(MyApp());
5 | }
6 |
7 | class MyApp extends StatelessWidget {
8 | @override
9 | Widget build(BuildContext context) {
10 | return MaterialApp(
11 | debugShowCheckedModeBanner: false,
12 | title: 'Flutter Demo',
13 | theme: ThemeData(
14 | primarySwatch: Colors.blue,
15 | ),
16 | home: GreenPage());
17 | }
18 | }
19 |
20 | class GreenPage extends StatelessWidget {
21 | const GreenPage({Key key}) : super(key: key);
22 |
23 | @override
24 | Widget build(BuildContext context) {
25 | return Scaffold(
26 | backgroundColor: Colors.green,
27 | appBar: AppBar(
28 | title: const Text('GreenPage'),
29 | actions: [
30 | IconButton(
31 | onPressed: () => _toRed(context),
32 | icon: Icon(Icons.navigate_next),
33 | )
34 | ],
35 | ),
36 | );
37 | }
38 |
39 | void _toRed(BuildContext context) {
40 | Navigator.of(context).push(
41 | PageRouteBuilder(
42 | pageBuilder: (ctx, a1, a2) => RedPage(),
43 | transitionDuration: const Duration(milliseconds: 300),
44 | reverseTransitionDuration: const Duration(milliseconds: 300),
45 | transitionsBuilder: _buildTransitions),
46 | );
47 | }
48 |
49 | Widget _buildTransitions(
50 | BuildContext context,
51 | Animation animation,
52 | Animation secondaryAnimation,
53 | Widget child,
54 | ) {
55 | return SlideTransition(
56 | position: Tween(
57 | begin: const Offset(1.0, 0),
58 | end: Offset.zero,
59 | ).animate(animation),
60 | child: FadeTransition(
61 | opacity: Tween(
62 | begin: 0.5,
63 | end: 1.0)
64 | .animate(animation),
65 | child: child,
66 | ),
67 | );
68 | }
69 | }
70 |
71 |
72 | class RedPage extends StatelessWidget {
73 | const RedPage({Key key}) : super(key: key);
74 |
75 | @override
76 | Widget build(BuildContext context) {
77 | return Scaffold(
78 | backgroundColor: Colors.red,
79 | appBar: AppBar(
80 | title: const Text('RedPage'),
81 | ),
82 | );
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/lib/14/debug/circle_anim.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class CircleAnim extends StatefulWidget {
4 | @override
5 | _CircleAnimState createState() => _CircleAnimState();
6 | }
7 |
8 | class _CircleAnimState extends State
9 | with SingleTickerProviderStateMixin {
10 | AnimationController _ctrl;
11 |
12 | @override
13 | void initState() {
14 | super.initState();
15 | _ctrl = AnimationController(
16 | vsync: this,
17 | duration: const Duration(milliseconds: 1000),
18 | )..addListener(() {
19 | print("------${_ctrl.value}----${DateTime.now().toIso8601String()}----------");
20 | });
21 | }
22 |
23 | @override
24 | void dispose() {
25 | _ctrl.dispose();
26 | super.dispose();
27 | }
28 |
29 | @override
30 | Widget build(BuildContext context) {
31 | return GestureDetector(
32 | onTap: _startAnim,
33 | child:Container(
34 | width: 60,
35 | height: 60,
36 | color: Colors.green,
37 | ));
38 | }
39 |
40 | Color get color => Color.lerp(Colors.blue, Colors.red, _ctrl.value);
41 |
42 | Widget _buildByAnim(_, __) => Container(
43 | width: 80,
44 | height: 80,
45 | decoration: BoxDecoration(color: color, shape: BoxShape.circle),
46 | );
47 |
48 | void _startAnim() {
49 | _ctrl.forward(from: 0);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/lib/14/debug/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'circle_anim.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: CircleAnim(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/15_ticker/ticker/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'ticker_demo.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: TickerDemo(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/15_ticker/ticker/ticker_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/scheduler.dart';
3 |
4 | class TickerDemo extends StatefulWidget {
5 | @override
6 | _TickerDemoState createState() => _TickerDemoState();
7 | }
8 |
9 | class _TickerDemoState extends State {
10 | Ticker _ticker;
11 |
12 | @override
13 | void initState() {
14 | super.initState();
15 | // SchedulerBinding.instance.scheduleFrameCallback(_tick);
16 | _ticker = Ticker(_tick);
17 | }
18 |
19 | void _tick(Duration elapsed) {
20 | print('----elapsed:$elapsed---${TimeOfDay.now()}------------');
21 | }
22 |
23 | @override
24 | void dispose() {
25 | _ticker.dispose();
26 | super.dispose();
27 | }
28 |
29 | @override
30 | Widget build(BuildContext context) {
31 | return GestureDetector(
32 | onTap: _startTicker,
33 | child: Container(
34 | width: 60,
35 | height: 60,
36 | color: Colors.green,
37 | ));
38 | }
39 |
40 | void _startTicker() {
41 |
42 | if (_ticker.isTicking) {
43 | _ticker.stop();
44 | } else {
45 | _ticker.start().then((v) {
46 | print('start finish!');
47 | });
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/lib/15_ticker/ticker_muted/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'ticker_demo.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: TickerDemo(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/15_ticker/ticker_muted/ticker_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/scheduler.dart';
3 |
4 | class TickerDemo extends StatefulWidget {
5 | @override
6 | _TickerDemoState createState() => _TickerDemoState();
7 | }
8 |
9 | class _TickerDemoState extends State {
10 | Ticker _ticker;
11 |
12 | @override
13 | void initState() {
14 | super.initState();
15 | // SchedulerBinding.instance.scheduleFrameCallback(_tick);
16 | _ticker = Ticker(_tick)..start();
17 | }
18 |
19 | void _tick(Duration elapsed) {
20 | print('----elapsed:$elapsed---${DateTime.now().toIso8601String()}------------');
21 | }
22 |
23 | @override
24 | void dispose() {
25 | _ticker.dispose();
26 | super.dispose();
27 | }
28 |
29 | @override
30 | Widget build(BuildContext context) {
31 | return GestureDetector(
32 | onTap: _startTicker,
33 | child: Container(
34 | width: 60,
35 | height: 60,
36 | color: Colors.green,
37 | ));
38 | }
39 |
40 | void _startTicker() {
41 | if (_ticker.muted) {
42 | _ticker.muted = false;
43 | } else {
44 | _ticker.muted = true;
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/lib/15_ticker/ticker_provider/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'ticker_demo.dart';
4 |
5 | void main() {
6 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
7 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
8 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
9 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title: 'Flutter Demo',
19 | theme: ThemeData(
20 | primarySwatch: Colors.blue,
21 | ),
22 | home: Scaffold(
23 | body: Center(
24 | child: TickerDemo(),
25 | ))
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/15_ticker/ticker_provider/ticker_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class TickerDemo extends StatefulWidget {
4 | @override
5 | _TickerDemoState createState() => _TickerDemoState();
6 | }
7 |
8 | class _TickerDemoState extends State with SingleTickerProviderStateMixin {
9 | AnimationController _ctrlA;
10 |
11 | final Duration animDuration = const Duration(milliseconds: 2000);
12 |
13 | @override
14 | void initState() {
15 | super.initState();
16 | _ctrlA = AnimationController(
17 | value: 0.4,
18 | vsync: this,
19 | duration: animDuration,
20 | );
21 |
22 |
23 | }
24 |
25 | @override
26 | void dispose() {
27 | _ctrlA.dispose();
28 |
29 | super.dispose();
30 | }
31 |
32 | @override
33 | Widget build(BuildContext context) {
34 | return GestureDetector(
35 | onTap: _start,
36 | child: Container(
37 | width: 60,
38 | height: 60,
39 | color: Colors.green,
40 | ));
41 | }
42 |
43 | void _start() {}
44 | }
45 |
--------------------------------------------------------------------------------
/lib/16_clock/01/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | import 'clock_widget.dart';
5 |
6 |
7 | void main() {
8 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
9 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
10 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
11 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
12 | runApp(MyApp());
13 | }
14 |
15 | class MyApp extends StatelessWidget {
16 | @override
17 | Widget build(BuildContext context) {
18 | return MaterialApp(
19 | debugShowCheckedModeBanner: false,
20 | title: 'Flutter Demo',
21 | theme: ThemeData(
22 | primarySwatch: Colors.blue,
23 | ),
24 | home: Scaffold(
25 | body: Center(
26 | child: ClockWidget(),
27 | ))
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/16_clock/02/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | import 'clock_widget.dart';
5 |
6 |
7 | void main() {
8 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
9 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
10 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
11 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
12 | runApp(MyApp());
13 | }
14 |
15 | class MyApp extends StatelessWidget {
16 | @override
17 | Widget build(BuildContext context) {
18 | return MaterialApp(
19 | debugShowCheckedModeBanner: false,
20 | title: 'Flutter Demo',
21 | theme: ThemeData(
22 | primarySwatch: Colors.blue,
23 | ),
24 | home: Scaffold(
25 | body: Center(
26 | child: ClockWidget(),
27 | ))
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/16_clock/03/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | import 'clock_widget.dart';
5 |
6 |
7 | void main() {
8 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
9 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
10 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
11 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
12 | runApp(MyApp());
13 | }
14 |
15 | class MyApp extends StatelessWidget {
16 | @override
17 | Widget build(BuildContext context) {
18 | return MaterialApp(
19 | debugShowCheckedModeBanner: false,
20 | title: 'Flutter Demo',
21 | theme: ThemeData(
22 | primarySwatch: Colors.blue,
23 | ),
24 | home: Scaffold(
25 | body: Center(
26 | child: ClockWidget(),
27 | ))
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/16_clock/04_stack/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | import 'clock_widget.dart';
5 |
6 |
7 | void main() {
8 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
9 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
10 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
11 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
12 | runApp(MyApp());
13 | }
14 |
15 | class MyApp extends StatelessWidget {
16 | @override
17 | Widget build(BuildContext context) {
18 | return MaterialApp(
19 | debugShowCheckedModeBanner: false,
20 | title: 'Flutter Demo',
21 | theme: ThemeData(
22 | primarySwatch: Colors.blue,
23 | ),
24 | home: Scaffold(
25 | body: Center(
26 | child: ClockWidget(),
27 | ))
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/16_clock/05_last/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | import 'clock_widget.dart';
5 |
6 |
7 | void main() {
8 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
9 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
10 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
11 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
12 | runApp(MyApp());
13 | }
14 |
15 | class MyApp extends StatelessWidget {
16 | @override
17 | Widget build(BuildContext context) {
18 | return MaterialApp(
19 | debugShowCheckedModeBanner: false,
20 | title: 'Flutter Demo',
21 | theme: ThemeData(
22 | primarySwatch: Colors.blue,
23 | ),
24 | home: Scaffold(
25 | body: Center(
26 | child: ClockWidget(),
27 | ))
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/16_clock/06_lizi/01/clock_fx.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter/widgets.dart';
5 |
6 | import 'particle.dart';
7 |
8 |
9 | final Color transparent = Color.fromARGB(0, 0, 0, 0);
10 |
11 | abstract class ClockFx with ChangeNotifier {
12 | /// The available canvas width for the FX.
13 | double width;
14 |
15 | /// The available canvas height for the FX.
16 | double height;
17 |
18 | /// The minimum value of [width] and [height].
19 | double sizeMin;
20 |
21 | /// The center of the canvas.
22 | Offset center;
23 |
24 | /// The area from wich to spawn new particles.
25 | Rect spawnArea;
26 |
27 | /// The colors used for painting.
28 | // Palette palette;
29 |
30 | /// All the FX's particles.
31 | List particles;
32 |
33 | /// The maximum number of particles.
34 | int numParticles;
35 |
36 | /// Date and time used for rendering time-specific effects.
37 | DateTime time;
38 |
39 | ClockFx({
40 | @required Size size,
41 | @required DateTime time,
42 | this.numParticles = 5000,
43 | }) {
44 | this.time = time;
45 | particles = List.filled(numParticles, null);
46 | setSize(size);
47 | }
48 |
49 | /// Initializes the particle effect by resetting all the particles and assigning a random color from the palette.
50 | void init() {
51 | // if (palette == null) return;
52 | for (int i = 0; i < numParticles; i++) {
53 | // var color = Rnd.getItem(palette.components);
54 | particles[i] = Particle(color:Colors.black );
55 | resetParticle(i);
56 | }
57 | }
58 |
59 | /// Sets the time used for time-specific effects.
60 | void setTime(DateTime time) {
61 | this.time = time;
62 | }
63 |
64 | /// Sets the canvas size and updates dependent values.
65 | void setSize(Size size) {
66 | width = size.width;
67 | height = size.height;
68 | sizeMin = min(width, height);
69 | center = Offset(width / 2, height / 2);
70 | spawnArea = Rect.fromLTRB(
71 | center.dx - sizeMin / 100,
72 | center.dy - sizeMin / 100,
73 | center.dx + sizeMin / 100,
74 | center.dy + sizeMin / 100,
75 | );
76 | init();
77 | }
78 |
79 | /// Resets a particle's values.
80 | Particle resetParticle(int i) {
81 | Particle p = particles[i];
82 | p.size = p.a = p.vx = p.vy = p.life = p.lifeLeft = 0;
83 | p.x = center.dx;
84 | p.y = center.dy;
85 | return p;
86 | }
87 |
88 | void tick(Duration duration) {
89 | notifyListeners();
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/lib/16_clock/06_lizi/01/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | import 'clock_widget.dart';
5 |
6 |
7 | void main() {
8 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
9 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
10 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
11 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
12 | runApp(MyApp());
13 | }
14 |
15 | class MyApp extends StatelessWidget {
16 | @override
17 | Widget build(BuildContext context) {
18 | return MaterialApp(
19 | debugShowCheckedModeBanner: false,
20 | title: 'Flutter Demo',
21 | theme: ThemeData(
22 | primarySwatch: Colors.blue,
23 | ),
24 | home: Scaffold(
25 | body: Center(
26 | child: ClockWidget(),
27 | ))
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/16_clock/06_lizi/01/particle.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter/widgets.dart';
5 |
6 | class Particle {
7 |
8 | double x; // x 坐标
9 | double y; // y 坐标
10 | double vx; // x 速度
11 | double vy; // y 速度
12 | double a; // 发射弧度
13 | double dist; // 距离画布中心的长度
14 | double distFrac;// 距离画布中心的百分比
15 | double size;// 粒子大小
16 | double life; // 粒子寿命
17 | double lifeLeft; // 粒子剩余寿命
18 | bool isFilled; // 是否填充
19 | Color color; // 颜色
20 | int distribution; // 描述
21 |
22 |
23 | Particle({
24 | this.x = 0,
25 | this.y = 0,
26 | this.a = 0,
27 | this.vx = 0,
28 | this.vy = 0,
29 | this.dist = 0,
30 | this.distFrac = 0,
31 | this.size = 0,
32 | this.life = 0,
33 | this.lifeLeft = 0,
34 | this.isFilled = false,
35 | this.color = Colors.blueAccent,
36 | this.distribution = 0,
37 | });
38 | }
39 |
40 |
41 |
--------------------------------------------------------------------------------
/lib/16_clock/06_lizi/01/utils/rnd.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 |
3 |
4 | class Rnd {
5 | static int _seed = DateTime.now().millisecondsSinceEpoch;
6 | static Random random = Random(_seed);
7 |
8 | static set seed(int val) => random = Random(_seed = val);
9 | static int get seed => _seed;
10 |
11 | /// Gets the next double.
12 | static get ratio => random.nextDouble();
13 |
14 | /// Gets a random int between [min] and [max].
15 | static int getInt(int min, int max) {
16 | return min + random.nextInt(max - min);
17 | }
18 |
19 | /// Gets a random double between [min] and [max].
20 | static double getDouble(double min, double max) {
21 | return min + random.nextDouble() * (max - min);
22 | }
23 |
24 | /// Gets a random boolean with chance [chance].
25 | static bool getBool([double chance = 0.5]) {
26 | return random.nextDouble() < chance;
27 | }
28 |
29 | /// Randomize the positions of items in a list.
30 | static List shuffle(List list) {
31 | for (int i = 0, l = list.length; i < l; i++) {
32 | int j = random.nextInt(l);
33 | if (j == i) {
34 | continue;
35 | }
36 | dynamic item = list[j];
37 | list[j] = list[i];
38 | list[i] = item;
39 | }
40 | return list;
41 | }
42 |
43 | /// Randomly selects an item from a list.
44 | static dynamic getItem(List list) {
45 | return list[random.nextInt(list.length)];
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/lib/16_clock/06_lizi/02/clock_widget.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 | import 'dart:ui';
3 |
4 | import 'package:flutter/foundation.dart';
5 | import 'package:flutter/material.dart';
6 | import 'package:flutter/scheduler.dart';
7 |
8 | import 'clock_fx.dart';
9 |
10 | /// create by 张风捷特烈 on 2021/2/7
11 | /// contact me by email 1981462002@qq.com
12 | /// 说明:
13 |
14 | class ClockWidget extends StatefulWidget {
15 | final double radius;
16 |
17 | const ClockWidget({Key key, this.radius = 100}) : super(key: key);
18 |
19 | @override
20 | _ClockWidgetState createState() => _ClockWidgetState();
21 | }
22 |
23 | class _ClockWidgetState extends State
24 | with SingleTickerProviderStateMixin {
25 | Ticker _ticker;
26 | ClockFx _fx;
27 |
28 | @override
29 | void initState() {
30 | super.initState();
31 | _ticker = createTicker(_tick)..start();
32 | _fx = ClockFx(
33 | size: Size(widget.radius * 2, widget.radius * 2),
34 | time: DateTime.now(),
35 | );
36 | }
37 |
38 | @override
39 | void dispose() {
40 | _ticker.dispose();
41 | _fx.dispose();
42 | super.dispose();
43 | }
44 |
45 | void _tick(Duration duration) {
46 | _fx.tick(duration);
47 | if (_fx.time.second != DateTime.now().second) {
48 | _fx.setTime(DateTime.now());
49 | }
50 | }
51 |
52 | @override
53 | Widget build(BuildContext context) {
54 | return CustomPaint(
55 | size: Size(widget.radius * 2, widget.radius * 2),
56 | painter: ClockFxPainter(fx: _fx),
57 | );
58 | }
59 | }
60 |
61 | /// Alpha value for noise particles.
62 | const double noiseAlpha = 160;
63 |
64 | class ClockFxPainter extends CustomPainter {
65 | final ClockFx fx;
66 |
67 | ClockFxPainter({@required this.fx}) : super(repaint: fx);
68 |
69 | @override
70 | void paint(Canvas canvas, Size size) {
71 | fx.particles.forEach((p) {
72 | double a;
73 | a = max(0.0, (p.distFrac - .13) / p.distFrac) * 255;
74 | a = min(a, min(noiseAlpha, p.lifeLeft * 3 * 255));
75 | int alpha = a.floor();
76 |
77 | Paint circlePaint = Paint()
78 | ..style = PaintingStyle.fill
79 | ..color = p.color.withAlpha(alpha);
80 |
81 | canvas.drawCircle(Offset(p.x, p.y), p.size, circlePaint);
82 | });
83 | }
84 |
85 | @override
86 | bool shouldRepaint(covariant ClockFxPainter oldDelegate) =>
87 | oldDelegate.fx != fx;
88 | }
89 |
--------------------------------------------------------------------------------
/lib/16_clock/06_lizi/02/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | import 'clock_widget.dart';
5 |
6 |
7 | void main() {
8 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
9 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
10 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
11 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
12 | runApp(MyApp());
13 | }
14 |
15 | class MyApp extends StatelessWidget {
16 | @override
17 | Widget build(BuildContext context) {
18 | return MaterialApp(
19 | debugShowCheckedModeBanner: false,
20 | title: 'Flutter Demo',
21 | theme: ThemeData(
22 | primarySwatch: Colors.blue,
23 | ),
24 | home: Scaffold(
25 | body: Center(
26 | child: ClockWidget(),
27 | ))
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/16_clock/06_lizi/02/particle.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter/widgets.dart';
5 |
6 | class Particle {
7 |
8 | double x; // x 坐标
9 | double y; // y 坐标
10 | double vx; // x 速度
11 | double vy; // y 速度
12 | double a; // 发射弧度
13 | double dist; // 距离画布中心的长度
14 | double distFrac;// 距离画布中心的百分比
15 | double size;// 粒子大小
16 | double life; // 粒子寿命
17 | double lifeLeft; // 粒子剩余寿命
18 | bool isFilled; // 是否填充
19 | Color color; // 颜色
20 | int distribution; // 分配情况
21 |
22 |
23 | Particle({
24 | this.x = 0,
25 | this.y = 0,
26 | this.a = 0,
27 | this.vx = 0,
28 | this.vy = 0,
29 | this.dist = 0,
30 | this.distFrac = 0,
31 | this.size = 0,
32 | this.life = 0,
33 | this.lifeLeft = 0,
34 | this.isFilled = false,
35 | this.color = Colors.blueAccent,
36 | this.distribution = 0,
37 | });
38 | }
39 |
40 |
41 |
--------------------------------------------------------------------------------
/lib/16_clock/06_lizi/02/utils/rnd.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 |
3 |
4 | class Rnd {
5 | static int _seed = DateTime.now().millisecondsSinceEpoch;
6 | static Random random = Random(_seed);
7 |
8 | static set seed(int val) => random = Random(_seed = val);
9 | static int get seed => _seed;
10 |
11 | /// Gets the next double.
12 | static get ratio => random.nextDouble();
13 |
14 | /// Gets a random int between [min] and [max].
15 | static int getInt(int min, int max) {
16 | return min + random.nextInt(max - min);
17 | }
18 |
19 | /// Gets a random double between [min] and [max].
20 | static double getDouble(double min, double max) {
21 | return min + random.nextDouble() * (max - min);
22 | }
23 |
24 | /// Gets a random boolean with chance [chance].
25 | static bool getBool([double chance = 0.5]) {
26 | return random.nextDouble() < chance;
27 | }
28 |
29 | /// Randomize the positions of items in a list.
30 | static List shuffle(List list) {
31 | for (int i = 0, l = list.length; i < l; i++) {
32 | int j = random.nextInt(l);
33 | if (j == i) {
34 | continue;
35 | }
36 | dynamic item = list[j];
37 | list[j] = list[i];
38 | list[i] = item;
39 | }
40 | return list;
41 | }
42 |
43 | /// Randomly selects an item from a list.
44 | static dynamic getItem(List list) {
45 | return list[random.nextInt(list.length)];
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/lib/16_clock/06_lizi/03/clock_widget.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 | import 'dart:ui';
3 |
4 | import 'package:flutter/foundation.dart';
5 | import 'package:flutter/material.dart';
6 | import 'package:flutter/scheduler.dart';
7 |
8 | import 'clock_fx.dart';
9 |
10 | /// create by 张风捷特烈 on 2021/2/7
11 | /// contact me by email 1981462002@qq.com
12 | /// 说明:
13 |
14 | class ClockWidget extends StatefulWidget {
15 | final double radius;
16 |
17 | const ClockWidget({Key key, this.radius = 100}) : super(key: key);
18 |
19 | @override
20 | _ClockWidgetState createState() => _ClockWidgetState();
21 | }
22 |
23 | class _ClockWidgetState extends State
24 | with SingleTickerProviderStateMixin {
25 | Ticker _ticker;
26 | ClockFx _fx;
27 |
28 | @override
29 | void initState() {
30 | super.initState();
31 | _ticker = createTicker(_tick)..start();
32 | _fx = ClockFx(
33 | size: Size(widget.radius * 2, widget.radius * 2),
34 | time: DateTime.now(),
35 | );
36 | }
37 |
38 | @override
39 | void dispose() {
40 | _ticker.dispose();
41 | _fx.dispose();
42 | super.dispose();
43 | }
44 |
45 | void _tick(Duration duration) {
46 | _fx.tick(duration);
47 | if (_fx.time.second != DateTime.now().second) {
48 | _fx.setTime(DateTime.now());
49 | }
50 | }
51 |
52 | @override
53 | Widget build(BuildContext context) {
54 | return CustomPaint(
55 | size: Size(widget.radius * 2, widget.radius * 2),
56 | painter: ClockFxPainter(fx: _fx),
57 | );
58 | }
59 | }
60 |
61 | /// Alpha value for noise particles.
62 | const double noiseAlpha = 160;
63 |
64 | class ClockFxPainter extends CustomPainter {
65 | final ClockFx fx;
66 |
67 | ClockFxPainter({@required this.fx}) : super(repaint: fx);
68 |
69 | @override
70 | void paint(Canvas canvas, Size size) {
71 | fx.particles.forEach((p) {
72 | double a;
73 | a = max(0.0, (p.distFrac - .13) / p.distFrac) * 255;
74 | a = min(a, min(noiseAlpha, p.lifeLeft * 3 * 255));
75 | int alpha = a.floor();
76 |
77 | Paint circlePaint = Paint()
78 | ..style = PaintingStyle.fill
79 | ..color = p.color.withAlpha(alpha);
80 |
81 | canvas.drawCircle(Offset(p.x, p.y), p.size, circlePaint);
82 | });
83 | }
84 |
85 | @override
86 | bool shouldRepaint(covariant ClockFxPainter oldDelegate) =>
87 | oldDelegate.fx != fx;
88 | }
89 |
--------------------------------------------------------------------------------
/lib/16_clock/06_lizi/03/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | import 'clock_widget.dart';
5 |
6 |
7 | void main() {
8 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
9 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
10 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
11 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
12 | runApp(MyApp());
13 | }
14 |
15 | class MyApp extends StatelessWidget {
16 | @override
17 | Widget build(BuildContext context) {
18 | return MaterialApp(
19 | debugShowCheckedModeBanner: false,
20 | title: 'Flutter Demo',
21 | theme: ThemeData(
22 | primarySwatch: Colors.blue,
23 | ),
24 | home: Scaffold(
25 | body: Center(
26 | child: ClockWidget(),
27 | ))
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/16_clock/06_lizi/03/particle.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter/widgets.dart';
5 |
6 | class Particle {
7 |
8 | double x; // x 坐标
9 | double y; // y 坐标
10 | double vx; // x 速度
11 | double vy; // y 速度
12 | double a; // 发射弧度
13 | double dist; // 距离画布中心的长度
14 | double distFrac;// 距离画布中心的百分比
15 | double size;// 粒子大小
16 | double life; // 粒子寿命
17 | double lifeLeft; // 粒子剩余寿命
18 | bool isFilled; // 是否填充
19 | Color color; // 颜色
20 | int distribution; // 分配情况
21 |
22 |
23 | Particle({
24 | this.x = 0,
25 | this.y = 0,
26 | this.a = 0,
27 | this.vx = 0,
28 | this.vy = 0,
29 | this.dist = 0,
30 | this.distFrac = 0,
31 | this.size = 0,
32 | this.life = 0,
33 | this.lifeLeft = 0,
34 | this.isFilled = false,
35 | this.color = Colors.blueAccent,
36 | this.distribution = 0,
37 | });
38 | }
39 |
40 |
41 |
--------------------------------------------------------------------------------
/lib/16_clock/06_lizi/03/utils/rnd.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 |
3 |
4 | class Rnd {
5 | static int _seed = DateTime.now().millisecondsSinceEpoch;
6 | static Random random = Random(_seed);
7 |
8 | static set seed(int val) => random = Random(_seed = val);
9 | static int get seed => _seed;
10 |
11 | /// Gets the next double.
12 | static get ratio => random.nextDouble();
13 |
14 | /// Gets a random int between [min] and [max].
15 | static int getInt(int min, int max) {
16 | return min + random.nextInt(max - min);
17 | }
18 |
19 | /// Gets a random double between [min] and [max].
20 | static double getDouble(double min, double max) {
21 | return min + random.nextDouble() * (max - min);
22 | }
23 |
24 | /// Gets a random boolean with chance [chance].
25 | static bool getBool([double chance = 0.5]) {
26 | return random.nextDouble() < chance;
27 | }
28 |
29 | /// Randomize the positions of items in a list.
30 | static List shuffle(List list) {
31 | for (int i = 0, l = list.length; i < l; i++) {
32 | int j = random.nextInt(l);
33 | if (j == i) {
34 | continue;
35 | }
36 | dynamic item = list[j];
37 | list[j] = list[i];
38 | list[i] = item;
39 | }
40 | return list;
41 | }
42 |
43 | /// Randomly selects an item from a list.
44 | static dynamic getItem(List list) {
45 | return list[random.nextInt(list.length)];
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/lib/16_clock/06_lizi/04/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | import 'clock_widget.dart';
5 |
6 |
7 | void main() {
8 | WidgetsFlutterBinding.ensureInitialized(); // 确定初始化
9 | SystemChrome.setPreferredOrientations( // 使设备横屏显示
10 | [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
11 | SystemChrome.setEnabledSystemUIOverlays([]); // 全屏显示
12 | runApp(MyApp());
13 | }
14 |
15 | class MyApp extends StatelessWidget {
16 | @override
17 | Widget build(BuildContext context) {
18 | return MaterialApp(
19 | debugShowCheckedModeBanner: false,
20 | title: 'Flutter Demo',
21 | theme: ThemeData(
22 | primarySwatch: Colors.blue,
23 | ),
24 | home: Scaffold(
25 | body: Center(
26 | child: ClockWidget(),
27 | ))
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/16_clock/06_lizi/04/particle.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter/widgets.dart';
5 |
6 | class Particle {
7 |
8 | double x; // x 坐标
9 | double y; // y 坐标
10 | double vx; // x 速度
11 | double vy; // y 速度
12 | double a; // 发射弧度
13 | double dist; // 距离画布中心的长度
14 | double distFrac;// 距离画布中心的百分比
15 | double size;// 粒子大小
16 | double life; // 粒子寿命
17 | double lifeLeft; // 粒子剩余寿命
18 | bool isFilled; // 是否填充
19 | Color color; // 颜色
20 | int distribution; // 分配情况
21 |
22 |
23 | Particle({
24 | this.x = 0,
25 | this.y = 0,
26 | this.a = 0,
27 | this.vx = 0,
28 | this.vy = 0,
29 | this.dist = 0,
30 | this.distFrac = 0,
31 | this.size = 0,
32 | this.life = 0,
33 | this.lifeLeft = 0,
34 | this.isFilled = false,
35 | this.color = Colors.blueAccent,
36 | this.distribution = 0,
37 | });
38 | }
39 |
40 |
41 |
--------------------------------------------------------------------------------
/lib/16_clock/06_lizi/04/utils/rnd.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 |
3 |
4 | class Rnd {
5 | static int _seed = DateTime.now().millisecondsSinceEpoch;
6 | static Random random = Random(_seed);
7 |
8 | static set seed(int val) => random = Random(_seed = val);
9 | static int get seed => _seed;
10 |
11 | /// Gets the next double.
12 | static get ratio => random.nextDouble();
13 |
14 | /// Gets a random int between [min] and [max].
15 | static int getInt(int min, int max) {
16 | return min + random.nextInt(max - min);
17 | }
18 |
19 | /// Gets a random double between [min] and [max].
20 | static double getDouble(double min, double max) {
21 | return min + random.nextDouble() * (max - min);
22 | }
23 |
24 | /// Gets a random boolean with chance [chance].
25 | static bool getBool([double chance = 0.5]) {
26 | return random.nextDouble() < chance;
27 | }
28 |
29 | /// Randomize the positions of items in a list.
30 | static List shuffle(List list) {
31 | for (int i = 0, l = list.length; i < l; i++) {
32 | int j = random.nextInt(l);
33 | if (j == i) {
34 | continue;
35 | }
36 | dynamic item = list[j];
37 | list[j] = list[i];
38 | list[i] = item;
39 | }
40 | return list;
41 | }
42 |
43 | /// Randomly selects an item from a list.
44 | static dynamic getItem(List list) {
45 | return list[random.nextInt(list.length)];
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------