├── macos
├── Flutter
│ ├── Flutter-Debug.xcconfig
│ ├── Flutter-Release.xcconfig
│ └── GeneratedPluginRegistrant.swift
├── Runner
│ ├── Configs
│ │ ├── Debug.xcconfig
│ │ ├── Release.xcconfig
│ │ ├── Warnings.xcconfig
│ │ └── AppInfo.xcconfig
│ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ ├── app_icon_16.png
│ │ │ ├── app_icon_32.png
│ │ │ ├── app_icon_64.png
│ │ │ ├── app_icon_1024.png
│ │ │ ├── app_icon_128.png
│ │ │ ├── app_icon_256.png
│ │ │ ├── app_icon_512.png
│ │ │ └── Contents.json
│ ├── Release.entitlements
│ ├── AppDelegate.swift
│ ├── DebugProfile.entitlements
│ ├── MainFlutterWindow.swift
│ ├── Info.plist
│ └── Base.lproj
│ │ └── MainMenu.xib
├── .gitignore
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── Runner.xcodeproj
│ ├── project.xcworkspace
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── xcshareddata
│ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ └── project.pbxproj
└── RunnerTests
│ └── RunnerTests.swift
├── web
├── favicon.png
├── icons
│ ├── Icon-192.png
│ ├── Icon-512.png
│ ├── Icon-maskable-192.png
│ └── Icon-maskable-512.png
├── manifest.json
└── index.html
├── assets
├── images
│ ├── apple.png
│ ├── flutter.png
│ ├── gemini.png
│ ├── google.png
│ ├── firebase.png
│ ├── og-image.png
│ └── svg
│ │ ├── flutter.svg
│ │ ├── gemini.svg
│ │ ├── google.svg
│ │ ├── apple.svg
│ │ └── firebase.svg
├── fonts
│ └── Montserrat
│ │ └── Montserrat-Regular.ttf
└── shaders
│ └── liquid.frag
├── analysis_options.yaml
├── devtools_options.yaml
├── README.md
├── pubspec.yaml
├── .gitignore
├── LICENSE
├── .metadata
├── lib
├── liquid_metal_logo_state.dart
├── main.dart
├── simple_slider.dart
├── liquid_metal_shader_controller.dart
├── logo_selector.dart
├── liquid_metal_logo.dart
└── control_panel.dart
└── pubspec.lock
/macos/Flutter/Flutter-Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "ephemeral/Flutter-Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/macos/Flutter/Flutter-Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "ephemeral/Flutter-Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/web/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ksokolovskyi/paper_liquid_metal_logo/HEAD/web/favicon.png
--------------------------------------------------------------------------------
/assets/images/apple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ksokolovskyi/paper_liquid_metal_logo/HEAD/assets/images/apple.png
--------------------------------------------------------------------------------
/web/icons/Icon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ksokolovskyi/paper_liquid_metal_logo/HEAD/web/icons/Icon-192.png
--------------------------------------------------------------------------------
/web/icons/Icon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ksokolovskyi/paper_liquid_metal_logo/HEAD/web/icons/Icon-512.png
--------------------------------------------------------------------------------
/assets/images/flutter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ksokolovskyi/paper_liquid_metal_logo/HEAD/assets/images/flutter.png
--------------------------------------------------------------------------------
/assets/images/gemini.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ksokolovskyi/paper_liquid_metal_logo/HEAD/assets/images/gemini.png
--------------------------------------------------------------------------------
/assets/images/google.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ksokolovskyi/paper_liquid_metal_logo/HEAD/assets/images/google.png
--------------------------------------------------------------------------------
/macos/Runner/Configs/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../../Flutter/Flutter-Debug.xcconfig"
2 | #include "Warnings.xcconfig"
3 |
--------------------------------------------------------------------------------
/assets/images/firebase.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ksokolovskyi/paper_liquid_metal_logo/HEAD/assets/images/firebase.png
--------------------------------------------------------------------------------
/assets/images/og-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ksokolovskyi/paper_liquid_metal_logo/HEAD/assets/images/og-image.png
--------------------------------------------------------------------------------
/macos/Runner/Configs/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../../Flutter/Flutter-Release.xcconfig"
2 | #include "Warnings.xcconfig"
3 |
--------------------------------------------------------------------------------
/macos/.gitignore:
--------------------------------------------------------------------------------
1 | # Flutter-related
2 | **/Flutter/ephemeral/
3 | **/Pods/
4 |
5 | # Xcode-related
6 | **/dgph
7 | **/xcuserdata/
8 |
--------------------------------------------------------------------------------
/web/icons/Icon-maskable-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ksokolovskyi/paper_liquid_metal_logo/HEAD/web/icons/Icon-maskable-192.png
--------------------------------------------------------------------------------
/web/icons/Icon-maskable-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ksokolovskyi/paper_liquid_metal_logo/HEAD/web/icons/Icon-maskable-512.png
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:very_good_analysis/analysis_options.yaml
2 |
3 | linter:
4 | rules:
5 | public_member_api_docs: false
--------------------------------------------------------------------------------
/assets/fonts/Montserrat/Montserrat-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ksokolovskyi/paper_liquid_metal_logo/HEAD/assets/fonts/Montserrat/Montserrat-Regular.ttf
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ksokolovskyi/paper_liquid_metal_logo/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ksokolovskyi/paper_liquid_metal_logo/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ksokolovskyi/paper_liquid_metal_logo/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ksokolovskyi/paper_liquid_metal_logo/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ksokolovskyi/paper_liquid_metal_logo/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ksokolovskyi/paper_liquid_metal_logo/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ksokolovskyi/paper_liquid_metal_logo/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
--------------------------------------------------------------------------------
/devtools_options.yaml:
--------------------------------------------------------------------------------
1 | description: This file stores settings for Dart & Flutter DevTools.
2 | documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
3 | extensions:
4 |
--------------------------------------------------------------------------------
/macos/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/macos/Flutter/GeneratedPluginRegistrant.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | import FlutterMacOS
6 | import Foundation
7 |
8 |
9 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
10 | }
11 |
--------------------------------------------------------------------------------
/macos/Runner/Release.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/assets/images/svg/flutter.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/macos/RunnerTests/RunnerTests.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import FlutterMacOS
3 | import XCTest
4 |
5 | class RunnerTests: XCTestCase {
6 |
7 | func testExample() {
8 | // If you add code to the Runner application, consider adding tests here.
9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest.
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/macos/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import FlutterMacOS
3 |
4 | @main
5 | class AppDelegate: FlutterAppDelegate {
6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
7 | return true
8 | }
9 |
10 | override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
11 | return true
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/macos/Runner/DebugProfile.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.cs.allow-jit
8 |
9 | com.apple.security.network.server
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/macos/Runner/MainFlutterWindow.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import FlutterMacOS
3 |
4 | class MainFlutterWindow: NSWindow {
5 | override func awakeFromNib() {
6 | let flutterViewController = FlutterViewController()
7 | let windowFrame = self.frame
8 | self.contentViewController = flutterViewController
9 | self.setFrame(windowFrame, display: true)
10 |
11 | RegisterGeneratedPlugins(registry: flutterViewController)
12 |
13 | super.awakeFromNib()
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/assets/images/svg/gemini.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Paper Liquid Metal Logo
2 |
3 | https://github.com/user-attachments/assets/5fedf009-93ba-4580-8981-3afe3a66f194
4 |
5 | This demo is made with [Flutter][flutter].
6 |
7 | This project was inspired by the [Turn your logo into liquid metal][liquid-logo-demo] demo made by [Paper][paper] team.
8 |
9 | Shader and colors were obtained from the [liquid-logo][liquid-logo-repository] repository.
10 |
11 | [flutter]: https://flutter.dev
12 | [liquid-logo-demo]: https://liquid.paper.design
13 | [liquid-logo-repository]: https://github.com/paper-design/liquid-logo
14 | [paper]: https://paper.design
15 |
--------------------------------------------------------------------------------
/assets/images/svg/google.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/macos/Runner/Configs/Warnings.xcconfig:
--------------------------------------------------------------------------------
1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings
2 | GCC_WARN_UNDECLARED_SELECTOR = YES
3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES
4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE
5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES
6 | CLANG_WARN_PRAGMA_PACK = YES
7 | CLANG_WARN_STRICT_PROTOTYPES = YES
8 | CLANG_WARN_COMMA = YES
9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES
10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES
11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES
12 | GCC_WARN_SHADOW = YES
13 | CLANG_WARN_UNREACHABLE_CODE = YES
14 |
--------------------------------------------------------------------------------
/assets/images/svg/apple.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/macos/Runner/Configs/AppInfo.xcconfig:
--------------------------------------------------------------------------------
1 | // Application-level settings for the Runner target.
2 | //
3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the
4 | // future. If not, the values below would default to using the project name when this becomes a
5 | // 'flutter create' template.
6 |
7 | // The application's name. By default this is also the title of the Flutter window.
8 | PRODUCT_NAME = paper_liquid_metal_logo
9 |
10 | // The application's bundle identifier
11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.paperLiquidMetalLogo
12 |
13 | // The copyright displayed in application information
14 | PRODUCT_COPYRIGHT = Copyright © 2025 com.example. All rights reserved.
15 |
--------------------------------------------------------------------------------
/assets/images/svg/firebase.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: paper_liquid_metal_logo
2 | description: Paper Liquid Metal Logo
3 | publish_to: 'none'
4 | version: 1.0.0
5 |
6 | environment:
7 | sdk: '>=3.6.0 <4.0.0'
8 |
9 | dependencies:
10 | flutter:
11 | sdk: flutter
12 | flutter_shaders: ^0.1.3
13 | provider: ^6.1.2
14 | vector_graphics: ^1.1.18
15 |
16 | dev_dependencies:
17 | flutter_test:
18 | sdk: flutter
19 | vector_graphics_compiler: ^1.1.16
20 | very_good_analysis: ^7.0.0
21 |
22 | flutter:
23 | uses-material-design: true
24 |
25 | fonts:
26 | - family: Montserrat
27 | fonts:
28 | - asset: assets/fonts/Montserrat/Montserrat-Regular.ttf
29 | weight: 400
30 |
31 | assets:
32 | - assets/images/
33 |
34 | - path: assets/images/svg/
35 | transformers:
36 | - package: vector_graphics_compiler
37 |
38 | shaders:
39 | - assets/shaders/liquid.frag
40 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .build/
9 | .buildlog/
10 | .history
11 | .svn/
12 | .swiftpm/
13 | migrate_working_dir/
14 |
15 | # IntelliJ related
16 | *.iml
17 | *.ipr
18 | *.iws
19 | .idea/
20 |
21 | # The .vscode folder contains launch configuration and tasks you configure in
22 | # VS Code which you may wish to be included in version control, so this line
23 | # is commented out by default.
24 | .vscode/
25 |
26 | # Flutter/Dart/Pub related
27 | **/doc/api/
28 | **/ios/Flutter/.last_build_id
29 | .dart_tool/
30 | .flutter-plugins
31 | .flutter-plugins-dependencies
32 | .pub-cache/
33 | .pub/
34 | /build/
35 |
36 | # Symbolication related
37 | app.*.symbols
38 |
39 | # Obfuscation related
40 | app.*.map.json
41 |
42 | # Android Studio will place build artifacts here
43 | /android/app/debug
44 | /android/app/profile
45 | /android/app/release
46 |
47 | # Firebase
48 | .firebase
49 | .firebaserc
50 | firebase.json
51 |
--------------------------------------------------------------------------------
/web/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Flutter Liquid Metal Logo",
3 | "short_name": "Flutter Liquid Metal Logo",
4 | "start_url": ".",
5 | "display": "standalone",
6 | "background_color": "#0175C2",
7 | "theme_color": "#0175C2",
8 | "description": "Flutter implementation of paper.design liquid logo",
9 | "orientation": "portrait-primary",
10 | "prefer_related_applications": false,
11 | "icons": [
12 | {
13 | "src": "icons/Icon-192.png",
14 | "sizes": "192x192",
15 | "type": "image/png"
16 | },
17 | {
18 | "src": "icons/Icon-512.png",
19 | "sizes": "512x512",
20 | "type": "image/png"
21 | },
22 | {
23 | "src": "icons/Icon-maskable-192.png",
24 | "sizes": "192x192",
25 | "type": "image/png",
26 | "purpose": "maskable"
27 | },
28 | {
29 | "src": "icons/Icon-maskable-512.png",
30 | "sizes": "512x512",
31 | "type": "image/png",
32 | "purpose": "maskable"
33 | }
34 | ]
35 | }
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 Kostia Sokolovskyi
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/macos/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 | NSHumanReadableCopyright
26 | $(PRODUCT_COPYRIGHT)
27 | NSMainNibFile
28 | MainMenu
29 | NSPrincipalClass
30 | NSApplication
31 |
32 |
33 |
--------------------------------------------------------------------------------
/.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: "09de023485e95e6d1225c2baa44b8feb85e0d45f"
8 | channel: "stable"
9 |
10 | project_type: app
11 |
12 | # Tracks metadata for the flutter migrate command
13 | migration:
14 | platforms:
15 | - platform: root
16 | create_revision: 09de023485e95e6d1225c2baa44b8feb85e0d45f
17 | base_revision: 09de023485e95e6d1225c2baa44b8feb85e0d45f
18 | - platform: macos
19 | create_revision: 09de023485e95e6d1225c2baa44b8feb85e0d45f
20 | base_revision: 09de023485e95e6d1225c2baa44b8feb85e0d45f
21 | - platform: web
22 | create_revision: 09de023485e95e6d1225c2baa44b8feb85e0d45f
23 | base_revision: 09de023485e95e6d1225c2baa44b8feb85e0d45f
24 |
25 | # User provided section
26 |
27 | # List of Local paths (relative to this file) that should be
28 | # ignored by the migrate tool.
29 | #
30 | # Files that are not part of the templates will be ignored by default.
31 | unmanaged_files:
32 | - 'lib/main.dart'
33 | - 'ios/Runner.xcodeproj/project.pbxproj'
34 |
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "16x16",
5 | "idiom" : "mac",
6 | "filename" : "app_icon_16.png",
7 | "scale" : "1x"
8 | },
9 | {
10 | "size" : "16x16",
11 | "idiom" : "mac",
12 | "filename" : "app_icon_32.png",
13 | "scale" : "2x"
14 | },
15 | {
16 | "size" : "32x32",
17 | "idiom" : "mac",
18 | "filename" : "app_icon_32.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "32x32",
23 | "idiom" : "mac",
24 | "filename" : "app_icon_64.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "128x128",
29 | "idiom" : "mac",
30 | "filename" : "app_icon_128.png",
31 | "scale" : "1x"
32 | },
33 | {
34 | "size" : "128x128",
35 | "idiom" : "mac",
36 | "filename" : "app_icon_256.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "256x256",
41 | "idiom" : "mac",
42 | "filename" : "app_icon_256.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "256x256",
47 | "idiom" : "mac",
48 | "filename" : "app_icon_512.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "512x512",
53 | "idiom" : "mac",
54 | "filename" : "app_icon_512.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "512x512",
59 | "idiom" : "mac",
60 | "filename" : "app_icon_1024.png",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/lib/liquid_metal_logo_state.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class LiquidMetalLogoState extends ChangeNotifier {
4 | LiquidMetalLogoState()
5 | : _type = LiquidMetalLogoType.flutter,
6 | _background = LiquidMetalLogoBackground.metal;
7 |
8 | LiquidMetalLogoType _type;
9 |
10 | LiquidMetalLogoBackground _background;
11 |
12 | LiquidMetalLogoType get type => _type;
13 |
14 | set type(LiquidMetalLogoType value) {
15 | if (value == _type) {
16 | return;
17 | }
18 |
19 | _type = value;
20 | notifyListeners();
21 | }
22 |
23 | LiquidMetalLogoBackground get background => _background;
24 |
25 | set background(LiquidMetalLogoBackground value) {
26 | if (value == _background) {
27 | return;
28 | }
29 |
30 | _background = value;
31 | notifyListeners();
32 | }
33 | }
34 |
35 | enum LiquidMetalLogoType {
36 | flutter,
37 | google,
38 | apple,
39 | firebase,
40 | gemini;
41 |
42 | String get asset {
43 | return switch (this) {
44 | flutter => 'assets/images/flutter.png',
45 | google => 'assets/images/google.png',
46 | apple => 'assets/images/apple.png',
47 | firebase => 'assets/images/firebase.png',
48 | gemini => 'assets/images/gemini.png',
49 | };
50 | }
51 |
52 | String get icon {
53 | return switch (this) {
54 | flutter => 'assets/images/svg/flutter.svg',
55 | google => 'assets/images/svg/google.svg',
56 | apple => 'assets/images/svg/apple.svg',
57 | firebase => 'assets/images/svg/firebase.svg',
58 | gemini => 'assets/images/svg/gemini.svg',
59 | };
60 | }
61 |
62 | String get label {
63 | return switch (this) {
64 | flutter => 'Flutter',
65 | google => 'Google',
66 | apple => 'Apple',
67 | firebase => 'Firebase',
68 | gemini => 'Gemini',
69 | };
70 | }
71 | }
72 |
73 | enum LiquidMetalLogoBackground {
74 | metal,
75 | white,
76 | black;
77 |
78 | LinearGradient get gradient {
79 | final colors = switch (this) {
80 | metal => const [Color(0xFFEEEEEE), Color(0xFFB8B8B8)],
81 | white => [Colors.white, Colors.white],
82 | black => [Colors.black, Colors.black],
83 | };
84 |
85 | return LinearGradient(
86 | colors: colors,
87 | begin: Alignment.topCenter,
88 | end: Alignment.bottomCenter,
89 | );
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | Flutter Liquid Metal Logo
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:paper_liquid_metal_logo/control_panel.dart';
3 | import 'package:paper_liquid_metal_logo/liquid_metal_logo.dart';
4 | import 'package:paper_liquid_metal_logo/liquid_metal_logo_state.dart';
5 | import 'package:paper_liquid_metal_logo/liquid_metal_shader_controller.dart';
6 | import 'package:paper_liquid_metal_logo/logo_selector.dart';
7 | import 'package:provider/provider.dart';
8 |
9 | void main() {
10 | runApp(const App());
11 | }
12 |
13 | class App extends StatefulWidget {
14 | const App({super.key});
15 |
16 | @override
17 | State createState() => _AppState();
18 | }
19 |
20 | class _AppState extends State with SingleTickerProviderStateMixin {
21 | @override
22 | Widget build(BuildContext context) {
23 | return MultiProvider(
24 | providers: [
25 | ChangeNotifierProvider(
26 | create: (_) => LiquidMetalLogoState(),
27 | lazy: false,
28 | ),
29 | Provider(
30 | create: (_) => LiquidMetalShaderController.withDefaults(
31 | vsync: this,
32 | )..start(),
33 | dispose: (_, controller) => controller.dispose(),
34 | lazy: false,
35 | ),
36 | ],
37 | child: const MaterialApp(
38 | debugShowCheckedModeBanner: false,
39 | home: Scaffold(
40 | backgroundColor: Colors.black,
41 | body: Screen(),
42 | ),
43 | ),
44 | );
45 | }
46 | }
47 |
48 | class Screen extends StatefulWidget {
49 | const Screen({super.key});
50 |
51 | @override
52 | State createState() => _ScreenState();
53 | }
54 |
55 | class _ScreenState extends State with SingleTickerProviderStateMixin {
56 | final _logoKey = GlobalKey();
57 | final _panelKey = GlobalKey();
58 |
59 | @override
60 | Widget build(BuildContext context) {
61 | final logo = KeyedSubtree(
62 | key: _logoKey,
63 | child: const LiquidMetalLogo(),
64 | );
65 | final panel = KeyedSubtree(
66 | key: _panelKey,
67 | child: const ControlPanel(),
68 | );
69 |
70 | return SingleChildScrollView(
71 | child: Builder(
72 | builder: (context) {
73 | final windowSize = MediaQuery.sizeOf(context);
74 | final isRowLayout = windowSize.width >= 1200;
75 |
76 | return ConstrainedBox(
77 | constraints: BoxConstraints(minHeight: windowSize.height),
78 | child: Column(
79 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
80 | crossAxisAlignment: CrossAxisAlignment.stretch,
81 | children: [
82 | const SizedBox(
83 | height: 72,
84 | width: double.infinity,
85 | ),
86 | Center(
87 | child: Padding(
88 | padding: const EdgeInsets.all(24),
89 | child: isRowLayout
90 | ? Row(
91 | spacing: 32,
92 | mainAxisAlignment: MainAxisAlignment.center,
93 | children: [logo, panel],
94 | )
95 | : Column(
96 | spacing: 24,
97 | mainAxisSize: MainAxisSize.min,
98 | mainAxisAlignment: MainAxisAlignment.center,
99 | children: [logo, panel],
100 | ),
101 | ),
102 | ),
103 | const LogoSelector(),
104 | ],
105 | ),
106 | );
107 | },
108 | ),
109 | );
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
43 |
49 |
50 |
51 |
52 |
53 |
64 |
66 |
72 |
73 |
74 |
75 |
81 |
83 |
89 |
90 |
91 |
92 |
94 |
95 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/lib/simple_slider.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class SimpleSlider extends StatelessWidget {
4 | const SimpleSlider({
5 | required this.value,
6 | required this.minValue,
7 | required this.maxValue,
8 | required this.onChanged,
9 | super.key,
10 | });
11 |
12 | final double value;
13 |
14 | final double minValue;
15 |
16 | final double maxValue;
17 |
18 | final ValueChanged onChanged;
19 |
20 | @override
21 | Widget build(BuildContext context) {
22 | return ConstrainedBox(
23 | constraints: const BoxConstraints(maxHeight: 40),
24 | child: SliderTheme(
25 | data: const SliderThemeData(
26 | thumbShape: HandleThumbShape(),
27 | thumbSize: WidgetStatePropertyAll(Size.square(16)),
28 | thumbColor: Colors.white,
29 | trackHeight: 6,
30 | trackShape: _TrackShape(),
31 | overlayShape: _NoOverlayShape(),
32 | ),
33 | child: Slider(
34 | padding: EdgeInsets.zero,
35 | value: value,
36 | min: minValue,
37 | max: maxValue,
38 | onChanged: onChanged,
39 | ),
40 | ),
41 | );
42 | }
43 | }
44 |
45 | class _TrackShape extends SliderTrackShape with BaseSliderTrackShape {
46 | const _TrackShape();
47 |
48 | @override
49 | void paint(
50 | PaintingContext context,
51 | Offset offset, {
52 | required RenderBox parentBox,
53 | required SliderThemeData sliderTheme,
54 | required Animation enableAnimation,
55 | required TextDirection textDirection,
56 | required Offset thumbCenter,
57 | Offset? secondaryOffset,
58 | bool isDiscrete = false,
59 | bool isEnabled = false,
60 | }) {
61 | final trackHeight = sliderTheme.trackHeight!;
62 | final activePaint = Paint()..color = const Color(0xFF81ADEC);
63 | final inactivePaint = Paint()..color = const Color(0x33FFFFFF);
64 | final (Paint leftTrackPaint, Paint rightTrackPaint) =
65 | switch (textDirection) {
66 | TextDirection.ltr => (activePaint, inactivePaint),
67 | TextDirection.rtl => (inactivePaint, activePaint),
68 | };
69 |
70 | final trackRect = getPreferredRect(
71 | parentBox: parentBox,
72 | offset: offset,
73 | sliderTheme: sliderTheme,
74 | isEnabled: isEnabled,
75 | isDiscrete: isDiscrete,
76 | );
77 | final trackRadius = Radius.circular(trackRect.height / 2);
78 | final activeTrackRadius = Radius.circular((trackRect.height) / 2);
79 | final isLTR = textDirection == TextDirection.ltr;
80 |
81 | final drawInactiveTrack =
82 | thumbCenter.dx < (trackRect.right - (trackHeight / 2));
83 | if (drawInactiveTrack) {
84 | // Draw the inactive track segment.
85 | context.canvas.drawRRect(
86 | RRect.fromLTRBR(
87 | thumbCenter.dx - (trackHeight / 2),
88 | trackRect.top,
89 | trackRect.right,
90 | trackRect.bottom,
91 | isLTR ? trackRadius : activeTrackRadius,
92 | ),
93 | rightTrackPaint,
94 | );
95 | }
96 |
97 | final drawActiveTrack =
98 | thumbCenter.dx > (trackRect.left + (trackHeight / 2));
99 | if (drawActiveTrack) {
100 | // Draw the active track segment.
101 | context.canvas.drawRRect(
102 | RRect.fromLTRBR(
103 | trackRect.left,
104 | isLTR ? trackRect.top : trackRect.top,
105 | thumbCenter.dx + (trackHeight / 2),
106 | isLTR ? trackRect.bottom : trackRect.bottom,
107 | isLTR ? activeTrackRadius : trackRadius,
108 | ),
109 | leftTrackPaint,
110 | );
111 | }
112 | }
113 |
114 | @override
115 | bool get isRounded => true;
116 | }
117 |
118 | class _NoOverlayShape extends SliderComponentShape {
119 | const _NoOverlayShape();
120 |
121 | @override
122 | Size getPreferredSize(bool isEnabled, bool isDiscrete) {
123 | return Size.zero;
124 | }
125 |
126 | @override
127 | void paint(
128 | PaintingContext context,
129 | Offset center, {
130 | required Animation activationAnimation,
131 | required Animation enableAnimation,
132 | required bool isDiscrete,
133 | required TextPainter labelPainter,
134 | required RenderBox parentBox,
135 | required SliderThemeData sliderTheme,
136 | required TextDirection textDirection,
137 | required double value,
138 | required double textScaleFactor,
139 | required Size sizeWithOverflow,
140 | }) {}
141 | }
142 |
--------------------------------------------------------------------------------
/lib/liquid_metal_shader_controller.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/foundation.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter/scheduler.dart';
4 |
5 | class LiquidMetalShaderController {
6 | LiquidMetalShaderController.withDefaults({
7 | required TickerProvider vsync,
8 | }) : dispersion = LiquidMetalShaderEditableParameter(
9 | minValue: 0,
10 | maxValue: 0.06,
11 | defaultValue: 0.015,
12 | ),
13 | edge = LiquidMetalShaderEditableParameter(
14 | minValue: 0,
15 | maxValue: 1,
16 | defaultValue: 0.4,
17 | ),
18 | patternBlur = LiquidMetalShaderEditableParameter(
19 | minValue: 0,
20 | maxValue: 0.05,
21 | defaultValue: 0.005,
22 | ),
23 | liquid = LiquidMetalShaderEditableParameter(
24 | minValue: 0,
25 | maxValue: 1,
26 | defaultValue: 0.07,
27 | ),
28 | patternScale = LiquidMetalShaderEditableParameter(
29 | minValue: 1,
30 | maxValue: 10,
31 | defaultValue: 2,
32 | ),
33 | time = LiquidMetalShaderParameter(
34 | minValue: 0,
35 | maxValue: double.infinity,
36 | defaultValue: 0,
37 | ) {
38 | speed = LiquidMetalShaderEditableParameter(
39 | minValue: 0,
40 | maxValue: 1,
41 | defaultValue: 0.3,
42 | onValueChanged: _onSpeedChanged,
43 | );
44 |
45 | _ticker = vsync.createTicker(_onTick);
46 | }
47 |
48 | final LiquidMetalShaderEditableParameter dispersion;
49 |
50 | final LiquidMetalShaderEditableParameter edge;
51 |
52 | final LiquidMetalShaderEditableParameter patternBlur;
53 |
54 | final LiquidMetalShaderEditableParameter liquid;
55 |
56 | late final LiquidMetalShaderEditableParameter speed;
57 |
58 | final LiquidMetalShaderEditableParameter patternScale;
59 |
60 | final LiquidMetalShaderParameter time;
61 |
62 | late final Ticker _ticker;
63 |
64 | var _elapsedMilliseconds = 0;
65 |
66 | List> get parameters => [
67 | dispersion,
68 | edge,
69 | patternBlur,
70 | liquid,
71 | speed,
72 | patternScale,
73 | time,
74 | ];
75 |
76 | void dispose() {
77 | dispersion.dispose();
78 | edge.dispose();
79 | patternBlur.dispose();
80 | liquid.dispose();
81 | speed.dispose();
82 | patternScale.dispose();
83 | time.dispose();
84 |
85 | _ticker.dispose();
86 | }
87 |
88 | void start() {
89 | _ticker.start();
90 | }
91 |
92 | void stop() {
93 | _ticker.stop();
94 | _elapsedMilliseconds = 0;
95 | }
96 |
97 | void _onSpeedChanged(double speed) {
98 | if (speed == 0) {
99 | stop();
100 | } else if (!_ticker.isTicking) {
101 | start();
102 | }
103 | }
104 |
105 | void _onTick(Duration elapsed) {
106 | final milliseconds = elapsed.inMilliseconds;
107 | final difference = milliseconds - _elapsedMilliseconds;
108 |
109 | time._value.value += difference * speed.value;
110 |
111 | _elapsedMilliseconds = milliseconds;
112 | }
113 | }
114 |
115 | class LiquidMetalShaderParameter implements ValueListenable {
116 | LiquidMetalShaderParameter({
117 | required this.minValue,
118 | required this.maxValue,
119 | required double defaultValue,
120 | }) : assert(
121 | defaultValue >= minValue && defaultValue <= maxValue,
122 | 'value is not in the allowed range',
123 | ),
124 | _value = ValueNotifier(defaultValue);
125 |
126 | final double minValue;
127 |
128 | final double maxValue;
129 |
130 | final ValueNotifier _value;
131 |
132 | @override
133 | double get value => _value.value;
134 |
135 | void dispose() {
136 | _value.dispose();
137 | }
138 |
139 | @override
140 | void addListener(VoidCallback listener) {
141 | _value.addListener(listener);
142 | }
143 |
144 | @override
145 | void removeListener(VoidCallback listener) {
146 | _value.removeListener(listener);
147 | }
148 | }
149 |
150 | class LiquidMetalShaderEditableParameter extends LiquidMetalShaderParameter {
151 | LiquidMetalShaderEditableParameter({
152 | required super.minValue,
153 | required super.maxValue,
154 | required super.defaultValue,
155 | ValueChanged? onValueChanged,
156 | }) : _onValueChanged = onValueChanged;
157 |
158 | final ValueChanged? _onValueChanged;
159 |
160 | set value(double newValue) {
161 | assert(
162 | newValue >= minValue && newValue <= maxValue,
163 | 'value is not in the allowed range',
164 | );
165 |
166 | _value.value = newValue;
167 | _onValueChanged?.call(newValue);
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/lib/logo_selector.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:paper_liquid_metal_logo/liquid_metal_logo_state.dart';
3 | import 'package:provider/provider.dart';
4 | import 'package:vector_graphics/vector_graphics_compat.dart';
5 |
6 | class LogoSelector extends StatefulWidget {
7 | const LogoSelector({super.key});
8 |
9 | @override
10 | State createState() => _LogoSelectorState();
11 | }
12 |
13 | class _LogoSelectorState extends State {
14 | final _controller = ScrollController();
15 |
16 | @override
17 | void dispose() {
18 | _controller.dispose();
19 | super.dispose();
20 | }
21 |
22 | @override
23 | Widget build(BuildContext context) {
24 | return RawScrollbar(
25 | controller: _controller,
26 | trackVisibility: true,
27 | thumbVisibility: true,
28 | thickness: 6,
29 | radius: const Radius.circular(3),
30 | trackRadius: const Radius.circular(3),
31 | thumbColor: const Color(0xFF666666),
32 | trackColor: const Color(0xFF292929),
33 | padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
34 | scrollbarOrientation: ScrollbarOrientation.bottom,
35 | child: SingleChildScrollView(
36 | controller: _controller,
37 | scrollDirection: Axis.horizontal,
38 | child: Builder(
39 | builder: (context) {
40 | final windowSize = MediaQuery.sizeOf(context);
41 |
42 | return ConstrainedBox(
43 | constraints: BoxConstraints(minWidth: windowSize.width),
44 | child: Padding(
45 | padding: const EdgeInsets.only(
46 | left: 16,
47 | right: 16,
48 | bottom: 32,
49 | ),
50 | child: Row(
51 | mainAxisAlignment: MainAxisAlignment.center,
52 | children: [
53 | for (final type in LiquidMetalLogoType.values)
54 | _Item(type: type),
55 | ],
56 | ),
57 | ),
58 | );
59 | },
60 | ),
61 | ),
62 | );
63 | }
64 | }
65 |
66 | class _Item extends StatefulWidget {
67 | const _Item({
68 | required this.type,
69 | });
70 |
71 | final LiquidMetalLogoType type;
72 |
73 | @override
74 | State<_Item> createState() => __ItemState();
75 | }
76 |
77 | class __ItemState extends State<_Item> with SingleTickerProviderStateMixin {
78 | late final _controller = AnimationController(
79 | vsync: this,
80 | duration: const Duration(milliseconds: 250),
81 | );
82 |
83 | late final _logoOpacity = Tween(begin: 0.4, end: 1)
84 | .chain(CurveTween(curve: Curves.easeInOut))
85 | .animate(_controller);
86 |
87 | late final _borderColor = ColorTween(
88 | begin: const Color(0x00FFFFFF),
89 | end: const Color(0x66FFFFFF),
90 | ).chain(CurveTween(curve: Curves.easeInOut)).animate(_controller);
91 |
92 | @override
93 | void dispose() {
94 | _controller.dispose();
95 | super.dispose();
96 | }
97 |
98 | @override
99 | Widget build(BuildContext context) {
100 | return MouseRegion(
101 | cursor: SystemMouseCursors.click,
102 | onEnter: (_) => _controller.forward(),
103 | onExit: (_) => _controller.reverse(),
104 | child: GestureDetector(
105 | onTap: () {
106 | context.read().type = widget.type;
107 | },
108 | child: Column(
109 | mainAxisSize: MainAxisSize.min,
110 | spacing: 8,
111 | children: [
112 | RepaintBoundary(
113 | child: SizedBox(
114 | width: 160,
115 | height: 100,
116 | child: AnimatedBuilder(
117 | animation: _borderColor,
118 | builder: (context, child) {
119 | return DecoratedBox(
120 | decoration: BoxDecoration(
121 | borderRadius:
122 | const BorderRadius.all(Radius.circular(8)),
123 | border: Border.fromBorderSide(
124 | BorderSide(color: _borderColor.value!),
125 | ),
126 | ),
127 | child: child,
128 | );
129 | },
130 | child: Padding(
131 | padding: const EdgeInsets.all(24),
132 | child: VectorGraphic(
133 | loader: AssetBytesLoader(widget.type.icon),
134 | opacity: _logoOpacity,
135 | height: 52,
136 | width: 112,
137 | fit: BoxFit.fitHeight,
138 | placeholderBuilder: (_) => const SizedBox.shrink(
139 | key: Key(''),
140 | ),
141 | transitionDuration: const Duration(milliseconds: 250),
142 | ),
143 | ),
144 | ),
145 | ),
146 | ),
147 | Text(
148 | widget.type.label,
149 | overflow: TextOverflow.ellipsis,
150 | style: const TextStyle(
151 | fontFamily: 'Montserrat',
152 | fontWeight: FontWeight.w400,
153 | fontSize: 16,
154 | height: 24 / 16,
155 | letterSpacing: -0.7,
156 | color: Color(0xB2FFFFFF),
157 | ),
158 | ),
159 | ],
160 | ),
161 | ),
162 | );
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/lib/liquid_metal_logo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_shaders/flutter_shaders.dart';
3 | import 'package:paper_liquid_metal_logo/liquid_metal_logo_state.dart';
4 | import 'package:paper_liquid_metal_logo/liquid_metal_shader_controller.dart';
5 | import 'package:provider/provider.dart';
6 |
7 | class LiquidMetalLogo extends StatefulWidget {
8 | const LiquidMetalLogo({super.key});
9 |
10 | @override
11 | State createState() => _LiquidMetalLogoState();
12 | }
13 |
14 | class _LiquidMetalLogoState extends State {
15 | @override
16 | Widget build(BuildContext context) {
17 | final state = context.watch();
18 |
19 | return RepaintBoundary(
20 | child: AnimatedContainer(
21 | duration: const Duration(milliseconds: 250),
22 | decoration: BoxDecoration(
23 | borderRadius: const BorderRadius.all(Radius.circular(10)),
24 | gradient: state.background.gradient,
25 | ),
26 | child: const _Logo(),
27 | ),
28 | );
29 | }
30 | }
31 |
32 | class _Logo extends StatelessWidget {
33 | const _Logo();
34 |
35 | @override
36 | Widget build(BuildContext context) {
37 | final controller = context.read();
38 |
39 | return ConstrainedBox(
40 | constraints: const BoxConstraints(
41 | maxHeight: 500,
42 | maxWidth: 500,
43 | ),
44 | child: AspectRatio(
45 | aspectRatio: 1,
46 | child: Center(
47 | child: ConstrainedBox(
48 | constraints: const BoxConstraints(maxWidth: 400),
49 | child: AspectRatio(
50 | aspectRatio: 1,
51 | child: ListenableBuilder(
52 | listenable: Listenable.merge(controller.parameters),
53 | builder: (context, child) {
54 | return ShaderBuilder(
55 | assetKey: 'assets/shaders/liquid.frag',
56 | (context, shader, _) {
57 | return AnimatedSampler(
58 | (image, size, canvas) {
59 | shader
60 | ..setImageSampler(0, image)
61 | ..setFloatUniforms((uniforms) {
62 | uniforms
63 | ..setSize(size)
64 | // u_time
65 | ..setFloat(controller.time.value)
66 | // u_ratio
67 | ..setFloat(1)
68 | // u_img_ratio
69 | ..setFloat(1)
70 | // u_patternScale
71 | ..setFloat(controller.patternScale.value)
72 | // u_refraction
73 | ..setFloat(controller.dispersion.value)
74 | // u_edge
75 | ..setFloat(controller.edge.value)
76 | // u_patternBlur
77 | ..setFloat(controller.patternBlur.value)
78 | // u_liquid
79 | ..setFloat(controller.liquid.value);
80 | });
81 |
82 | canvas.drawRect(
83 | Rect.fromLTWH(0, 0, size.width, size.height),
84 | Paint()..shader = shader,
85 | );
86 | },
87 | child: child!,
88 | );
89 | },
90 | );
91 | },
92 | child: const _Image(),
93 | ),
94 | ),
95 | ),
96 | ),
97 | ),
98 | );
99 | }
100 | }
101 |
102 | class _Image extends StatefulWidget {
103 | const _Image();
104 |
105 | @override
106 | State<_Image> createState() => _ImageState();
107 | }
108 |
109 | class _ImageState extends State<_Image> with SingleTickerProviderStateMixin {
110 | late final _controller = AnimationController(
111 | vsync: this,
112 | duration: const Duration(milliseconds: 500),
113 | reverseDuration: const Duration(milliseconds: 300),
114 | );
115 |
116 | late final _opacity = CurvedAnimation(
117 | parent: _controller,
118 | curve: Curves.easeOut,
119 | reverseCurve: Curves.easeIn,
120 | );
121 |
122 | late final LiquidMetalLogoState _state;
123 |
124 | late LiquidMetalLogoType _type;
125 |
126 | LiquidMetalLogoType? _nextType;
127 |
128 | @override
129 | void initState() {
130 | super.initState();
131 |
132 | _state = context.read();
133 | _state.addListener(_onTypeChanged);
134 |
135 | _type = _state.type;
136 |
137 | _controller.forward();
138 | }
139 |
140 | @override
141 | void dispose() {
142 | _controller.dispose();
143 | _opacity.dispose();
144 |
145 | _state.removeListener(_onTypeChanged);
146 |
147 | super.dispose();
148 | }
149 |
150 | Future _onTypeChanged() async {
151 | final nextType = _state.type;
152 |
153 | if (nextType == _type || nextType == _nextType) {
154 | return;
155 | }
156 |
157 | _nextType = nextType;
158 |
159 | await _controller.reverse();
160 |
161 | if (!mounted || _nextType != nextType) {
162 | return;
163 | }
164 |
165 | setState(() {
166 | _type = nextType;
167 | _nextType = null;
168 | });
169 |
170 | _controller
171 | ..reset()
172 | ..forward();
173 | }
174 |
175 | @override
176 | Widget build(BuildContext context) {
177 | return ColoredBox(
178 | color: Colors.white,
179 | child: Image.asset(
180 | _type.asset,
181 | opacity: _opacity,
182 | ),
183 | );
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/assets/shaders/liquid.frag:
--------------------------------------------------------------------------------
1 | // Original shader made by Paper: https://github.com/paper-design/liquid-logo/blob/main/src/app/hero/liquid-frag.ts
2 |
3 | #version 300 es
4 |
5 | precision mediump float;
6 |
7 | #include
8 |
9 | uniform vec2 uSize;
10 | uniform float u_time;
11 | uniform float u_ratio;
12 | uniform float u_img_ratio;
13 | uniform float u_patternScale;
14 | uniform float u_refraction;
15 | uniform float u_edge;
16 | uniform float u_patternBlur;
17 | uniform float u_liquid;
18 | uniform sampler2D u_image_texture;
19 |
20 | out vec4 fragColor;
21 |
22 | #define TWO_PI 6.28318530718
23 | #define PI 3.14159265358979323846
24 |
25 | vec3 mod289(vec3 x) { return x - floor(x * (1. / 289.)) * 289.; }
26 | vec2 mod289(vec2 x) { return x - floor(x * (1. / 289.)) * 289.; }
27 | vec3 permute(vec3 x) { return mod289(((x*34.)+1.)*x); }
28 |
29 | float snoise(vec2 v) {
30 | const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439);
31 | vec2 i = floor(v + dot(v, C.yy));
32 | vec2 x0 = v - i + dot(i, C.xx);
33 | vec2 i1;
34 | i1 = (x0.x > x0.y) ? vec2(1., 0.) : vec2(0., 1.);
35 | vec4 x12 = x0.xyxy + C.xxzz;
36 | x12.xy -= i1;
37 | i = mod289(i);
38 | vec3 p = permute(permute(i.y + vec3(0., i1.y, 1.)) + i.x + vec3(0., i1.x, 1.));
39 | vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.);
40 | m = m*m;
41 | m = m*m;
42 | vec3 x = 2. * fract(p * C.www) - 1.;
43 | vec3 h = abs(x) - 0.5;
44 | vec3 ox = floor(x + 0.5);
45 | vec3 a0 = x - ox;
46 | m *= 1.79284291400159 - 0.85373472095314 * (a0*a0 + h*h);
47 | vec3 g;
48 | g.x = a0.x * x0.x + h.x * x0.y;
49 | g.yz = a0.yz * x12.xz + h.yz * x12.yw;
50 | return 130. * dot(m, g);
51 | }
52 |
53 | vec2 get_img_uv(vec2 uv) {
54 | vec2 img_uv = uv;
55 | img_uv -= .5;
56 | if (u_ratio > u_img_ratio) {
57 | img_uv.x = img_uv.x * u_ratio / u_img_ratio;
58 | } else {
59 | img_uv.y = img_uv.y * u_img_ratio / u_ratio;
60 | }
61 | float scale_factor = 1.;
62 | img_uv *= scale_factor;
63 | img_uv += .5;
64 |
65 | img_uv.y = 1. - img_uv.y;
66 |
67 | return img_uv;
68 | }
69 |
70 | vec2 rotate(vec2 uv, float th) {
71 | return mat2(cos(th), sin(th), -sin(th), cos(th)) * uv;
72 | }
73 |
74 | float get_color_channel(float c1, float c2, float stripe_p, vec3 w, float extra_blur, float b) {
75 | float ch = c2;
76 | float border = 0.;
77 | float blur = u_patternBlur + extra_blur;
78 |
79 | ch = mix(ch, c1, smoothstep(.0, blur, stripe_p));
80 |
81 | border = w[0];
82 | ch = mix(ch, c2, smoothstep(border - blur, border + blur, stripe_p));
83 |
84 | b = smoothstep(.2, .8, b);
85 | border = w[0] + .4 * (1. - b) * w[1];
86 | ch = mix(ch, c1, smoothstep(border - blur, border + blur, stripe_p));
87 |
88 | border = w[0] + .5 * (1. - b) * w[1];
89 | ch = mix(ch, c2, smoothstep(border - blur, border + blur, stripe_p));
90 |
91 | border = w[0] + w[1];
92 | ch = mix(ch, c1, smoothstep(border - blur, border + blur, stripe_p));
93 |
94 | float gradient_t = (stripe_p - w[0] - w[1]) / w[2];
95 | float gradient = mix(c1, c2, smoothstep(0., 1., gradient_t));
96 | ch = mix(ch, gradient, smoothstep(border - blur, border + blur, stripe_p));
97 |
98 | return ch;
99 | }
100 |
101 | float get_img_frame_alpha(vec2 uv, float img_frame_width) {
102 | float img_frame_alpha = smoothstep(0., img_frame_width, uv.x) * smoothstep(1., 1. - img_frame_width, uv.x);
103 | img_frame_alpha *= smoothstep(0., img_frame_width, uv.y) * smoothstep(1., 1. - img_frame_width, uv.y);
104 | return img_frame_alpha;
105 | }
106 |
107 | void main() {
108 | vec2 uv = FlutterFragCoord().xy / uSize;
109 | uv.x *= u_ratio;
110 |
111 | float diagonal = uv.x - uv.y;
112 |
113 | float t = .001 * u_time;
114 |
115 | vec2 img_uv = get_img_uv(vec2(uv.x, 1. - uv.y));
116 | vec4 img = texture(u_image_texture, img_uv);
117 |
118 | vec3 color = vec3(0.);
119 | float opacity = 1.;
120 |
121 | vec3 color1 = vec3(.98, 0.98, 1.);
122 | vec3 color2 = vec3(.1, .1, .1 + .1 * smoothstep(.7, 1.3, uv.x + uv.y));
123 |
124 | float edge = img.r;
125 |
126 | vec2 grad_uv = uv;
127 | grad_uv -= .5;
128 |
129 | float dist = length(grad_uv + vec2(0., .2 * diagonal));
130 |
131 | grad_uv = rotate(grad_uv, (.25 - .2 * diagonal) * PI);
132 |
133 | float bulge = pow(1.8 * dist, 1.2);
134 | bulge = 1. - bulge;
135 | bulge *= pow(uv.y, .3);
136 |
137 | float cycle_width = u_patternScale;
138 | float thin_strip_1_ratio = .12 / cycle_width * (1. - .4 * bulge);
139 | float thin_strip_2_ratio = .07 / cycle_width * (1. + .4 * bulge);
140 | float wide_strip_ratio = (1. - thin_strip_1_ratio - thin_strip_2_ratio);
141 |
142 | float thin_strip_1_width = cycle_width * thin_strip_1_ratio;
143 | float thin_strip_2_width = cycle_width * thin_strip_2_ratio;
144 |
145 | opacity = 1. - smoothstep(.9 - .5 * u_edge, 1. - .5 * u_edge, edge);
146 | opacity *= get_img_frame_alpha(img_uv, 0.01);
147 |
148 | float noise = snoise(uv - t);
149 |
150 | edge += (1. - edge) * u_liquid * noise;
151 |
152 | float refr = 0.;
153 | refr += (1. - bulge);
154 | refr = clamp(refr, 0., 1.);
155 |
156 | float dir = grad_uv.x;
157 |
158 | dir += diagonal;
159 |
160 | dir -= 2. * noise * diagonal * (smoothstep(0., 1., edge) * smoothstep(1., 0., edge));
161 |
162 | bulge *= clamp(pow(uv.y, .1), .3, 1.);
163 | dir *= (.1 + (1.1 - edge) * bulge);
164 |
165 | dir *= smoothstep(1., .7, edge);
166 |
167 | dir += .18 * (smoothstep(.1, .2, uv.y) * smoothstep(.4, .2, uv.y));
168 | dir += .03 * (smoothstep(.1, .2, 1. - uv.y) * smoothstep(.4, .2, 1. - uv.y));
169 |
170 | dir *= (.5 + .5 * pow(uv.y, 2.));
171 |
172 | dir *= cycle_width;
173 |
174 | dir -= t;
175 |
176 | float refr_r = refr;
177 | refr_r += .03 * bulge * noise;
178 | float refr_b = 1.3 * refr;
179 |
180 | refr_r += 5. * (smoothstep(-.1, .2, uv.y) * smoothstep(.5, .1, uv.y)) * (smoothstep(.4, .6, bulge) * smoothstep(1., .4, bulge));
181 | refr_r -= diagonal;
182 |
183 | refr_b += (smoothstep(0., .4, uv.y) * smoothstep(.8, .1, uv.y)) * (smoothstep(.4, .6, bulge) * smoothstep(.8, .4, bulge));
184 | refr_b -= .2 * edge;
185 |
186 | refr_r *= u_refraction;
187 | refr_b *= u_refraction;
188 |
189 | vec3 w = vec3(thin_strip_1_width, thin_strip_2_width, wide_strip_ratio);
190 | w[1] -= .02 * smoothstep(.0, 1., edge + bulge);
191 | float stripe_r = mod(dir + refr_r, 1.);
192 | float r = get_color_channel(color1.r, color2.r, stripe_r, w, 0.02 + .03 * u_refraction * bulge, bulge);
193 | float stripe_g = mod(dir, 1.);
194 | float g = get_color_channel(color1.g, color2.g, stripe_g, w, 0.01 / (1. - diagonal), bulge);
195 | float stripe_b = mod(dir - refr_b, 1.);
196 | float b = get_color_channel(color1.b, color2.b, stripe_b, w, .01, bulge);
197 |
198 | color = vec3(r, g, b);
199 |
200 | color *= opacity;
201 |
202 | fragColor = vec4(color, opacity);
203 | }
--------------------------------------------------------------------------------
/lib/control_panel.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:paper_liquid_metal_logo/liquid_metal_logo_state.dart';
3 | import 'package:paper_liquid_metal_logo/liquid_metal_shader_controller.dart';
4 | import 'package:paper_liquid_metal_logo/simple_slider.dart';
5 | import 'package:provider/provider.dart';
6 |
7 | class ControlPanel extends StatelessWidget {
8 | const ControlPanel({super.key});
9 |
10 | @override
11 | Widget build(BuildContext context) {
12 | final controller = context.read();
13 |
14 | final controls = Padding(
15 | padding: const EdgeInsets.all(16),
16 | child: Column(
17 | spacing: 12,
18 | children: [
19 | const _BackgroundControl(),
20 | _Control(
21 | label: 'Dispersion',
22 | parameter: controller.dispersion,
23 | ),
24 | _Control(
25 | label: 'Edge',
26 | parameter: controller.edge,
27 | ),
28 | _Control(
29 | label: 'Pattern Blur',
30 | parameter: controller.patternBlur,
31 | ),
32 | _Control(
33 | label: 'Liquify',
34 | parameter: controller.liquid,
35 | ),
36 | _Control(
37 | label: 'Speed',
38 | parameter: controller.speed,
39 | ),
40 | _Control(
41 | label: 'Pattern Scale',
42 | parameter: controller.patternScale,
43 | ),
44 | ],
45 | ),
46 | );
47 |
48 | return DecoratedBox(
49 | decoration: const BoxDecoration(
50 | borderRadius: BorderRadius.all(Radius.circular(8)),
51 | border: Border.fromBorderSide(
52 | BorderSide(color: Color(0x33FFFFFF)),
53 | ),
54 | ),
55 | child: Builder(
56 | builder: (context) {
57 | final windowWidth = MediaQuery.sizeOf(context).width;
58 |
59 | return ConstrainedBox(
60 | constraints: BoxConstraints(
61 | maxHeight: windowWidth >= 1200 ? 500 : double.infinity,
62 | maxWidth: 500,
63 | ),
64 | child: controls,
65 | );
66 | },
67 | ),
68 | );
69 | }
70 | }
71 |
72 | class _BackgroundControl extends StatelessWidget {
73 | const _BackgroundControl();
74 |
75 | @override
76 | Widget build(BuildContext context) {
77 | return Row(
78 | spacing: 24,
79 | children: [
80 | const Expanded(
81 | child: _Label(label: 'Background'),
82 | ),
83 | Builder(
84 | builder: (context) {
85 | final width = MediaQuery.sizeOf(context).width;
86 | final isCompactLayout = width < 600;
87 |
88 | return SizedBox(
89 | width: isCompactLayout ? 200 : 284,
90 | child: Row(
91 | spacing: 8,
92 | children: [
93 | for (final background in LiquidMetalLogoBackground.values)
94 | _BackgroundCircle(background: background),
95 | ],
96 | ),
97 | );
98 | },
99 | ),
100 | ],
101 | );
102 | }
103 | }
104 |
105 | class _BackgroundCircle extends StatelessWidget {
106 | const _BackgroundCircle({
107 | required this.background,
108 | });
109 |
110 | final LiquidMetalLogoBackground background;
111 |
112 | @override
113 | Widget build(BuildContext context) {
114 | return GestureDetector(
115 | onTap: () {
116 | context.read().background = background;
117 | },
118 | child: ClipRRect(
119 | borderRadius: const BorderRadius.all(
120 | Radius.circular(14),
121 | ),
122 | child: MouseRegion(
123 | cursor: SystemMouseCursors.click,
124 | child: DecoratedBox(
125 | decoration: ShapeDecoration(
126 | shape: CircleBorder(
127 | side: background == LiquidMetalLogoBackground.black
128 | ? const BorderSide(color: Color(0x4DFFFFFF))
129 | : BorderSide.none,
130 | ),
131 | gradient: background.gradient,
132 | ),
133 | child: const SizedBox.square(dimension: 28),
134 | ),
135 | ),
136 | ),
137 | );
138 | }
139 | }
140 |
141 | class _Control extends StatelessWidget {
142 | const _Control({
143 | required this.label,
144 | required this.parameter,
145 | });
146 |
147 | final String label;
148 |
149 | final LiquidMetalShaderEditableParameter parameter;
150 |
151 | @override
152 | Widget build(BuildContext context) {
153 | return Row(
154 | spacing: 24,
155 | children: [
156 | Expanded(
157 | child: _Label(label: label),
158 | ),
159 | RepaintBoundary(
160 | child: ValueListenableBuilder(
161 | valueListenable: parameter,
162 | builder: (context, value, _) {
163 | final width = MediaQuery.sizeOf(context).width;
164 | final isCompactLayout = width < 600;
165 |
166 | return Row(
167 | spacing: 24,
168 | children: [
169 | SizedBox(
170 | width: isCompactLayout ? 200 : 160,
171 | child: SimpleSlider(
172 | value: value,
173 | minValue: parameter.minValue,
174 | maxValue: parameter.maxValue,
175 | onChanged: (value) {
176 | parameter.value = value;
177 | },
178 | ),
179 | ),
180 | if (!isCompactLayout) _ValuePreview(value: value),
181 | ],
182 | );
183 | },
184 | ),
185 | ),
186 | ],
187 | );
188 | }
189 | }
190 |
191 | class _Label extends StatelessWidget {
192 | const _Label({
193 | required this.label,
194 | });
195 |
196 | final String label;
197 |
198 | @override
199 | Widget build(BuildContext context) {
200 | return Text(
201 | label,
202 | overflow: TextOverflow.ellipsis,
203 | style: const TextStyle(
204 | fontFamily: 'Montserrat',
205 | fontWeight: FontWeight.w400,
206 | fontSize: 18,
207 | height: 28 / 18,
208 | letterSpacing: -0.68,
209 | color: Colors.white,
210 | ),
211 | );
212 | }
213 | }
214 |
215 | class _ValuePreview extends StatelessWidget {
216 | const _ValuePreview({
217 | required this.value,
218 | });
219 |
220 | final double value;
221 |
222 | @override
223 | Widget build(BuildContext context) {
224 | return DecoratedBox(
225 | decoration: const BoxDecoration(
226 | borderRadius: BorderRadius.all(Radius.circular(4)),
227 | color: Color(0x26FFFFFF),
228 | ),
229 | child: SizedBox(
230 | height: 40,
231 | width: 100,
232 | child: Align(
233 | alignment: Alignment.centerLeft,
234 | child: Padding(
235 | padding: const EdgeInsets.symmetric(horizontal: 14),
236 | child: Text(
237 | value % 1 == 0
238 | ? value.toStringAsFixed(0)
239 | : value.toStringAsFixed(3),
240 | style: const TextStyle(
241 | fontFamily: 'Montserrat',
242 | fontWeight: FontWeight.w400,
243 | fontSize: 16,
244 | height: 24 / 16,
245 | letterSpacing: -0.68,
246 | color: Colors.white,
247 | ),
248 | ),
249 | ),
250 | ),
251 | ),
252 | );
253 | }
254 | }
255 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | args:
5 | dependency: transitive
6 | description:
7 | name: args
8 | sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
9 | url: "https://pub.dev"
10 | source: hosted
11 | version: "2.7.0"
12 | async:
13 | dependency: transitive
14 | description:
15 | name: async
16 | sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
17 | url: "https://pub.dev"
18 | source: hosted
19 | version: "2.12.0"
20 | boolean_selector:
21 | dependency: transitive
22 | description:
23 | name: boolean_selector
24 | sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
25 | url: "https://pub.dev"
26 | source: hosted
27 | version: "2.1.2"
28 | characters:
29 | dependency: transitive
30 | description:
31 | name: characters
32 | sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
33 | url: "https://pub.dev"
34 | source: hosted
35 | version: "1.4.0"
36 | clock:
37 | dependency: transitive
38 | description:
39 | name: clock
40 | sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
41 | url: "https://pub.dev"
42 | source: hosted
43 | version: "1.1.2"
44 | collection:
45 | dependency: transitive
46 | description:
47 | name: collection
48 | sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
49 | url: "https://pub.dev"
50 | source: hosted
51 | version: "1.19.1"
52 | fake_async:
53 | dependency: transitive
54 | description:
55 | name: fake_async
56 | sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc"
57 | url: "https://pub.dev"
58 | source: hosted
59 | version: "1.3.2"
60 | flutter:
61 | dependency: "direct main"
62 | description: flutter
63 | source: sdk
64 | version: "0.0.0"
65 | flutter_shaders:
66 | dependency: "direct main"
67 | description:
68 | name: flutter_shaders
69 | sha256: "34794acadd8275d971e02df03afee3dee0f98dbfb8c4837082ad0034f612a3e2"
70 | url: "https://pub.dev"
71 | source: hosted
72 | version: "0.1.3"
73 | flutter_test:
74 | dependency: "direct dev"
75 | description: flutter
76 | source: sdk
77 | version: "0.0.0"
78 | http:
79 | dependency: transitive
80 | description:
81 | name: http
82 | sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f
83 | url: "https://pub.dev"
84 | source: hosted
85 | version: "1.3.0"
86 | http_parser:
87 | dependency: transitive
88 | description:
89 | name: http_parser
90 | sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
91 | url: "https://pub.dev"
92 | source: hosted
93 | version: "4.1.2"
94 | leak_tracker:
95 | dependency: transitive
96 | description:
97 | name: leak_tracker
98 | sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
99 | url: "https://pub.dev"
100 | source: hosted
101 | version: "10.0.8"
102 | leak_tracker_flutter_testing:
103 | dependency: transitive
104 | description:
105 | name: leak_tracker_flutter_testing
106 | sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
107 | url: "https://pub.dev"
108 | source: hosted
109 | version: "3.0.9"
110 | leak_tracker_testing:
111 | dependency: transitive
112 | description:
113 | name: leak_tracker_testing
114 | sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
115 | url: "https://pub.dev"
116 | source: hosted
117 | version: "3.0.1"
118 | matcher:
119 | dependency: transitive
120 | description:
121 | name: matcher
122 | sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
123 | url: "https://pub.dev"
124 | source: hosted
125 | version: "0.12.17"
126 | material_color_utilities:
127 | dependency: transitive
128 | description:
129 | name: material_color_utilities
130 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
131 | url: "https://pub.dev"
132 | source: hosted
133 | version: "0.11.1"
134 | meta:
135 | dependency: transitive
136 | description:
137 | name: meta
138 | sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
139 | url: "https://pub.dev"
140 | source: hosted
141 | version: "1.16.0"
142 | nested:
143 | dependency: transitive
144 | description:
145 | name: nested
146 | sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
147 | url: "https://pub.dev"
148 | source: hosted
149 | version: "1.0.0"
150 | path:
151 | dependency: transitive
152 | description:
153 | name: path
154 | sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
155 | url: "https://pub.dev"
156 | source: hosted
157 | version: "1.9.1"
158 | path_parsing:
159 | dependency: transitive
160 | description:
161 | name: path_parsing
162 | sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca"
163 | url: "https://pub.dev"
164 | source: hosted
165 | version: "1.1.0"
166 | petitparser:
167 | dependency: transitive
168 | description:
169 | name: petitparser
170 | sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646"
171 | url: "https://pub.dev"
172 | source: hosted
173 | version: "6.1.0"
174 | provider:
175 | dependency: "direct main"
176 | description:
177 | name: provider
178 | sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
179 | url: "https://pub.dev"
180 | source: hosted
181 | version: "6.1.2"
182 | sky_engine:
183 | dependency: transitive
184 | description: flutter
185 | source: sdk
186 | version: "0.0.0"
187 | source_span:
188 | dependency: transitive
189 | description:
190 | name: source_span
191 | sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
192 | url: "https://pub.dev"
193 | source: hosted
194 | version: "1.10.1"
195 | stack_trace:
196 | dependency: transitive
197 | description:
198 | name: stack_trace
199 | sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
200 | url: "https://pub.dev"
201 | source: hosted
202 | version: "1.12.1"
203 | stream_channel:
204 | dependency: transitive
205 | description:
206 | name: stream_channel
207 | sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
208 | url: "https://pub.dev"
209 | source: hosted
210 | version: "2.1.4"
211 | string_scanner:
212 | dependency: transitive
213 | description:
214 | name: string_scanner
215 | sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
216 | url: "https://pub.dev"
217 | source: hosted
218 | version: "1.4.1"
219 | term_glyph:
220 | dependency: transitive
221 | description:
222 | name: term_glyph
223 | sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
224 | url: "https://pub.dev"
225 | source: hosted
226 | version: "1.2.2"
227 | test_api:
228 | dependency: transitive
229 | description:
230 | name: test_api
231 | sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
232 | url: "https://pub.dev"
233 | source: hosted
234 | version: "0.7.4"
235 | typed_data:
236 | dependency: transitive
237 | description:
238 | name: typed_data
239 | sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
240 | url: "https://pub.dev"
241 | source: hosted
242 | version: "1.4.0"
243 | vector_graphics:
244 | dependency: "direct main"
245 | description:
246 | name: vector_graphics
247 | sha256: "44cc7104ff32563122a929e4620cf3efd584194eec6d1d913eb5ba593dbcf6de"
248 | url: "https://pub.dev"
249 | source: hosted
250 | version: "1.1.18"
251 | vector_graphics_codec:
252 | dependency: transitive
253 | description:
254 | name: vector_graphics_codec
255 | sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146"
256 | url: "https://pub.dev"
257 | source: hosted
258 | version: "1.1.13"
259 | vector_graphics_compiler:
260 | dependency: "direct dev"
261 | description:
262 | name: vector_graphics_compiler
263 | sha256: "1b4b9e706a10294258727674a340ae0d6e64a7231980f9f9a3d12e4b42407aad"
264 | url: "https://pub.dev"
265 | source: hosted
266 | version: "1.1.16"
267 | vector_math:
268 | dependency: transitive
269 | description:
270 | name: vector_math
271 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
272 | url: "https://pub.dev"
273 | source: hosted
274 | version: "2.1.4"
275 | very_good_analysis:
276 | dependency: "direct dev"
277 | description:
278 | name: very_good_analysis
279 | sha256: "62d2b86d183fb81b2edc22913d9f155d26eb5cf3855173adb1f59fac85035c63"
280 | url: "https://pub.dev"
281 | source: hosted
282 | version: "7.0.0"
283 | vm_service:
284 | dependency: transitive
285 | description:
286 | name: vm_service
287 | sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14"
288 | url: "https://pub.dev"
289 | source: hosted
290 | version: "14.3.1"
291 | web:
292 | dependency: transitive
293 | description:
294 | name: web
295 | sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
296 | url: "https://pub.dev"
297 | source: hosted
298 | version: "1.1.1"
299 | xml:
300 | dependency: transitive
301 | description:
302 | name: xml
303 | sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
304 | url: "https://pub.dev"
305 | source: hosted
306 | version: "6.5.0"
307 | sdks:
308 | dart: ">=3.7.0-0 <4.0.0"
309 | flutter: ">=3.22.0"
310 |
--------------------------------------------------------------------------------
/macos/Runner/Base.lproj/MainMenu.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
--------------------------------------------------------------------------------
/macos/Runner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 54;
7 | objects = {
8 |
9 | /* Begin PBXAggregateTarget section */
10 | 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = {
11 | isa = PBXAggregateTarget;
12 | buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */;
13 | buildPhases = (
14 | 33CC111E2044C6BF0003C045 /* ShellScript */,
15 | );
16 | dependencies = (
17 | );
18 | name = "Flutter Assemble";
19 | productName = FLX;
20 | };
21 | /* End PBXAggregateTarget section */
22 |
23 | /* Begin PBXBuildFile section */
24 | 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; };
25 | 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; };
26 | 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; };
27 | 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
28 | 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
29 | 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
30 | /* End PBXBuildFile section */
31 |
32 | /* Begin PBXContainerItemProxy section */
33 | 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */ = {
34 | isa = PBXContainerItemProxy;
35 | containerPortal = 33CC10E52044A3C60003C045 /* Project object */;
36 | proxyType = 1;
37 | remoteGlobalIDString = 33CC10EC2044A3C60003C045;
38 | remoteInfo = Runner;
39 | };
40 | 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = {
41 | isa = PBXContainerItemProxy;
42 | containerPortal = 33CC10E52044A3C60003C045 /* Project object */;
43 | proxyType = 1;
44 | remoteGlobalIDString = 33CC111A2044C6BA0003C045;
45 | remoteInfo = FLX;
46 | };
47 | /* End PBXContainerItemProxy section */
48 |
49 | /* Begin PBXCopyFilesBuildPhase section */
50 | 33CC110E2044A8840003C045 /* Bundle Framework */ = {
51 | isa = PBXCopyFilesBuildPhase;
52 | buildActionMask = 2147483647;
53 | dstPath = "";
54 | dstSubfolderSpec = 10;
55 | files = (
56 | );
57 | name = "Bundle Framework";
58 | runOnlyForDeploymentPostprocessing = 0;
59 | };
60 | /* End PBXCopyFilesBuildPhase section */
61 |
62 | /* Begin PBXFileReference section */
63 | 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
64 | 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; };
65 | 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; };
66 | 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; };
67 | 33CC10ED2044A3C60003C045 /* paper_liquid_metal_logo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "paper_liquid_metal_logo.app"; sourceTree = BUILT_PRODUCTS_DIR; };
68 | 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
69 | 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; };
70 | 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; };
71 | 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; };
72 | 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; };
73 | 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; };
74 | 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; };
75 | 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; };
76 | 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; };
77 | 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; };
78 | 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; };
79 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; };
80 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; };
81 | /* End PBXFileReference section */
82 |
83 | /* Begin PBXFrameworksBuildPhase section */
84 | 331C80D2294CF70F00263BE5 /* Frameworks */ = {
85 | isa = PBXFrameworksBuildPhase;
86 | buildActionMask = 2147483647;
87 | files = (
88 | );
89 | runOnlyForDeploymentPostprocessing = 0;
90 | };
91 | 33CC10EA2044A3C60003C045 /* Frameworks */ = {
92 | isa = PBXFrameworksBuildPhase;
93 | buildActionMask = 2147483647;
94 | files = (
95 | );
96 | runOnlyForDeploymentPostprocessing = 0;
97 | };
98 | /* End PBXFrameworksBuildPhase section */
99 |
100 | /* Begin PBXGroup section */
101 | 331C80D6294CF71000263BE5 /* RunnerTests */ = {
102 | isa = PBXGroup;
103 | children = (
104 | 331C80D7294CF71000263BE5 /* RunnerTests.swift */,
105 | );
106 | path = RunnerTests;
107 | sourceTree = "";
108 | };
109 | 33BA886A226E78AF003329D5 /* Configs */ = {
110 | isa = PBXGroup;
111 | children = (
112 | 33E5194F232828860026EE4D /* AppInfo.xcconfig */,
113 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
114 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
115 | 333000ED22D3DE5D00554162 /* Warnings.xcconfig */,
116 | );
117 | path = Configs;
118 | sourceTree = "";
119 | };
120 | 33CC10E42044A3C60003C045 = {
121 | isa = PBXGroup;
122 | children = (
123 | 33FAB671232836740065AC1E /* Runner */,
124 | 33CEB47122A05771004F2AC0 /* Flutter */,
125 | 331C80D6294CF71000263BE5 /* RunnerTests */,
126 | 33CC10EE2044A3C60003C045 /* Products */,
127 | D73912EC22F37F3D000D13A0 /* Frameworks */,
128 | );
129 | sourceTree = "";
130 | };
131 | 33CC10EE2044A3C60003C045 /* Products */ = {
132 | isa = PBXGroup;
133 | children = (
134 | 33CC10ED2044A3C60003C045 /* paper_liquid_metal_logo.app */,
135 | 331C80D5294CF71000263BE5 /* RunnerTests.xctest */,
136 | );
137 | name = Products;
138 | sourceTree = "";
139 | };
140 | 33CC11242044D66E0003C045 /* Resources */ = {
141 | isa = PBXGroup;
142 | children = (
143 | 33CC10F22044A3C60003C045 /* Assets.xcassets */,
144 | 33CC10F42044A3C60003C045 /* MainMenu.xib */,
145 | 33CC10F72044A3C60003C045 /* Info.plist */,
146 | );
147 | name = Resources;
148 | path = ..;
149 | sourceTree = "";
150 | };
151 | 33CEB47122A05771004F2AC0 /* Flutter */ = {
152 | isa = PBXGroup;
153 | children = (
154 | 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */,
155 | 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */,
156 | 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */,
157 | 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */,
158 | );
159 | path = Flutter;
160 | sourceTree = "";
161 | };
162 | 33FAB671232836740065AC1E /* Runner */ = {
163 | isa = PBXGroup;
164 | children = (
165 | 33CC10F02044A3C60003C045 /* AppDelegate.swift */,
166 | 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */,
167 | 33E51913231747F40026EE4D /* DebugProfile.entitlements */,
168 | 33E51914231749380026EE4D /* Release.entitlements */,
169 | 33CC11242044D66E0003C045 /* Resources */,
170 | 33BA886A226E78AF003329D5 /* Configs */,
171 | );
172 | path = Runner;
173 | sourceTree = "";
174 | };
175 | D73912EC22F37F3D000D13A0 /* Frameworks */ = {
176 | isa = PBXGroup;
177 | children = (
178 | );
179 | name = Frameworks;
180 | sourceTree = "";
181 | };
182 | /* End PBXGroup section */
183 |
184 | /* Begin PBXNativeTarget section */
185 | 331C80D4294CF70F00263BE5 /* RunnerTests */ = {
186 | isa = PBXNativeTarget;
187 | buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
188 | buildPhases = (
189 | 331C80D1294CF70F00263BE5 /* Sources */,
190 | 331C80D2294CF70F00263BE5 /* Frameworks */,
191 | 331C80D3294CF70F00263BE5 /* Resources */,
192 | );
193 | buildRules = (
194 | );
195 | dependencies = (
196 | 331C80DA294CF71000263BE5 /* PBXTargetDependency */,
197 | );
198 | name = RunnerTests;
199 | productName = RunnerTests;
200 | productReference = 331C80D5294CF71000263BE5 /* RunnerTests.xctest */;
201 | productType = "com.apple.product-type.bundle.unit-test";
202 | };
203 | 33CC10EC2044A3C60003C045 /* Runner */ = {
204 | isa = PBXNativeTarget;
205 | buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
206 | buildPhases = (
207 | 33CC10E92044A3C60003C045 /* Sources */,
208 | 33CC10EA2044A3C60003C045 /* Frameworks */,
209 | 33CC10EB2044A3C60003C045 /* Resources */,
210 | 33CC110E2044A8840003C045 /* Bundle Framework */,
211 | 3399D490228B24CF009A79C7 /* ShellScript */,
212 | );
213 | buildRules = (
214 | );
215 | dependencies = (
216 | 33CC11202044C79F0003C045 /* PBXTargetDependency */,
217 | );
218 | name = Runner;
219 | productName = Runner;
220 | productReference = 33CC10ED2044A3C60003C045 /* paper_liquid_metal_logo.app */;
221 | productType = "com.apple.product-type.application";
222 | };
223 | /* End PBXNativeTarget section */
224 |
225 | /* Begin PBXProject section */
226 | 33CC10E52044A3C60003C045 /* Project object */ = {
227 | isa = PBXProject;
228 | attributes = {
229 | BuildIndependentTargetsInParallel = YES;
230 | LastSwiftUpdateCheck = 0920;
231 | LastUpgradeCheck = 1510;
232 | ORGANIZATIONNAME = "";
233 | TargetAttributes = {
234 | 331C80D4294CF70F00263BE5 = {
235 | CreatedOnToolsVersion = 14.0;
236 | TestTargetID = 33CC10EC2044A3C60003C045;
237 | };
238 | 33CC10EC2044A3C60003C045 = {
239 | CreatedOnToolsVersion = 9.2;
240 | LastSwiftMigration = 1100;
241 | ProvisioningStyle = Automatic;
242 | SystemCapabilities = {
243 | com.apple.Sandbox = {
244 | enabled = 1;
245 | };
246 | };
247 | };
248 | 33CC111A2044C6BA0003C045 = {
249 | CreatedOnToolsVersion = 9.2;
250 | ProvisioningStyle = Manual;
251 | };
252 | };
253 | };
254 | buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */;
255 | compatibilityVersion = "Xcode 9.3";
256 | developmentRegion = en;
257 | hasScannedForEncodings = 0;
258 | knownRegions = (
259 | en,
260 | Base,
261 | );
262 | mainGroup = 33CC10E42044A3C60003C045;
263 | productRefGroup = 33CC10EE2044A3C60003C045 /* Products */;
264 | projectDirPath = "";
265 | projectRoot = "";
266 | targets = (
267 | 33CC10EC2044A3C60003C045 /* Runner */,
268 | 331C80D4294CF70F00263BE5 /* RunnerTests */,
269 | 33CC111A2044C6BA0003C045 /* Flutter Assemble */,
270 | );
271 | };
272 | /* End PBXProject section */
273 |
274 | /* Begin PBXResourcesBuildPhase section */
275 | 331C80D3294CF70F00263BE5 /* Resources */ = {
276 | isa = PBXResourcesBuildPhase;
277 | buildActionMask = 2147483647;
278 | files = (
279 | );
280 | runOnlyForDeploymentPostprocessing = 0;
281 | };
282 | 33CC10EB2044A3C60003C045 /* Resources */ = {
283 | isa = PBXResourcesBuildPhase;
284 | buildActionMask = 2147483647;
285 | files = (
286 | 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */,
287 | 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */,
288 | );
289 | runOnlyForDeploymentPostprocessing = 0;
290 | };
291 | /* End PBXResourcesBuildPhase section */
292 |
293 | /* Begin PBXShellScriptBuildPhase section */
294 | 3399D490228B24CF009A79C7 /* ShellScript */ = {
295 | isa = PBXShellScriptBuildPhase;
296 | alwaysOutOfDate = 1;
297 | buildActionMask = 2147483647;
298 | files = (
299 | );
300 | inputFileListPaths = (
301 | );
302 | inputPaths = (
303 | );
304 | outputFileListPaths = (
305 | );
306 | outputPaths = (
307 | );
308 | runOnlyForDeploymentPostprocessing = 0;
309 | shellPath = /bin/sh;
310 | shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n";
311 | };
312 | 33CC111E2044C6BF0003C045 /* ShellScript */ = {
313 | isa = PBXShellScriptBuildPhase;
314 | buildActionMask = 2147483647;
315 | files = (
316 | );
317 | inputFileListPaths = (
318 | Flutter/ephemeral/FlutterInputs.xcfilelist,
319 | );
320 | inputPaths = (
321 | Flutter/ephemeral/tripwire,
322 | );
323 | outputFileListPaths = (
324 | Flutter/ephemeral/FlutterOutputs.xcfilelist,
325 | );
326 | outputPaths = (
327 | );
328 | runOnlyForDeploymentPostprocessing = 0;
329 | shellPath = /bin/sh;
330 | shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
331 | };
332 | /* End PBXShellScriptBuildPhase section */
333 |
334 | /* Begin PBXSourcesBuildPhase section */
335 | 331C80D1294CF70F00263BE5 /* Sources */ = {
336 | isa = PBXSourcesBuildPhase;
337 | buildActionMask = 2147483647;
338 | files = (
339 | 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */,
340 | );
341 | runOnlyForDeploymentPostprocessing = 0;
342 | };
343 | 33CC10E92044A3C60003C045 /* Sources */ = {
344 | isa = PBXSourcesBuildPhase;
345 | buildActionMask = 2147483647;
346 | files = (
347 | 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */,
348 | 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */,
349 | 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */,
350 | );
351 | runOnlyForDeploymentPostprocessing = 0;
352 | };
353 | /* End PBXSourcesBuildPhase section */
354 |
355 | /* Begin PBXTargetDependency section */
356 | 331C80DA294CF71000263BE5 /* PBXTargetDependency */ = {
357 | isa = PBXTargetDependency;
358 | target = 33CC10EC2044A3C60003C045 /* Runner */;
359 | targetProxy = 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */;
360 | };
361 | 33CC11202044C79F0003C045 /* PBXTargetDependency */ = {
362 | isa = PBXTargetDependency;
363 | target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */;
364 | targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */;
365 | };
366 | /* End PBXTargetDependency section */
367 |
368 | /* Begin PBXVariantGroup section */
369 | 33CC10F42044A3C60003C045 /* MainMenu.xib */ = {
370 | isa = PBXVariantGroup;
371 | children = (
372 | 33CC10F52044A3C60003C045 /* Base */,
373 | );
374 | name = MainMenu.xib;
375 | path = Runner;
376 | sourceTree = "";
377 | };
378 | /* End PBXVariantGroup section */
379 |
380 | /* Begin XCBuildConfiguration section */
381 | 331C80DB294CF71000263BE5 /* Debug */ = {
382 | isa = XCBuildConfiguration;
383 | buildSettings = {
384 | BUNDLE_LOADER = "$(TEST_HOST)";
385 | CURRENT_PROJECT_VERSION = 1;
386 | GENERATE_INFOPLIST_FILE = YES;
387 | MARKETING_VERSION = 1.0;
388 | PRODUCT_BUNDLE_IDENTIFIER = com.example.paperLiquidMetalLogo.RunnerTests;
389 | PRODUCT_NAME = "$(TARGET_NAME)";
390 | SWIFT_VERSION = 5.0;
391 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/paper_liquid_metal_logo.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/paper_liquid_metal_logo";
392 | };
393 | name = Debug;
394 | };
395 | 331C80DC294CF71000263BE5 /* Release */ = {
396 | isa = XCBuildConfiguration;
397 | buildSettings = {
398 | BUNDLE_LOADER = "$(TEST_HOST)";
399 | CURRENT_PROJECT_VERSION = 1;
400 | GENERATE_INFOPLIST_FILE = YES;
401 | MARKETING_VERSION = 1.0;
402 | PRODUCT_BUNDLE_IDENTIFIER = com.example.paperLiquidMetalLogo.RunnerTests;
403 | PRODUCT_NAME = "$(TARGET_NAME)";
404 | SWIFT_VERSION = 5.0;
405 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/paper_liquid_metal_logo.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/paper_liquid_metal_logo";
406 | };
407 | name = Release;
408 | };
409 | 331C80DD294CF71000263BE5 /* Profile */ = {
410 | isa = XCBuildConfiguration;
411 | buildSettings = {
412 | BUNDLE_LOADER = "$(TEST_HOST)";
413 | CURRENT_PROJECT_VERSION = 1;
414 | GENERATE_INFOPLIST_FILE = YES;
415 | MARKETING_VERSION = 1.0;
416 | PRODUCT_BUNDLE_IDENTIFIER = com.example.paperLiquidMetalLogo.RunnerTests;
417 | PRODUCT_NAME = "$(TARGET_NAME)";
418 | SWIFT_VERSION = 5.0;
419 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/paper_liquid_metal_logo.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/paper_liquid_metal_logo";
420 | };
421 | name = Profile;
422 | };
423 | 338D0CE9231458BD00FA5F75 /* Profile */ = {
424 | isa = XCBuildConfiguration;
425 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
426 | buildSettings = {
427 | ALWAYS_SEARCH_USER_PATHS = NO;
428 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
429 | CLANG_ANALYZER_NONNULL = YES;
430 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
431 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
432 | CLANG_CXX_LIBRARY = "libc++";
433 | CLANG_ENABLE_MODULES = YES;
434 | CLANG_ENABLE_OBJC_ARC = YES;
435 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
436 | CLANG_WARN_BOOL_CONVERSION = YES;
437 | CLANG_WARN_CONSTANT_CONVERSION = YES;
438 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
439 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
440 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
441 | CLANG_WARN_EMPTY_BODY = YES;
442 | CLANG_WARN_ENUM_CONVERSION = YES;
443 | CLANG_WARN_INFINITE_RECURSION = YES;
444 | CLANG_WARN_INT_CONVERSION = YES;
445 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
446 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
447 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
448 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
449 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
450 | CODE_SIGN_IDENTITY = "-";
451 | COPY_PHASE_STRIP = NO;
452 | DEAD_CODE_STRIPPING = YES;
453 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
454 | ENABLE_NS_ASSERTIONS = NO;
455 | ENABLE_STRICT_OBJC_MSGSEND = YES;
456 | ENABLE_USER_SCRIPT_SANDBOXING = NO;
457 | GCC_C_LANGUAGE_STANDARD = gnu11;
458 | GCC_NO_COMMON_BLOCKS = YES;
459 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
460 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
461 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
462 | GCC_WARN_UNUSED_FUNCTION = YES;
463 | GCC_WARN_UNUSED_VARIABLE = YES;
464 | MACOSX_DEPLOYMENT_TARGET = 10.14;
465 | MTL_ENABLE_DEBUG_INFO = NO;
466 | SDKROOT = macosx;
467 | SWIFT_COMPILATION_MODE = wholemodule;
468 | SWIFT_OPTIMIZATION_LEVEL = "-O";
469 | };
470 | name = Profile;
471 | };
472 | 338D0CEA231458BD00FA5F75 /* Profile */ = {
473 | isa = XCBuildConfiguration;
474 | baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
475 | buildSettings = {
476 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
477 | CLANG_ENABLE_MODULES = YES;
478 | CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
479 | CODE_SIGN_STYLE = Automatic;
480 | COMBINE_HIDPI_IMAGES = YES;
481 | INFOPLIST_FILE = Runner/Info.plist;
482 | LD_RUNPATH_SEARCH_PATHS = (
483 | "$(inherited)",
484 | "@executable_path/../Frameworks",
485 | );
486 | PROVISIONING_PROFILE_SPECIFIER = "";
487 | SWIFT_VERSION = 5.0;
488 | };
489 | name = Profile;
490 | };
491 | 338D0CEB231458BD00FA5F75 /* Profile */ = {
492 | isa = XCBuildConfiguration;
493 | buildSettings = {
494 | CODE_SIGN_STYLE = Manual;
495 | PRODUCT_NAME = "$(TARGET_NAME)";
496 | };
497 | name = Profile;
498 | };
499 | 33CC10F92044A3C60003C045 /* Debug */ = {
500 | isa = XCBuildConfiguration;
501 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
502 | buildSettings = {
503 | ALWAYS_SEARCH_USER_PATHS = NO;
504 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
505 | CLANG_ANALYZER_NONNULL = YES;
506 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
507 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
508 | CLANG_CXX_LIBRARY = "libc++";
509 | CLANG_ENABLE_MODULES = YES;
510 | CLANG_ENABLE_OBJC_ARC = YES;
511 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
512 | CLANG_WARN_BOOL_CONVERSION = YES;
513 | CLANG_WARN_CONSTANT_CONVERSION = YES;
514 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
515 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
516 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
517 | CLANG_WARN_EMPTY_BODY = YES;
518 | CLANG_WARN_ENUM_CONVERSION = YES;
519 | CLANG_WARN_INFINITE_RECURSION = YES;
520 | CLANG_WARN_INT_CONVERSION = YES;
521 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
522 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
523 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
524 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
525 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
526 | CODE_SIGN_IDENTITY = "-";
527 | COPY_PHASE_STRIP = NO;
528 | DEAD_CODE_STRIPPING = YES;
529 | DEBUG_INFORMATION_FORMAT = dwarf;
530 | ENABLE_STRICT_OBJC_MSGSEND = YES;
531 | ENABLE_TESTABILITY = YES;
532 | ENABLE_USER_SCRIPT_SANDBOXING = NO;
533 | GCC_C_LANGUAGE_STANDARD = gnu11;
534 | GCC_DYNAMIC_NO_PIC = NO;
535 | GCC_NO_COMMON_BLOCKS = YES;
536 | GCC_OPTIMIZATION_LEVEL = 0;
537 | GCC_PREPROCESSOR_DEFINITIONS = (
538 | "DEBUG=1",
539 | "$(inherited)",
540 | );
541 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
542 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
543 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
544 | GCC_WARN_UNUSED_FUNCTION = YES;
545 | GCC_WARN_UNUSED_VARIABLE = YES;
546 | MACOSX_DEPLOYMENT_TARGET = 10.14;
547 | MTL_ENABLE_DEBUG_INFO = YES;
548 | ONLY_ACTIVE_ARCH = YES;
549 | SDKROOT = macosx;
550 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
551 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
552 | };
553 | name = Debug;
554 | };
555 | 33CC10FA2044A3C60003C045 /* Release */ = {
556 | isa = XCBuildConfiguration;
557 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
558 | buildSettings = {
559 | ALWAYS_SEARCH_USER_PATHS = NO;
560 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
561 | CLANG_ANALYZER_NONNULL = YES;
562 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
563 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
564 | CLANG_CXX_LIBRARY = "libc++";
565 | CLANG_ENABLE_MODULES = YES;
566 | CLANG_ENABLE_OBJC_ARC = YES;
567 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
568 | CLANG_WARN_BOOL_CONVERSION = YES;
569 | CLANG_WARN_CONSTANT_CONVERSION = YES;
570 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
571 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
572 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
573 | CLANG_WARN_EMPTY_BODY = YES;
574 | CLANG_WARN_ENUM_CONVERSION = YES;
575 | CLANG_WARN_INFINITE_RECURSION = YES;
576 | CLANG_WARN_INT_CONVERSION = YES;
577 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
578 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
579 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
580 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
581 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
582 | CODE_SIGN_IDENTITY = "-";
583 | COPY_PHASE_STRIP = NO;
584 | DEAD_CODE_STRIPPING = YES;
585 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
586 | ENABLE_NS_ASSERTIONS = NO;
587 | ENABLE_STRICT_OBJC_MSGSEND = YES;
588 | ENABLE_USER_SCRIPT_SANDBOXING = NO;
589 | GCC_C_LANGUAGE_STANDARD = gnu11;
590 | GCC_NO_COMMON_BLOCKS = YES;
591 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
592 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
593 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
594 | GCC_WARN_UNUSED_FUNCTION = YES;
595 | GCC_WARN_UNUSED_VARIABLE = YES;
596 | MACOSX_DEPLOYMENT_TARGET = 10.14;
597 | MTL_ENABLE_DEBUG_INFO = NO;
598 | SDKROOT = macosx;
599 | SWIFT_COMPILATION_MODE = wholemodule;
600 | SWIFT_OPTIMIZATION_LEVEL = "-O";
601 | };
602 | name = Release;
603 | };
604 | 33CC10FC2044A3C60003C045 /* Debug */ = {
605 | isa = XCBuildConfiguration;
606 | baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
607 | buildSettings = {
608 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
609 | CLANG_ENABLE_MODULES = YES;
610 | CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
611 | CODE_SIGN_STYLE = Automatic;
612 | COMBINE_HIDPI_IMAGES = YES;
613 | INFOPLIST_FILE = Runner/Info.plist;
614 | LD_RUNPATH_SEARCH_PATHS = (
615 | "$(inherited)",
616 | "@executable_path/../Frameworks",
617 | );
618 | PROVISIONING_PROFILE_SPECIFIER = "";
619 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
620 | SWIFT_VERSION = 5.0;
621 | };
622 | name = Debug;
623 | };
624 | 33CC10FD2044A3C60003C045 /* Release */ = {
625 | isa = XCBuildConfiguration;
626 | baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
627 | buildSettings = {
628 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
629 | CLANG_ENABLE_MODULES = YES;
630 | CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
631 | CODE_SIGN_STYLE = Automatic;
632 | COMBINE_HIDPI_IMAGES = YES;
633 | INFOPLIST_FILE = Runner/Info.plist;
634 | LD_RUNPATH_SEARCH_PATHS = (
635 | "$(inherited)",
636 | "@executable_path/../Frameworks",
637 | );
638 | PROVISIONING_PROFILE_SPECIFIER = "";
639 | SWIFT_VERSION = 5.0;
640 | };
641 | name = Release;
642 | };
643 | 33CC111C2044C6BA0003C045 /* Debug */ = {
644 | isa = XCBuildConfiguration;
645 | buildSettings = {
646 | CODE_SIGN_STYLE = Manual;
647 | PRODUCT_NAME = "$(TARGET_NAME)";
648 | };
649 | name = Debug;
650 | };
651 | 33CC111D2044C6BA0003C045 /* Release */ = {
652 | isa = XCBuildConfiguration;
653 | buildSettings = {
654 | CODE_SIGN_STYLE = Automatic;
655 | PRODUCT_NAME = "$(TARGET_NAME)";
656 | };
657 | name = Release;
658 | };
659 | /* End XCBuildConfiguration section */
660 |
661 | /* Begin XCConfigurationList section */
662 | 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
663 | isa = XCConfigurationList;
664 | buildConfigurations = (
665 | 331C80DB294CF71000263BE5 /* Debug */,
666 | 331C80DC294CF71000263BE5 /* Release */,
667 | 331C80DD294CF71000263BE5 /* Profile */,
668 | );
669 | defaultConfigurationIsVisible = 0;
670 | defaultConfigurationName = Release;
671 | };
672 | 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = {
673 | isa = XCConfigurationList;
674 | buildConfigurations = (
675 | 33CC10F92044A3C60003C045 /* Debug */,
676 | 33CC10FA2044A3C60003C045 /* Release */,
677 | 338D0CE9231458BD00FA5F75 /* Profile */,
678 | );
679 | defaultConfigurationIsVisible = 0;
680 | defaultConfigurationName = Release;
681 | };
682 | 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = {
683 | isa = XCConfigurationList;
684 | buildConfigurations = (
685 | 33CC10FC2044A3C60003C045 /* Debug */,
686 | 33CC10FD2044A3C60003C045 /* Release */,
687 | 338D0CEA231458BD00FA5F75 /* Profile */,
688 | );
689 | defaultConfigurationIsVisible = 0;
690 | defaultConfigurationName = Release;
691 | };
692 | 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = {
693 | isa = XCConfigurationList;
694 | buildConfigurations = (
695 | 33CC111C2044C6BA0003C045 /* Debug */,
696 | 33CC111D2044C6BA0003C045 /* Release */,
697 | 338D0CEB231458BD00FA5F75 /* Profile */,
698 | );
699 | defaultConfigurationIsVisible = 0;
700 | defaultConfigurationName = Release;
701 | };
702 | /* End XCConfigurationList section */
703 | };
704 | rootObject = 33CC10E52044A3C60003C045 /* Project object */;
705 | }
706 |
--------------------------------------------------------------------------------