1679317505
Microsoft PowerToys is a set of utilities for power users to tune and streamline their Windows experience for greater productivity. For more info on PowerToys overviews and how to use the utilities, or any other tools and resources for Windows development environments, head over to learn.microsoft.com!
Go to Microsoft PowerToys GitHub releases page, click on Assets
at the bottom to show the files available in the release. Please use the appropriate PowerToys installer that matches your machine's architecture. For most, it is x64
.
This is our preferred method.
Install from the Microsoft Store's PowerToys page. You must be using the new Microsoft Store which is available for both Windows 11 and Windows 10.
Download PowerToys from WinGet. To install PowerToys, run the following command from the command line / PowerShell:
winget install Microsoft.PowerToys -s winget
There are community driven install methods such as Chocolatey and Scoop. If these are your preferred install solutions, you can find the install instructions there.
This project welcomes contributions of all types. Help spec'ing, design, documentation, finding bugs are ways everyone can help on top of coding features / bug fixes. We are excited to work with the power user community to build a set of tools for helping you get the most out of Windows.
We ask that before you start work on a feature that you would like to contribute, please read our Contributor's Guide. We will be happy to work with you to figure out the best approach, provide guidance and mentorship throughout feature development, and help avoid any wasted or duplicate effort.
Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution.
For guidance on developing for PowerToys, please read the developer docs for a detailed breakdown. This includes how to setup your computer to compile.
Our prioritized roadmap of features and utilities that the core team is focusing on.
In this release, we focused on releasing new features, stability and improvements.
Highlights
For v0.69, we'll work on below:
The PowerToys team is extremely grateful to have the support of an amazing active community. The work you do is incredibly important. PowerToys wouldn’t be nearly what it is today without your help filing bugs, updating documentation, guiding the design, or writing features. We want to say thank you and take time to recognize your work. Month over month, you directly help make PowerToys a better piece of software.
This project has adopted the Microsoft Open Source Code of Conduct.
The application logs basic telemetry. Our Telemetry Data page (Coming Soon) has the trends from the telemetry. Please read the Microsoft privacy statement for more information.
Author: Microsoft
Source Code: https://github.com/microsoft/PowerToys
License: MIT license
1679158080
SwiftUIX attempts to fill the gaps of the still nascent SwiftUI framework, providing an extensive suite of components, extensions and utilities to complement the standard library. This project is by far the most complete port of missing UIKit/AppKit functionality, striving to deliver it in the most Apple-like fashion possible.
Why
The goal of this project is to complement the SwiftUI standard library, offering hundreds of extensions and views that empower you, the developer, to build applications with the ease promised by the revolution that is SwiftUI.
Requirements
Installation
The preferred way of installing SwiftUIX is via the Swift Package Manager.
Xcode 11 integrates with libSwiftPM to provide support for iOS, watchOS, macOS and tvOS platforms.
https://github.com/SwiftUIX/SwiftUIX
) and click Next.master
).Contents
All documentation is available via the repository wiki.
While the project itself is stable and heavily being used in production, its documentation is work-in-progress. Contributions are encouraged and welcomed.
UIKit | SwiftUI | SwiftUIX |
---|---|---|
LPLinkView | - | LinkPresentationView |
UIActivityIndicatorView | - | ActivityIndicator |
UIActivityViewController | - | AppActivityView |
UIBlurEffect | - | BlurEffectView |
UICollectionView | - | CollectionView |
UIDeviceOrientation | - | DeviceLayoutOrientation |
UIImagePickerController | - | ImagePicker |
UIPageViewController | - | PaginationView |
UIScreen | - | Screen |
UISearchBar | - | SearchBar |
UIScrollView | ScrollView | CocoaScrollView |
UISwipeGestureRecognizer | - | SwipeGestureOverlay |
UITableView | List | CocoaList |
UITextField | TextField | CocoaTextField |
UIModalPresentationStyle | - | ModalPresentationStyle |
UIViewControllerTransitioningDelegate | - | UIHostingControllerTransitioningDelegate |
UIVisualEffectView | - | VisualEffectView |
UIWindow | - | WindowOverlay |
ActivityIndicator
ActivityIndicator()
.animated(true)
.style(.large)
AppActivityView
- a SwiftUI port for UIActivityViewController
.
AppActivityView(activityItems: [...])
.excludeActivityTypes([...])
.onCancel { }
.onComplete { result in
foo(result)
}
View/visible(_:)
- Sets a view's visibility.TryButton
- A button capable of performing throwing functions.flip3D(_:axis:reverse:)
- Flips this view.RectangleCorner
- A corner of a Rectangle.ZeroSizeView
- A zero-size view for when EmptyView
just doesn't work.Keyboard
- An object representing the keyboard.View/padding(.keyboard)
- Pads this view with the active system height of the keyboard.LinkPresentationView
LinkPresentationView(url: url)
.frame(height: 192)
View/navigationBarColor(_:)
- Configures the color of the navigation bar for this view.View/navigationBarTranslucent(_:)
- Configures the translucency of the navigation bar for this view.View/navigationBarTransparent(_:)
- Configures the transparency of the navigation bar for this view.PaginationView
PaginationView(axis: .horizontal) {
ForEach(0..<10, id: \.hashValue) { index in
Text(String(index))
}
}
.currentPageIndex($...)
.pageIndicatorAlignment(...)
.pageIndicatorTintColor(...)
.currentPageIndicatorTintColor(...)
View/isScrollEnabled(_:)
- Adds a condition that controls whether users can scroll within this view. Works with:
CocoaList
CocoaScrollView
CollectionView
TextView
SearchBar
- A SwiftUI port for UISearchBar
.
struct ContentView: View {
@State var isEditing: Bool = false
@State var searchText: String = ""
var body: some View {
SearchBar("Search...", text: $searchText, isEditing: $isEditing)
.showsCancelButton(isEditing)
.onCancel { print("Canceled!") }
}
}
View/navigationSearchBar(_:)
- Sets the navigation search bar for this view.
Text("Hello, world!")
.navigationSearchBar {
SearchBar("Placeholder", text: $text)
}
View/navigationSearchBarHiddenWhenScrolling(_:)
- Hides the integrated search bar when scrolling any underlying content.
Screen
- A representation of the device's screen.UserInterfaceIdiom
- A SwiftUI port for UIUserInterfaceIdiom
.UserInterfaceOrientation
- A SwiftUI port for UserInterfaceOrientation
.ScrollIndicatorStyle
- A type that specifies the appearance and interaction of all scroll indicators within a view hierarchyHiddenScrollViewIndicatorStyle
- A scroll indicator style that hides all scroll view indicators within a view hierarchy.View/statusItem(id:image:
) - Adds a status bar item configured to present a popover when clicked
Text("Hello, world!")
.statusItem(id: "foo", image: .system(.exclamationmark)) {
Text("Popover!")
.padding()
}
TextView
TextView("placeholder text", text: $text, onEditingChanged: { editing in
print(editing)
})
VisualEffectBlurView
- A blur effect view that expands to fill.
VisualEffectBlurView(blurStyle: .dark)
.edgesIgnoringSafeArea(.all)
View/windowOverlay(isKeyAndVisible:content:)
- Makes a window key and visible when a given condition is true.Contributing
SwiftUIX welcomes contributions in the form of GitHub issues and pull-requests. Please refer the projects section before raising a bug or feature request, as it may already be under progress.
To create an Xcode project for SwiftUIX run bundle install; bundle exec fastlane generate_xcodeproj
. To check the automated builds for SwiftUIX run bundle install; bundle exec fastlane build
.
Support
SwiftUIX is and will always be free and open. Maintaining SwiftUIX, however, is a time-consuming endeavour. If you're reliant on SwiftUIX for your app/project and would like to see it grow, consider contributing/donating as way to help.
Credits
SwiftUIX is a project of @vmanot.
Author: SwiftUIX
Source Code: https://github.com/SwiftUIX/SwiftUIX
License: MIT license
1679035563
When your app is opened, there is a brief time while the native app loads Flutter. By default, during this time, the native app displays a white splash screen. This package automatically generates iOS, Android, and Web-native code for customizing this native splash screen background color and splash image. Supports dark mode, full screen, and platform-specific options.
[BETA] Support for flavors is in beta. Currently only Android and iOS are supported. See instructions below.
You can now keep the splash screen up while your app initializes! No need for a secondary splash screen anymore. Just use the preserve
and remove
methods together to remove the splash screen after your initialization is complete. See details below.
Would you prefer a video tutorial instead? Check out Johannes Milke's tutorial.
First, add flutter_native_splash
as a dependency in your pubspec.yaml file.
dependencies:
flutter_native_splash: ^2.2.19
Don't forget to flutter pub get
.
Customize the following settings and add to your project's pubspec.yaml
file or place in a new file in your root project folder named flutter_native_splash.yaml
.
flutter_native_splash:
# This package generates native code to customize Flutter's default white native splash screen
# with background color and splash image.
# Customize the parameters below, and run the following command in the terminal:
# flutter pub run flutter_native_splash:create
# To restore Flutter's default white splash screen, run the following command in the terminal:
# flutter pub run flutter_native_splash:remove
# color or background_image is the only required parameter. Use color to set the background
# of your splash screen to a solid color. Use background_image to set the background of your
# splash screen to a png image. This is useful for gradients. The image will be stretch to the
# size of the app. Only one parameter can be used, color and background_image cannot both be set.
color: "#42a5f5"
#background_image: "assets/background.png"
# Optional parameters are listed below. To enable a parameter, uncomment the line by removing
# the leading # character.
# The image parameter allows you to specify an image used in the splash screen. It must be a
# png file and should be sized for 4x pixel density.
#image: assets/splash.png
# The branding property allows you to specify an image used as branding in the splash screen.
# It must be a png file. It is supported for Android, iOS and the Web. For Android 12,
# see the Android 12 section below.
#branding: assets/dart.png
# To position the branding image at the bottom of the screen you can use bottom, bottomRight,
# and bottomLeft. The default values is bottom if not specified or specified something else.
#branding_mode: bottom
# The color_dark, background_image_dark, image_dark, branding_dark are parameters that set the background
# and image when the device is in dark mode. If they are not specified, the app will use the
# parameters from above. If the image_dark parameter is specified, color_dark or
# background_image_dark must be specified. color_dark and background_image_dark cannot both be
# set.
#color_dark: "#042a49"
#background_image_dark: "assets/dark-background.png"
#image_dark: assets/splash-invert.png
#branding_dark: assets/dart_dark.png
# Android 12 handles the splash screen differently than previous versions. Please visit
# https://developer.android.com/guide/topics/ui/splash-screen
# Following are Android 12 specific parameter.
android_12:
# The image parameter sets the splash screen icon image. If this parameter is not specified,
# the app's launcher icon will be used instead.
# Please note that the splash screen will be clipped to a circle on the center of the screen.
# App icon with an icon background: This should be 960×960 pixels, and fit within a circle
# 640 pixels in diameter.
# App icon without an icon background: This should be 1152×1152 pixels, and fit within a circle
# 768 pixels in diameter.
#image: assets/android12splash.png
# Splash screen background color.
#color: "#42a5f5"
# App icon background color.
#icon_background_color: "#111111"
# The branding property allows you to specify an image used as branding in the splash screen.
#branding: assets/dart.png
# The image_dark, color_dark, icon_background_color_dark, and branding_dark set values that
# apply when the device is in dark mode. If they are not specified, the app will use the
# parameters from above.
#image_dark: assets/android12splash-invert.png
#color_dark: "#042a49"
#icon_background_color_dark: "#eeeeee"
# The android, ios and web parameters can be used to disable generating a splash screen on a given
# platform.
#android: false
#ios: false
#web: false
# Platform specific images can be specified with the following parameters, which will override
# the respective parameter. You may specify all, selected, or none of these parameters:
#color_android: "#42a5f5"
#color_dark_android: "#042a49"
#color_ios: "#42a5f5"
#color_dark_ios: "#042a49"
#color_web: "#42a5f5"
#color_dark_web: "#042a49"
#image_android: assets/splash-android.png
#image_dark_android: assets/splash-invert-android.png
#image_ios: assets/splash-ios.png
#image_dark_ios: assets/splash-invert-ios.png
#image_web: assets/splash-web.png
#image_dark_web: assets/splash-invert-web.png
#background_image_android: "assets/background-android.png"
#background_image_dark_android: "assets/dark-background-android.png"
#background_image_ios: "assets/background-ios.png"
#background_image_dark_ios: "assets/dark-background-ios.png"
#background_image_web: "assets/background-web.png"
#background_image_dark_web: "assets/dark-background-web.png"
#branding_android: assets/brand-android.png
#branding_dark_android: assets/dart_dark-android.png
#branding_ios: assets/brand-ios.png
#branding_dark_ios: assets/dart_dark-ios.png
# The position of the splash image can be set with android_gravity, ios_content_mode, and
# web_image_mode parameters. All default to center.
#
# android_gravity can be one of the following Android Gravity (see
# https://developer.android.com/reference/android/view/Gravity): bottom, center,
# center_horizontal, center_vertical, clip_horizontal, clip_vertical, end, fill, fill_horizontal,
# fill_vertical, left, right, start, or top.
#android_gravity: center
#
# ios_content_mode can be one of the following iOS UIView.ContentMode (see
# https://developer.apple.com/documentation/uikit/uiview/contentmode): scaleToFill,
# scaleAspectFit, scaleAspectFill, center, top, bottom, left, right, topLeft, topRight,
# bottomLeft, or bottomRight.
#ios_content_mode: center
#
# web_image_mode can be one of the following modes: center, contain, stretch, and cover.
#web_image_mode: center
# The screen orientation can be set in Android with the android_screen_orientation parameter.
# Valid parameters can be found here:
# https://developer.android.com/guide/topics/manifest/activity-element#screen
#android_screen_orientation: sensorLandscape
# To hide the notification bar, use the fullscreen parameter. Has no effect in web since web
# has no notification bar. Defaults to false.
# NOTE: Unlike Android, iOS will not automatically show the notification bar when the app loads.
# To show the notification bar, add the following code to your Flutter app:
# WidgetsFlutterBinding.ensureInitialized();
# SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom, SystemUiOverlay.top]);
#fullscreen: true
# If you have changed the name(s) of your info.plist file(s), you can specify the filename(s)
# with the info_plist_files parameter. Remove only the # characters in the three lines below,
# do not remove any spaces:
#info_plist_files:
# - 'ios/Runner/Info-Debug.plist'
# - 'ios/Runner/Info-Release.plist'
After adding your settings, run the following command in the terminal:
flutter pub run flutter_native_splash:create
When the package finishes running, your splash screen is ready.
To specify the YAML file location just add --path with the command in the terminal:
flutter pub run flutter_native_splash:create --path=path/to/my/file.yaml
By default, the splash screen will be removed when Flutter has drawn the first frame. If you would like the splash screen to remain while your app initializes, you can use the preserve()
and remove()
methods together. Pass the preserve()
method the value returned from WidgetsFlutterBinding.ensureInitialized()
to keep the splash on screen. Later, when your app has initialized, make a call to remove()
to remove the splash screen.
import 'package:flutter_native_splash/flutter_native_splash.dart';
void main() {
WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
runApp(const MyApp());
}
// whenever your initialization is completed, remove the splash screen:
FlutterNativeSplash.remove();
NOTE: If you do not need to use the preserve()
and remove()
methods, you can place the flutter_native_splash
dependency in the dev_dependencies
section of pubspec.yaml
.
If you find this package useful, you can support it for free by giving it a thumbs up at the top of this page. Here's another option to support the package:
Android 12 has a new method of adding splash screens, which consists of a window background, icon, and the icon background. Note that a background image is not supported.
Be aware of the following considerations regarding these elements:
1: image
parameter. By default, the launcher icon is used:
2: icon_background_color
is optional, and is useful if you need more contrast between the icon and the window background.
3: One-third of the foreground is masked.
4: color
the window background consists of a single opaque color.
PLEASE NOTE: The splash screen may not appear when you launch the app from Android Studio on API 31. However, it should appear when you launch by clicking on the launch icon in Android. This seems to be resolved in API 32+.
PLEASE NOTE: There are a number of reports that non-Google launchers do not display the launch image correctly. If the launch image does not display correctly, please try the Google launcher to confirm that this package is working.
PLEASE NOTE: The splash screen does not appear when you launch the app from a notification. Apparently this is the intended behavior on Android 12: core-splashscreen Icon not shown when cold launched from notification.
If you have a project setup that contains multiple flavors or environments, and you created more than one flavor this would be a feature for you.
Instead of maintaining multiple files and copy/pasting images, you can now, using this tool, create different splash screens for different environments.
In order to use the new feature, and generate the desired splash images for you app, a couple of changes are required.
If you want to generate just one flavor and one file you would use either options as described in Step 1. But in order to setup the flavors, you will then be required to move all your setup values to the flutter_native_splash.yaml
file, but with a prefix.
Let's assume for the rest of the setup that you have 3 different flavors, Production
, Acceptance
, Development
.
First this you will need to do is to create a different setup file for all 3 flavors with a suffix like so:
flutter_native_splash-production.yaml
flutter_native_splash-acceptance.yaml
flutter_native_splash-development.yaml
You would setup those 3 files the same way as you would the one, but with different assets depending on which environment you would be generating. For example (Note: these are just examples, you can use whatever setup you need for your project that is already supported by the package):
# flutter_native_splash-development.yaml
flutter_native_splash:
color: "#ffffff"
image: assets/logo-development.png
branding: assets/branding-development.png
color_dark: "#121212"
image_dark: assets/logo-development.png
branding_dark: assets/branding-development.png
android_12:
image: assets/logo-development.png
icon_background_color: "#ffffff"
image_dark: assets/logo-development.png
icon_background_color_dark: "#121212"
web: false
# flutter_native_splash-acceptance.yaml
flutter_native_splash:
color: "#ffffff"
image: assets/logo-acceptance.png
branding: assets/branding-acceptance.png
color_dark: "#121212"
image_dark: assets/logo-acceptance.png
branding_dark: assets/branding-acceptance.png
android_12:
image: assets/logo-acceptance.png
icon_background_color: "#ffffff"
image_dark: assets/logo-acceptance.png
icon_background_color_dark: "#121212"
web: false
# flutter_native_splash-production.yaml
flutter_native_splash:
color: "#ffffff"
image: assets/logo-production.png
branding: assets/branding-production.png
color_dark: "#121212"
image_dark: assets/logo-production.png
branding_dark: assets/branding-production.png
android_12:
image: assets/logo-production.png
icon_background_color: "#ffffff"
image_dark: assets/logo-production.png
icon_background_color_dark: "#121212"
web: false
Great, now comes the fun part running the new command!
The new command is:
# If you have a flavor called production you would do this:
flutter pub run flutter_native_splash:create --flavor production
# For a flavor with a name staging you would provide it's name like so:
flutter pub run flutter_native_splash:create --flavor staging
# And if you have a local version for devs you could do that:
flutter pub run flutter_native_splash:create --flavor development
You're done! No, really, Android doesn't need any additional setup.
Note: If it didn't work, please make sure that your flavors are named the same as your config files, otherwise the setup will not work.
iOS is a bit tricky, so hang tight, it might look scary but most of the steps are just a single click, explained as much as possible to lower the possibility of mistakes.
When you run the new command, you will need to open xCode and follow the steps bellow:
Assumption
schemes
setup; production, acceptance and development.Preparation
{project root}/ios/Runner/Base.lproj
xCode
Xcode still doesn't know how to use them, so we need to specify for all the current flavors (schemes) which file to use and to use that value inside the Info.plist file.
LAUNCH_SCREEN_STORYBOARD
$(LAUNCH_SCREEN_STORYBOARD)
Congrats you finished your setup for multiple flavors,
This message is not related to this package but is related to a change in how Flutter handles splash screens in Flutter 2.5. It is caused by having the following code in your android/app/src/main/AndroidManifest.xml
, which was included by default in previous versions of Flutter:
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/>
The solution is to remove the above code. Note that this will also remove the fade effect between the native splash screen and your app.
Not at this time. PRs are always welcome!
This attribute is only found in Android 12, so if you are getting this error, it means your project is not fully set up for Android 12. Did you update your app's build configuration?
This is caused by an iOS splash caching bug, which can be solved by uninstalling your app, powering off your device, power back on, and then try reinstalling.
removeAfter
method.No. This package creates a splash screen that is displayed before Flutter is loaded. Because of this, when the splash screen loads, internal app settings are not available to the splash screen. Unfortunately, this means that it is impossible to control light/dark settings of the splash from app settings.
Notes
If the splash screen was not updated correctly on iOS or if you experience a white screen before the splash screen, run flutter clean
and recompile your app. If that does not solve the problem, delete your app, power down the device, power up the device, install and launch the app as per this StackOverflow thread.
This package modifies launch_background.xml
and styles.xml
files on Android, LaunchScreen.storyboard
and Info.plist
on iOS, and index.html
on Web. If you have modified these files manually, this plugin may not work properly. Please open an issue if you find any bugs.
mdpi
, hdpi
, xhdpi
, xxhdpi
and xxxhdpi
drawables.<item>
tag containing a <bitmap>
for your splash image drawable will be added in launch_background.xml
colors.xml
and referenced in launch_background.xml
.styles.xml
.drawable-night
, values-night
, etc. resource folders.@3x
and @2x
images.LaunchScreen.storyboard
.Info.plist
.web/splash
folder will be created for splash screen images and CSS files.1x
, 2x
, 3x
, and 4x
sizes and placed in web/splash/img
.web/index.html
, as well as the HTML for the splash pictures.This package was originally created by Henrique Arthur and it is currently maintained by Jon Hanson.
If you encounter any problems feel free to open an issue. If you feel the library is missing a feature, please raise a ticket. Pull request are also welcome.
Run this command:
With Flutter:
$ flutter pub add flutter_native_splash
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
flutter_native_splash: ^2.2.19
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:flutter_native_splash/flutter_native_splash.dart';
import 'package:flutter/material.dart';
import 'package:flutter_native_splash/flutter_native_splash.dart';
void main() {
WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
}
@override
void initState() {
super.initState();
initialization();
}
void initialization() async {
// This is where you can initialize the resources needed by your app while
// the splash screen is displayed. Remove the following example because
// delaying the user experience is a bad design practice!
// ignore_for_file: avoid_print
print('ready in 3...');
await Future.delayed(const Duration(seconds: 1));
print('ready in 2...');
await Future.delayed(const Duration(seconds: 1));
print('ready in 1...');
await Future.delayed(const Duration(seconds: 1));
print('go!');
FlutterNativeSplash.remove();
}
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
// Column is also a layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Invoke "debug painting" (press "p" in the console, choose the
// "Toggle Debug Paint" action from the Flutter Inspector in Android
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
// to see the wireframe for each widget.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
Author: jonbhanson
Download Link: Download The Source Code
Official Website: https://github.com/jonbhanson/flutter_native_splash
License: MIT license
1678973357
В этой статье вы узнаете, как создать генератор градиентного цвета с помощью JavaScript. JavaScript Gradient Color Generator — отличный проект для начинающих. Если вы знаете основы JavaScript , вы легко сможете создать такой проект.
Мы используем линейно-градиентные цвета для различных целей. Однако не всегда удается создать идеальный цвет. Таким образом, этот тип проекта поможет вам создавать красивые градиенты, легко комбинируя разные цвета под разными углами.
С его помощью вы получите все цветовые коды, которые можно добавить непосредственно в файл CSS. Ранее я показывал, как создавать разные типы генераторов случайных цветов . Но здесь вы можете добавить цвет по вашему выбору.
Сначала я сделал блок в верхней части веб-страницы, а затем сделал дисплей. Цвета можно увидеть на его дисплее. Всякий раз, когда вы создаете градиент с использованием двух цветов , этот цвет можно увидеть на дисплее. Затем я сделал коробку, в которой можно найти код цвета.
Затем я создал два поля ввода цвета. Для этого я использовал функцию ввода HTML. Если вы знаете основы HTML, то должны знать, что существуют разные типы ввода. Цвет — это своего рода функция ввода, такая как пароль, электронная почта, текст, файл и т. д. Я создал здесь пространство для ввода двух цветов. Я сделал поле выбора рядом с ним, где есть много углов.
Ниже я поделился пошаговым руководством по созданию генератора цветов с линейным градиентом . Для этого вам нужно иметь представление об основах HTML CSS и JavaScript. HTML CSS помог создать его базовую структуру. JavaScript помог сделать его полностью функциональным.
Когда вы вводите цвет по вашему выбору между двухцветными входными пробелами . Затем цвета можно увидеть на дисплее, соединив их друг с другом. Вы можете выбрать угол по вашему выбору, используя это поле выбора. В зависимости от того, под каким углом два цвета будут соединены друг с другом, чтобы получился градиентный цвет .
Вы можете увидеть код цвета на коробке. Вы можете скопировать этот код и добавить его непосредственно в свой файл CSS.
Надеюсь, приведенная выше демонстрация помогла вам получить предварительный просмотр этого javascript-генератора градиента в реальном времени .
Мы поделились видео с живой демонстрацией, которое поможет вам понять все шаг за шагом. Сначала вы создаете файл HTML и CSS.
Под статьей я дал исходный код, который вы можете скачать напрямую. Но если вы новичок, вы должны следовать пошаговому руководству ниже.
Мы создали базовую структуру для создания генераторов градиентов , используя этот код. Базовая структура представляет собой поле, содержащее всю информацию, такую как ввод цвета, отображение и цветовой код.
<div class=”random-color”>
</div>
html {
height: 100%;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
background-repeat:no-repeat;
}
body {
color: #035aab;
text-align: center;
}
Ширина окна: 350 пикселей и высота: 400 пикселей. Я добавил box-shadow, чтобы улучшить его красоту.
.random-color{
width: 350px;
box-shadow: 0 0 20px rgba(0,139,253,0.25);
margin: 50px auto;
padding: 20px;
height: 400px;
}
Теперь мы создали дисплей, для которого были использованы следующие коды. Дисплей поможет увидеть цвет градиента. Ширина экрана: 350 пикселей и высота: 200 пикселей.
Box-shadow использовался для создания некоторой тени. Здесь используется фоновый цвет, который можно увидеть по умолчанию на этом дисплее.
<div class=”display” id=”gradient”></div>
.display{
width: 350px;
height: 200px;
border: 2px solid white;
box-shadow: 0 0 20px rgba(1,1,1,0.35);
background: linear-gradient(to right, #FFAAAA, #734C8F)
}
Теперь я создал небольшую коробку для просмотра цветового кода. В этом поле вы можете увидеть цветовой код цвета, который вы видите на дисплее. В результате вы можете скопировать эти коды непосредственно в файл CSS.
<div class=”codess”></div>
.codess{
padding: 5px;
margin-top: 30px;
margin-bottom: 30px;
font-family: sans-serif;
letter-spacing: 1px;
box-shadow: 0 0 20px rgba(0,139,253,0.25);
}
Теперь создал пространство для ввода цвета . Как я уже говорил, для ввода доступны различные типы тегов. Я создал здесь пространство для ввода двух цветов. Коробки имеют ширину: 70 пикселей и высоту: 40 пикселей.
<input type=”color” class=”color1″ name=”color1″ value=”#FFAAAA”>
<input type=”color” class=”color2″ name=”color2″ value=”#734C8F”>
.color1,.color2{
width: 70px;
height: 40px;
float: left;
margin: 10px;
margin-top: 20px;
}
Чтобы создать поле выбора, я использовал функцию выбора HTML, а затем добавил 8 опций.
<select name=”toDirection”>
<option value=”to right”>to right</option>
<option value=”to right bottom”>to right bottom</option>
<option value=”to right top”>to right top</option>
<option value=”to left”>to left</option>
<option value=”to left bottom”>to left bottom</option>
<option value=”to left top”>to left top</option>
<option value=”to bottom”>to bottom</option>
<option value=”to top”>to top</option>
</select>
select{
float: right;
margin-top: 25px;
width: 130px;
height: 35px;
}
Я разработал основы для создания генератора цветов градиента выше. Теперь пришло время сделать его полностью работоспособным с помощью JavaScript. Надеюсь, у вас не возникло трудностей с пониманием кодов HTML CSS. Если у вас возникли проблемы, вы можете посмотреть обучающее видео.
Теперь я определил глобальные константы некоторых классов, идентификаторов и функций HTML одну за другой.
var css = document.querySelector(“.codess”)
var color1 = document.querySelector(“.color1”)
var color2 = document.querySelector(“.color2”)
var bodys = document.getElementById(“gradient”)
var linearDirection = document.getElementsByName(“toDirection”)[0]
Используя следующий JavaScript, я организовал его отображение в поле цветового кода. Как вы можете видеть в демо выше. Есть поле, где вы можете увидеть цветовые коды в виде кодов CSS.
Здесь я указал, что цвет, который можно увидеть на дисплее, можно увидеть в поле кода CSS.
Интерфейс метода getPropertyValue() возвращает DOMString, содержащую значение указанного свойства CSS.
Здесь мы сохранили все вычисления в константе с именем «CSSprop». Затем я организовал отображение информации на дисплее с помощью «textContent». Напротив, innerText показывает только «удобочитаемые» элементы. textContent возвращает каждый элемент в узле.
function currentSettings() {
var CSSprop = window.getComputedStyle(bodys,null).getPropertyValue(“background-image”)
css.textContent = CSSprop
}
currentSettings()
Я дал два типа инструкций, используя следующие коды.
➤ Это определит, как цветовые коды будут отображаться в поле кода.
➤ В соответствии с цветовым кодом цвета отображаются на дисплее.
Здесь мы используем «bodys.style.background», который позволяет отображать цвет на дисплее. При этом я добавил формат того, как цветовые коды можно увидеть в коробке.
Здесь мы в основном дали формат линейного градиента, с которым будет добавлено значение степени, цвета 1, цвета 2. В результате, когда значение этого содержимого изменится, изменится цветовой код и изменится цвет дисплея.
function returnColor(){
bodys.style.background =
“linear-gradient(“
+ linearDirection.value
+ “, “
+ color1.value
+ “,”
+ color2.value
+ “)”;
currentSettings()
}
Мы добавили значения ввода в «returnColor», используя следующий трехстрочный код. Чтобы добавить это, использовался «addEventListener». Метод addEventListener() позволяет добавлять прослушиватели событий к любому объекту HTML DOM, например к элементам HTML.
Это изменит значение всех вышеперечисленных вычислений, когда вы измените значение ввода.
document.querySelector(‘select[name=”toDirection”]’).onchange=returnColor;
color1.addEventListener(“input”, returnColor)
color2.addEventListener(“input”, returnColor)
Надеюсь, из этого урока вы узнали, как создать генератор градиентного цвета с помощью HTML CSS JavaScript. Тем временем я создал еще много подобных проектов.
Надеемся, что приведенное выше видео помогло вам узнать, как был создан этот генератор градиентных цветов JavaScript . Вы можете загрузить исходный код, необходимый для создания этого генератора линейных градиентов , нажав кнопку ниже.
Оригинальный источник статьи: https://foolishdeveloper.com/
1678969644
在本文中,您将学习如何使用 JavaScript 创建渐变颜色生成器。JavaScript Gradient Color Generator是一个非常适合初学者的项目。如果您了解基本的 JavaScript,您可以轻松创建这样的项目。
我们出于各种目的使用线性渐变颜色。然而,并非总能创造出完美的色彩。因此,此类项目将通过轻松组合不同角度的不同颜色来帮助您创建漂亮的渐变效果。
有了它,您将获得所有可以直接添加到 CSS 文件中的颜色代码。早些时候我展示了如何制作不同类型的随机颜色生成器。但在这里您可以添加您选择的颜色。
首先,我在网页顶部制作了一个框,然后制作了一个显示。在它的显示屏上可以看到颜色。无论何时使用两种颜色创建渐变,都可以在显示屏中看到该颜色。然后我制作了一个盒子,可以在其中找到颜色代码。
然后我创建了两个颜色输入空间。为此,我使用了 HTML 的输入功能。如果您了解基本的 HTML,那么您一定知道有不同类型的输入。颜色是一种输入功能,如密码、邮箱、文本、文件等,我这里创建了一个空间可以输入两种颜色。我在它旁边做了一个选择框,那里有很多角度。
下面我分享了有关如何创建此线性渐变颜色生成器的分步教程。为此,您需要了解基本的 HTML CSS 和 JavaScript。HTML CSS 帮助创建了它的基本结构。JavaScript 帮助它实现了完整的功能。
当您在双色输入空格 之间输入您选择的颜色时。然后通过将它们相互连接,可以在显示器中看到颜色。您可以使用此选择框选择您选择的角度。两种颜色会按照哪个角度相互连接,形成Gradient Color。
您可以在框中看到颜色代码。您可以复制该代码并将其直接添加到您的 CSS 文件中。
希望上面的演示帮助您实时预览此渐变生成器 javascript。
我们分享了一个带有现场演示的视频,可帮助您逐步了解整个过程。首先,您创建一个 HTML 和 CSS 文件。
文章下方,我给出了源码,大家可以直接下载。但如果您是初学者,则必须按照下面的分步教程进行操作。
我们已经创建了使用此代码创建渐变生成器的基本结构。基本结构是一个盒子,里面包含了颜色输入、显示、颜色代码等所有信息。
<div class=”random-color”>
</div>
html {
height: 100%;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
background-repeat:no-repeat;
}
body {
color: #035aab;
text-align: center;
}
盒子宽度:350px 和高度:400px 已被使用。我添加了 box-shadow 来增强它的美感。
.random-color{
width: 350px;
box-shadow: 0 0 20px rgba(0,139,253,0.25);
margin: 50px auto;
padding: 20px;
height: 400px;
}
现在我们已经创建了一个显示,其中使用了以下代码。显示将有助于查看渐变颜色。显示宽度:350px 和高度:200px。
Box-shadow 已用于创建一定量的阴影。这里使用了背景颜色,默认情况下可以在该显示中看到。
<div class=”display” id=”gradient”></div>
.display{
width: 350px;
height: 200px;
border: 2px solid white;
box-shadow: 0 0 20px rgba(1,1,1,0.35);
background: linear-gradient(to right, #FFAAAA, #734C8F)
}
现在我已经创建了一个小框来查看颜色代码。在该框中,您可以看到在显示屏中看到的颜色的颜色代码。因此,您可以将这些代码直接复制到 CSS 文件中。
<div class=”codess”></div>
.codess{
padding: 5px;
margin-top: 30px;
margin-bottom: 30px;
font-family: sans-serif;
letter-spacing: 1px;
box-shadow: 0 0 20px rgba(0,139,253,0.25);
}
现在已经创建了一个颜色输入空间。正如我之前所说,有不同类型的标签可供输入。我在这里创建了一个空间来输入两种颜色。这些框的宽度为:70px,高度为:40px。
<input type=”color” class=”color1″ name=”color1″ value=”#FFAAAA”>
<input type=”color” class=”color2″ name=”color2″ value=”#734C8F”>
.color1,.color2{
width: 70px;
height: 40px;
float: left;
margin: 10px;
margin-top: 20px;
}
为了创建一个选择框,我使用了 HTML 的选择功能,然后添加了 8 个选项。
<select name=”toDirection”>
<option value=”to right”>to right</option>
<option value=”to right bottom”>to right bottom</option>
<option value=”to right top”>to right top</option>
<option value=”to left”>to left</option>
<option value=”to left bottom”>to left bottom</option>
<option value=”to left top”>to left top</option>
<option value=”to bottom”>to bottom</option>
<option value=”to top”>to top</option>
</select>
select{
float: right;
margin-top: 25px;
width: 130px;
height: 35px;
}
我在上面设计了制作渐变颜色生成器的基础知识。现在是使用 JavaScript 使其完全可操作的时候了。希望您在理解 HTML CSS 代码时没有任何困难。遇到问题可以看视频教程。
现在我已经一一定义了一些类的全局常量、ID、HTML函数。
var css = document.querySelector(“.codess”)
var color1 = document.querySelector(“.color1”)
var color2 = document.querySelector(“.color2”)
var bodys = document.getElementById(“gradient”)
var linearDirection = document.getElementsByName(“toDirection”)[0]
使用以下 JavaScript,我已将其显示在颜色代码框中。正如您在上面的演示中所看到的。有一个框,您可以在其中查看 CSS 代码形式的颜色代码。
这里我已经指出了在显示中可以看到的颜色在CSS代码框中可以看到。
getPropertyValue() 方法接口返回一个包含指定 CSS 属性值的 DOMString。
在这里,我们将所有计算存储在一个名为“CSSprop”的常量中。然后我安排使用“textContent”在显示器中显示信息。相反, innerText 只显示“人类可读”的元素。textContent 返回节点中的每个元素。
function currentSettings() {
var CSSprop = window.getComputedStyle(bodys,null).getPropertyValue(“background-image”)
css.textContent = CSSprop
}
currentSettings()
我使用以下代码给出了两种类型的说明。
➤ 这将决定颜色代码在代码框中的显示方式。
➤ 根据颜色代码,可以在显示屏上看到颜色。
这里我们使用“bodys.style.background”,它设法在显示器中显示颜色。有了这个,我添加了如何在框中看到颜色代码的格式。
这里我们基本上给出了线性渐变的格式,其中将添加度数,颜色1,颜色2的值。结果,当该内容的值改变时,颜色代码将改变并且显示的颜色将改变。
function returnColor(){
bodys.style.background =
“linear-gradient(“
+ linearDirection.value
+ “, “
+ color1.value
+ “,”
+ color2.value
+ “)”;
currentSettings()
}
我们使用以下三行代码将输入值添加到“returnColor”。“addEventListener”已用于添加此内容。addEventListener() 方法允许您在任何 HTML DOM 对象(例如 HTML 元素)上添加事件侦听器。
当您更改输入值时,这将更改上述所有计算的值。
document.querySelector(‘select[name=”toDirection”]’).onchange=returnColor;
color1.addEventListener(“input”, returnColor)
color2.addEventListener(“input”, returnColor)
希望从本教程中,您已经学会了如何使用 HTML CSS JavaScript 创建渐变颜色生成器。与此同时,我创建了更多这样的项目。
希望上面的视频可以帮助您了解这个 JavaScript 渐变颜色生成器是如何创建的。您可以从下面的按钮下载创建此线性渐变生成器所需的源代码。
文章原文出处:https: //foolishdeveloper.com/
1678965792
In this article, you will learn how to create a Gradient Color Generator using JavaScript. JavaScript Gradient Color Generator is a great project for beginners. If you know basic JavaScript, you can easily create such a project.
We use linear-gradient colors for various purposes. However, it is not always possible to create the perfect color. So this type of project will help you to create beautiful gradients by easily combining different colors with different angles.
With it, you will get all the color codes that you can add directly to the CSS file. Earlier I showed how to make different types of random color generators. But here you can add the color of your choice.
First I made a box at the top of the web page then I made a display. Colors can be seen in its display. Whenever you create a gradient using two colors, that color can be seen in the display. Then I made a box in which the color code can be found.
Then I created two color input spaces. For this, I have used the input function of HTML. If you know basic HTML then you must know that there are different types of inputs. Color is a kind of input function like password, email, text, file, etc. I have created a space to input two colors here. I have made a select box next to it where there are many angles.
Below I have shared a step-by-step tutorial on how to create this linear gradient Color Generator. For this, you need to have an idea about basic HTML CSS and JavaScript. HTML CSS has helped to create its basic structure. JavaScript has helped to make it fully functional.
When you input the color of your choice between the two-color input spaces. Then the colors can be seen in the display by connecting them with each other. You can select the angle of your choice using this select box. According to which angle the two colors will be connected to each other to make Gradient Color.
You can see the color code in the box. You can copy that code and add it directly to your CSS file.
Hopefully, the demo above has helped you get a live preview of this gradient generator javascript.
We’ve shared a video with the live demo that will help you understand the whole step-by-step. First, you create an HTML and CSS file.
Below the article, I have given the source code which you can download directly. But if you are a beginner, you must follow the step-by-step tutorial below.
We have created the basic structure for creating Gradient generators using this code. The basic structure is a box that contains all the information such as color input, display, and color code.
<div class=”random-color”>
</div>
html {
height: 100%;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
background-repeat:no-repeat;
}
body {
color: #035aab;
text-align: center;
}
Box width: 350px and height: 400px have been used. I have added box-shadow to enhance its beauty.
.random-color{
width: 350px;
box-shadow: 0 0 20px rgba(0,139,253,0.25);
margin: 50px auto;
padding: 20px;
height: 400px;
}
Now we have created a display for which the following codes have been used. The display will help to see the Gradient Color. Display width: 350px and height: 200px.
Box-shadow has been used to create some amount of shadow. Here a background color is used which can be seen by default in that display.
<div class=”display” id=”gradient”></div>
.display{
width: 350px;
height: 200px;
border: 2px solid white;
box-shadow: 0 0 20px rgba(1,1,1,0.35);
background: linear-gradient(to right, #FFAAAA, #734C8F)
}
Now I have created a small box to view the color code. In that box, you can see the color code of the color you see in the display. As a result, you can copy those codes directly into the CSS file.
<div class=”codess”></div>
.codess{
padding: 5px;
margin-top: 30px;
margin-bottom: 30px;
font-family: sans-serif;
letter-spacing: 1px;
box-shadow: 0 0 20px rgba(0,139,253,0.25);
}
Has now created a space for color input. As I said before, there are different types of tags available for input. I have created a space to input two colors here. The boxes are width: 70px and height: 40px.
<input type=”color” class=”color1″ name=”color1″ value=”#FFAAAA”>
<input type=”color” class=”color2″ name=”color2″ value=”#734C8F”>
.color1,.color2{
width: 70px;
height: 40px;
float: left;
margin: 10px;
margin-top: 20px;
}
To create a select box I used the select function of HTML and then added 8 options.
<select name=”toDirection”>
<option value=”to right”>to right</option>
<option value=”to right bottom”>to right bottom</option>
<option value=”to right top”>to right top</option>
<option value=”to left”>to left</option>
<option value=”to left bottom”>to left bottom</option>
<option value=”to left top”>to left top</option>
<option value=”to bottom”>to bottom</option>
<option value=”to top”>to top</option>
</select>
select{
float: right;
margin-top: 25px;
width: 130px;
height: 35px;
}
I have designed the basics for making Gradient Color Generator above. Now is the time to make it fully operational using JavaScript. Hopefully, you didn’t have any difficulty understanding the HTML CSS codes. If you have problems, you can watch the video tutorial.
Now I have defined the global constants of some classes, IDs, and HTML functions one by one.
var css = document.querySelector(“.codess”)
var color1 = document.querySelector(“.color1”)
var color2 = document.querySelector(“.color2”)
var bodys = document.getElementById(“gradient”)
var linearDirection = document.getElementsByName(“toDirection”)[0]
Using the following JavaScript I have arranged to display it in the color code box. As you can see in the demo above. There is a box where you can see the color codes in the form of CSS codes.
Here I have indicated that the color that can be seen in the display can be seen in the CSS code box.
getPropertyValue () method interface returns a DOMString containing the value of a specified CSS property.
Here we have stored all the calculations in a constant called “CSSprop”. Then I have arranged to display the information in the display using “textContent”. In contrast, innerText only shows “human-readable” elements. textContent returns every element in the node.
function currentSettings() {
var CSSprop = window.getComputedStyle(bodys,null).getPropertyValue(“background-image”)
css.textContent = CSSprop
}
currentSettings()
I have given two types of instructions using the following codes.
➤ This will determine how the color codes appear in the code box.
➤ According to the color code, the colors can be seen in the display.
Here we use “bodys.style.background” which manages to display the color in the display. With this, I have added the format of how the color codes can be seen in the box.
Here we have basically given the format of linear-gradient with which the value of the degree, color 1, color 2 will be added. As a result, when the value of that content is changed, the color code will change and the color of the display will change.
function returnColor(){
bodys.style.background =
“linear-gradient(“
+ linearDirection.value
+ “, “
+ color1.value
+ “,”
+ color2.value
+ “)”;
currentSettings()
}
We have added the values of the input to “returnColor” using the following three-line code. The “addEventListener” has been used to add this. The addEventListener () method allows you to add event listeners on any HTML DOM object such as HTML elements.
This will change the value of all of the above calculations when you change the value of the input.
document.querySelector(‘select[name=”toDirection”]’).onchange=returnColor;
color1.addEventListener(“input”, returnColor)
color2.addEventListener(“input”, returnColor)
Hopefully from this tutorial, you have learned how to create a Gradient Color Generator using HTML CSS JavaScript. In the meantime, I have created many more projects like this.
Hopefully, the video above has helped you to know how this JavaScript Gradient Color Generator was created. You can download the source code required to create this linear gradient generator from the button below.
Original article source at: https://foolishdeveloper.com/
1677171359
color_extract
Color Extract is a Flutter package that allows you to extract and calculate colors from your app's background.
in this demo you can see how you can make your widget behave like a Chameleon 🦎
Add the following to your pubspec.yaml
:
dependencies:
color_extract: ^1.0.0
Then run flutter pub get
.
The ColorExtractor
it's the widget we want to extract the average color from. It's a wrapper for RepaintBoundary so you can use RepaintBoundary
also instead.
ColorExtractor(
boundaryKey: GlobalKey(),
child: Container(
width: 200,
height: 200,
color: Colors.red,
),
);
The ColorAverager
widget calculates the average color of a part of the ColorExtractor
or RepaintBoundary
. It can be used to determine the overall color of a region of ColorExtractor
or RepaintBoundary
, such as the area behind a logo or an image.
ColorAverager(
boundaryKey: GlobalKey(),
child: SizedBox(
width: 50,
height: 50,
),
onChanged: (color) {
// Handle the new average color.
},
);
You can also use the ColorAveragerController
to calculate the average color programmatically.
final controller = ColorAveragerController();
// ... render the widget ...
final avgColor = await controller.calculateAvgColor();
import 'package:flutter/material.dart';
import 'package:color_extract/color_extract.dart';
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
ColorExtractor(
boundaryKey: boundaryKey,
child: Container(
width: 200,
height: 200,
color: Colors.blue,
),
),
ColorAverager(
// boundaryKey should be the same one in the above ColorExtractor boundaryKey
boundaryKey: boundaryKey,
child: const SizedBox(width: 50, height: 50),
onChanged: (color) {
// Do something with the average color.
// color should be = Colors.blue
},
)
],
)
);
}
}
Run this command:
With Flutter:
$ flutter pub add color_extract
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
color_extract: ^1.0.0
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:color_extract/color_extract.dart';
import 'dart:math';
import 'package:color_extract/color_extract.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class PosColor {
Offset offset;
Size size;
Color color;
PosColor({
required this.offset,
required this.size,
required this.color,
});
}
List<PosColor> generatePosColors() {
List<PosColor> posColors = [];
final random = Random();
for (int i = 0; i < 20; i++) {
double width = random.nextDouble() * 200 + 100;
double height = random.nextDouble() * 200 + 100;
double x = random.nextDouble() * 300 + 50;
double y = random.nextDouble() * 800 + 50;
posColors.add(
PosColor(
offset: Offset(x, y),
size: Size(width, height),
color: getRandomColor(),
),
);
}
for (int i = 0; i < 5; i++) {
double size = random.nextDouble() * 100 + 50;
double x = 250 - size / 2;
double y = 400 - size / 2;
posColors.add(
PosColor(
offset: Offset(x, y),
size: Size(size, size),
color: Colors.white,
),
);
}
for (int i = 0; i < 5; i++) {
double size = random.nextDouble() * 100 + 50;
double x = 250 - size / 2;
double y = 550 - size / 2;
posColors.add(
PosColor(
offset: Offset(x, y),
size: Size(size, size),
color: Colors.black,
),
);
}
for (int i = 0; i < 20; i++) {
double width = random.nextDouble() * 200 + 100;
double height = random.nextDouble() * 200 + 100;
double x = random.nextDouble() * 300 + 50;
double y = random.nextDouble() * 800 + 600;
posColors.add(
PosColor(
offset: Offset(x, y),
size: Size(width, height),
color: getRandomColor(),
),
);
}
return posColors;
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final boundaryKey = GlobalKey();
final _scrollController = ScrollController();
final _controller = ColorAveragerController();
final recsInfo = ValueNotifier(generatePosColors());
final draggableInfo = ValueNotifier(
PosColor(
offset: const Offset(30, 30),
color: Colors.blue,
size: const Size(50, 50)),
);
Future<Color> calcAvgColor([bool reverse = false]) async {
var color = (await _controller.calculateAvgColor()) ?? Colors.blue;
if (reverse) color = color.reverse;
return color;
}
bool isReversedColor = false;
@override
void initState() {
_scrollController.addListener(() {
if (_scrollController.hasClients) {
if (_scrollController.position.userScrollDirection !=
ScrollDirection.idle) {
SchedulerBinding.instance.addPostFrameCallback((_) {
_controller.calculateAvgColor();
});
}
}
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
ColorExtractor(
boundaryKey: boundaryKey,
child: SingleChildScrollView(
controller: _scrollController,
child: SizedBox(
height: 2000,
child: Stack(
children: recsInfo.value
.map((posColor) => Positioned(
left: posColor.offset.dx,
top: posColor.offset.dy,
child: Container(
width: posColor.size.width,
height: posColor.size.height,
color: posColor.color,
),
))
.toList()),
),
),
),
ValueListenableBuilder(
valueListenable: draggableInfo,
builder: (_, __, ___) {
return Positioned(
left: draggableInfo.value.offset.dx,
top: draggableInfo.value.offset.dy,
child: Draggable(
feedback: Opacity(
opacity: 0.6,
child: Container(
width: draggableInfo.value.size.width,
height: draggableInfo.value.size.height,
decoration: BoxDecoration(
color: draggableInfo.value.color,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.grey.withOpacity(0.4)),
),
),
),
onDragEnd: (dragDetails) async {
draggableInfo.value = PosColor(
color: await calcAvgColor(isReversedColor),
offset: Offset(
dragDetails.offset.dx,
dragDetails.offset.dy -
MediaQuery.of(context).padding.top,
),
size: draggableInfo.value.size,
);
WidgetsBinding.instance.addPostFrameCallback((_) async {
draggableInfo.value = PosColor(
color: await calcAvgColor(isReversedColor),
offset: Offset(
dragDetails.offset.dx,
dragDetails.offset.dy -
MediaQuery.of(context).padding.top,
),
size: draggableInfo.value.size,
);
});
},
child: ColorAverager(
boundaryKey: boundaryKey,
controller: _controller,
fillerColor: Theme.of(context).scaffoldBackgroundColor,
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
width: draggableInfo.value.size.width,
height: draggableInfo.value.size.height,
decoration: BoxDecoration(
color: draggableInfo.value.color,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.grey.withOpacity(0.4)),
),
),
onChanged: (value) {
//debugPrint('value $value');
final color = value ?? Colors.blue;
draggableInfo.value = PosColor(
color: isReversedColor ? color.reverse : color,
offset: draggableInfo.value.offset,
size: draggableInfo.value.size,
);
},
),
),
);
},
),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: ColoredBox(
color:
Theme.of(context).scaffoldBackgroundColor.withOpacity(0.8),
child: CheckboxListTile(
controlAffinity: ListTileControlAffinity.trailing,
title: const Text('Reverse Color'),
value: isReversedColor,
onChanged: (_) {
setState(() {
isReversedColor = !isReversedColor;
WidgetsBinding.instance.addPostFrameCallback((_) async {
draggableInfo.value = PosColor(
color: await calcAvgColor(isReversedColor),
offset: draggableInfo.value.offset,
size: draggableInfo.value.size,
);
});
});
},
),
))
],
),
);
}
}
Download Details:
Author: itisnajim
Source Code: https://github.com/itisnajim/color_extract
1676993460
Text plays a significant role on our web pages. This is because it helps users learn what the web page is all about and what they can do there.
When you add text to your web pages, this text defaults to a black color. But sometimes you will want to change the text color to be more personalized.
For example, suppose you have a darker color as the background of your website. In that case, you'll want to make the text color a lighter, brighter color to improve your website’s readability and accessibility.
In this article, you will learn how to change the color of your text in HTML. We'll look at various methods, and we'll discuss which method is best.
Before the introduction of HTML5, you'd use <font>
to add text to websites. This tag takes the color
attribute, which accepts the color as a name or hex code value:
<font color="#9900FF"> Welcome to freeCodeCamp. </font>
// Or
<font color="green"> Welcome to freeCodeCamp. </font>
This tag got depreciated when HTML5 was introduced. This makes sense because HTML is a markup language, not a styling language. When dealing with any type of styling, it is best to use CSS, which has the primary function of styling.
This means for you to add color to your web pages, you need to make use of CSS.
In case you are in a rush to see how you can change the color of your text, then here it is:
// Using inline CSS
<h1 style="color: value;"> Welcome to freeCodeCamp! </h1>
// Using internal/external CSS
selector {
color: value;
}
Suppose you are not in a rush. Let's briefly dive right in.
You can use the CSS color property to change the text color. This property accepts color values like Hex codes, RGB, HSL, or color names.
For example, if you want to change the text color to sky blue, you can make use of the name skyblue
, the hex code #87CEEB
, the RGB decimal code rgb(135,206,235)
, or the HSL value hsl(197, 71%, 73%)
.
There are three ways you can change the color of your text with CSS. These are using inline, internal, or external styling.
Inline CSS allows you to apply styles directly to your HTML elements. This means you are putting CSS into an HTML tag directly.
You can use the style attribute, which holds all the styles you wish to apply to this tag.
<p style="...">Welcome to freeCodeCamp!</p>
You will use the CSS color property alongside your preferred color value:
// Color Name Value
<p style="color: skyblue">Welcome to freeCodeCamp!</p>
// Hex Value
<p style="color: #87CEEB">Welcome to freeCodeCamp!</p>
// RGB Value
<p style="color: rgb(135,206,235)">Welcome to freeCodeCamp!</p>
// HSL Value
<p style="color: hsl(197, 71%, 73%)">Welcome to freeCodeCamp!</p>
But inline styling isn't the greatest option if your apps get bigger and more complex. So let's look at what you can do instead.
Another preferred way to change the color of your text is to use either internal or external styling. These two are quite similar since both use a selector.
For internal styling, you do it within your HTML file's <head>
tag. In the <head>
tag, you will add the <style>
tag and place all your CSS stylings there as seen below:
<!DOCTYPE html>
<html>
<head>
<style>
selector {
color: value;
}
</style>
</head>
// ...
</html>
While for external styling, all you have to do is add the CSS styling to your CSS file using the general syntax:
selector {
color: value;
}
The selector can either be your HTML tag or maybe a class
or an ID
. For example:
// HTML
<p> Welcome to freeCodeCamp! </p>
// CSS
p {
color: skyblue;
}
Or you could use a class
:
// HTML
<p class="my-paragraph" > Welcome to freeCodeCamp! </p>
// CSS
.my-paragraph {
color: skyblue;
}
Or you could use an id
:
// HTML
<p id="my-paragraph" > Welcome to freeCodeCamp! </p>
// CSS
#my-paragraph {
color: skyblue;
}
Note: As you have seen earlier, with inline CSS, you can use the color name, Hex code, RGB value, and HSL value with internal or external styling.
In this article, you have learned how to change an HTML element's font/text color using CSS. You also learned how developers did it before the introduction of HTML5 with the <font>
tag and color attributes.
Also, keep in mind that styling your HTML elements with internal or external styling is always preferable to inline styling. This is because it provides more flexibility.
For example, instead of adding similar inline styles to all your <p>
tag elements, you can use a single CSS class
for all of them.
Inline styles are not considered best practices because they result in a lot of repetition - you cannot reuse the styles elsewhere. To learn more, you can read my article on Inline Style in HTML. You can also learn how to change text size in this article and background color in this article.
I hope this tutorial gives you the knowledge to change the color of your HTML text to make it look better.
Have fun coding!
Original article source at: https://www.freecodecamp.org/
1676685180
SakuraKit, is a lightweight and powerful library for application to switching themes or skins, inspired by SwiftTheme and DKNightVersion. Its provides chain and functional programming, that is more readable for your codes.
For Demo take a look at the SakuraDemo_OC, an iOS example project in the workspace. You will need to run pod install
after downloading.
sakura
mean theme
as following. Now, sakura for your Apps.
Installation
There are three ways to use SakuraKit in your project:
Using CocoaPods
Manual
Using Carthage
CocoaPods is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries in your projects.
Podfile
platform :ios, '8.0'
pod 'SakuraKit'
Download repo's zip, and just drag ALL files in the SakuraKit folder to your projects.
Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.
You can install Carthage with Homebrew using the following command:
$ brew update
$ brew install carthage
To integrate SakuraKit into your Xcode project using Carthage, specify it in your Cartfile:
github "tingxins/SakuraKit"
Run carthage to build the frameworks and drag the SakuraKit.framework framework into your Xcode project.
Usage
Here's an example, configure skins for UIButton
as an example following.
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
button.sakura
.backgroundColor(@"Home.buttonBackgroundColor")
.titleColor(@"Home.buttonTitleColor", UIControlStateNormal);
Obviously, as the code show. it's just configure backgroundColor
& titleColor
of skin for a button. If you want to switch theme or skin for your apps. Just call this API use TXSakuraManager
:
// name: name of a theme or skin.
// type: TXSakuraTypeMainBundle or TXSakuraTypeSandBox
+ (BOOL)shiftSakuraWithName:(TXSakuraName *)name type:(TXSakuraType)type;
For lines of code above. You may be puzzled by some literals, such as Home.buttonBackgroundColor
or Home.buttonTitleColor
. Do not worry about, we will focus on how to set up a profile for sakura step by step later.
Now, let's focus on profile. In brief, profile is a simple way to manage theme or skin for your application setting in a project. (Actually, sakura profile is just likes localizing your app.)
SakuraKit supports both .json & .plist format of file. For .json file example. you may should do configure like this:
{
"Home":{
"buttonBackgroundColor":"#BB503D",
"buttonTitleColor":"#4AF2A1"
}
}
as show above, we can know that literals of Home.buttonBackgroundColor
and Home.buttonTitleColor
is just a KeyPath
for dictionary. SakuraKit always fetch value from Profile switching theme or skin for your app, such as color/iconName/text/fontSize.e.g.
Precautions:
Bundle themes are exists in your app bundle. we also called Local Theme. we should always configure a default theme for app. of course, SakuraKit can add multi bundle themes for your app following these steps:
First, create [SakuraName
].json profile. be sure that the SakuraName
is your theme name. For example, if you want to add a new bundle theme which named typewriter
, then the corresponding profile should be named typewriter.json.
Next, configure icons for typewriter
theme. And name of icons need be distinguish with other local theme. For example. If an icon named cm2_btm_icn_account
in default theme, then the corresponding icon in typewriter
theme should be named like this cm2_btm_icn_account_xxx
.
After Step 1 & 2. you may should register all local sakura theme in AppDelegate. (default theme can be ignored.)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Coding ...
[TXSakuraManager registerLocalSakuraWithNames:@[@"typewriter"]];
// Coding ...
return YES;
}
At this point, we have configured all Bundle themes. we can switching to these themes any time now. For example. If you want switching to a specified bundle theme which named typewriter
. Just call API like this:
[TXSakuraManager shiftSakuraWithName:@"typewriter" type:TXSakuraTypeMainBundle];
Sandbox themes, using compressed package(.zip) with a folder, which contains Profile & Icons. And we also called Remote Theme. The user can downloads via the network from server. Server can uploading multi themes dynamic, and then user can downloads from app.
About remote theme data format suggestion, give an example:(FYI)
{
"name": "I'm a monkey",
"sakuraName": "monkey",
"url": "http:\\image.tingxins.cn\sakura\monkey.zip"
}
sakuraName
is your theme name. And url
is a remote url address of sakura theme. (Note: If the sakuraName field passed nil, the name of the corresponding theme will default to the name of downloaded package.)
When the remote theme has been downloaded, we can switching the theme like this:
[TXSakuraManager shiftSakuraWithName:sakuraName type:TXSakuraTypeSandBox];
About some exciting for you. SakuraKit also provides some API that you can used to download the remote theme. And supports both Block
& Delegate
callback. Very awesome, right? And of course, you can also customize your own download operation for remote theme.
Let's talk about it now.
If you want to download a sakura theme. You can call the download task block API like this. Show the code of Use-Case:
[[TXSakuraManager manager] tx_sakuraDownloadWithInfos:sakuraModel downloadProgressHandler:^(int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) {
// Sakura theme download progress callback
} downloadErrorHandler:^(NSError * error) {
// Sakura theme download error callback
} unzipProgressHandler:^(unsigned long long loaded, unsigned long long total) {
// Unzip sakura theme compressed package progress callback
} completedHandler:^(id<TXSakuraDownloadProtocol> infos, NSURL * location) {
// completed callback
} ];
In this example, the object of sakuraModel
conform to TXSakuraDownloadProtocol
. You can check out SakuraDemo_OC for more details in DownloadSakuraController
.
If you want to download a sakura theme. You can call the download task delegate API like this :
[[TXSakuraManager manager] tx_sakuraDownloadWithInfos:sakuraModel delegate:self];
Implement delegate methods that you need to.
// If download task of sakura theme is already exist or already exist in sandbox, this API will callback.
- (void)sakuraManagerDownload:(TXSakuraManager *)manager
downloadTask:(NSURLSessionDownloadTask *)downloadTask
status:(TXSakuraDownloadTaskStatus)status;
// completed callback
- (void)sakuraManagerDownload:(TXSakuraManager *)manager
downloadTask:(NSURLSessionDownloadTask *)downloadTask
sakuraInfos:(id<TXSakuraDownloadProtocol>)infos
didFinishDownloadingToURL:(NSURL *)location;
// Sakura download progress callback
- (void)sakuraManagerDownload:(TXSakuraManager *)manager
downloadTask:(NSURLSessionDownloadTask *)downloadTask
didWriteData:(int64_t)bytesWritten
totalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite;
/** Reserved for future use */
- (void)sakuraManagerDownload:(TXSakuraManager *)manager
downloadTask:(NSURLSessionDownloadTask *)downloadTask
didResumeAtOffset:(int64_t)fileOffset
expectedTotalBytes:(int64_t)expectedTotalBytes;
// Sakura theme download error callback
- (void)sakuraManagerDownload:(TXSakuraManager *)manager
sessionTask:(NSURLSessionTask *)downloadTask
didCompleteWithError:(nullable NSError *)error;
// Unzip sakura theme compressed package progress callback
- (void)sakuraManagerDownload:(TXSakuraManager *)manager
downloadTask:(NSURLSessionDownloadTask *)downloadTask
progressEvent:(unsigned long long)loaded
total:(unsigned long long)total;
You can check out SakuraDemo_OC for more details in AppDelegate
.
If you do not want use API to download the remote theme that SakuraKit provided, you can customize your own download operation for sakura theme.
Show the code that you want:
// `sakuraModel` conform to `TXSakuraDownloadProtocol`. location is theme compressed package path that downloaded。
[[TXSakuraManager manager] tx_generatePathWithInfos:sakuraModel downloadFileLocalURL:location successHandler:^(NSString *toFilePath, NSString *sakuraPath, TXSakuraName *sakuraName) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
BOOL isSuccess = [SSZipArchive unzipFileAtPath:toFilePath toDestination:sakuraPath delegate:self];
// Note: Be sure that call this API to format theme path if you are customize your own download operation. otherwise, when switching theme you may be failed.
[TXSakuraManager formatSakuraPath:sakuraPath cleanCachePath:toFilePath];
dispatch_sync(dispatch_get_main_queue(), ^{
if (isSuccess) {
[TXSakuraManager shiftSakuraWithName:sakuraName type:TXSakuraTypeSandBox];
}
});
});
} errorHandler:^(NSError * _Nullable error) {
NSLog(@"errorDescription:%@",error);
}];
FQA
Q: Why do each theme has its own profile?
A: Because each theme, beside the name of icons are the same, and different themes background color, font size may not be the same. So each theme should have its own profile, unless you just want to making theme only for icons.
Q: Why is the sakura name should be consistent with the profile name of corresponding theme?
A: This is only a convention for us. when switching theme, SakuraKit will through the theme name to find the theme in the local or in the sandbox path, making both theme and profile name the same, you will reduce some unnecessary workload.
Q: What is the difference between bundle and sandbox themes?
A: Actually. Bundle theme, we called the local theme. Remote theme also called sandbox theme.
Q: Do SakuraKit have a version that written in Swift?
A: No. Will Coming soon. If you are really need it now. Here's an example for Using Swift with SakuraKitOC. (SakuraKitOCForSwiftDemo)
Communication
Absolutely,you can contribute to this project all the time if you want to.
If you need help or ask general question, just @tingxins in Weibo or Twitter, of course, you can access to my blog.
If you found a bug, just open an issue.
If you have a feature request, just open an issue.
If you want to contribute, fork this repository, and then submit a pull request.
Author: Tingxins
Source Code: https://github.com/tingxins/SakuraKit
License: MIT license
1675112040
The familiar color picker supercharged
The macOS color picker as an app with lots of extra features.
#
.You can use the following keyboard shortcuts in the app:
The built-in color picker supports plugins:
macOS hides menu bar apps when there is no space left in the menu bar. This is a common problem on MacBooks with a notch. Try quitting some menu bar apps to free up space. If this does not solve it, try quitting Bartender if you have it installed.
It's a more human-friendly color format.
Note that the LCH color is currently clamped to sRGB range.
That is because the default color space in the picker is Display P3, which is part of CSS Color 4, but the color space used for the legacy CSS color formats is sRGB (browsers are starting to handle color spaces but they are not all there yet).
Right-click the color wheel. You probably want to select “sRGB”.
Note that the color strings will always be converted to sRGB color space.
SwiftUI.Color
/ UIColor
/ NSColor
formats?The best practice is to use Asset Catalog for colors instead of hard-coding the values in code. If you really want to hard-code colors, the Scala color picker plugin supports UIColor
and NSColor
.
I don't have any immediate plans to localize the app.
Requires macOS 12 or later.
Older versions
Author: Sindresorhus
Source Code: https://github.com/sindresorhus/System-Color-Picker
License: MIT license
1673952060
platform :ios, '10.0'
pod "Colorful", "~> 3.0"
$ pod install
let colorPicker = ColorPicker(frame: ...)
colorPicker.addTarget(self, action: #selector(...), for: .valueChanged)
colorPicker.set(color: .red, colorSpace: .extendedSRGB)
view.addSubview(colorPicker)
You can receive .valueChanged
event when user changes color.
ColorSpace | Description |
---|---|
.extendedSRGB | The extended sRGB is color space for support wider and deeper representation of color. |
.sRGB | sRGB (standard Red Green Blue) is often the "default" color space for images that contain no color space information |
iOS11 ~
Author: Hayashi311
Source Code: https://github.com/hayashi311/Color-Picker-for-iOS
License: View license
1673000520
"A collection of functional programming libraries that can be composed together. Unlike a framework, thi.ng is a suite of instruments and you (the user) must be the composer of. Geared towards versatility, not any specific type of music." — @loganpowell via Twitter
Please visit thi.ng for additional information & topic based search of packages relevant to your use cases...
This mono-repository is home to 176 individual TypeScript/ES6 projects (plus 119 example projects), a wide and jointly developed collection of packages, tools and general building blocks for (non-exhaustive list of topics, see package overview below):
This project is NOT a framework, provides no turn-key, one-size-fits-all approach and instead encourages a mix & match philosophy for various key aspects of application design (in & outside the browser). Most customization points only expect certain interfaces/type signatures rather than concrete implementations.
All packages:
api.ts
The sheer number and varied nature & purpose of these packages makes it impossible to provide traditional "Getting started" tutorials. To compensate, this repo provides a large number of example projects, detailed readmes (at the very least for all the larger and/or more important packages) and smaller usage examples in the docstrings.
There's a steadily growing number (~120) of standalone examples of different complexities (often combining functionality from several packages) in the examples directory.
Due to other priorities still very much in its infancy & planning stage, but please help to document your own usage of these packages by contributing project information to the awesome.thi.ng repo, which will be used to build a showcase site... Thank you!
Several generative art projects by Karsten Schmidt on fx(hash) have been created exclusively with libraries from this collection.
"Of umbrellas, transducers, reactive streams & mushrooms" (ongoing series):
Join our little community on our Discord server or get in touch via Twitter or the issue tracker. If you'd like to contribute, please first read this document.
In general, we welcome contributions of all kinds (docs, examples, bug fixes, feature requests, financial contributions etc.). You can find a fairly detailed overview for contributors here: CONTRIBUTING.md.
Note: The default branch for this repo is develop
and all PRs should be created based on this branch. This too means, the README files on this branch might refer to yet-unreleased features or packages. Please use the main branch for viewing the most recently released version(s)!.
Also please be sure to check the wiki for other project-wide information, tidbits, useful snippets etc.
As of: 2022-12-29
Status | Project | Version | Changelog |
---|---|---|---|
@thi.ngarrays | changelog | ||
@thi.ng/date | changelog | ||
@thi.ng/geom-axidraw | changelog | ||
@thi.ng/geom-trace-bitmap | changelog | ||
@thi.ng/wasm-api-canvas | changelog |
Project | Version | Changelog | Description |
---|---|---|---|
@thi.ng/args | changelog | Declarative & functional CLI arg parsing & coercions | |
@thi.ng/api | changelog | Common types, decorators, mixins | |
@thi.ng/bench | changelog | Basic benchmarking helpers | |
@thi.ng/checks | changelog | Type & value checks | |
@thi.ng/compare | changelog | Comparators | |
@thi.ng/compose | changelog | Functional composition helpers | |
@thi.ng/date | changelog | Date/time iterators, formatters, rounding | |
@thi.ng/defmulti | changelog | Dynamic multiple dispatch | |
@thi.ng/distance | changelog | n-D distance metrics & K-nearest neighborhoods | |
@thi.ng/equiv | changelog | Deep value equivalence checking | |
@thi.ng/errors | changelog | Custom error types | |
@thi.ng/expose | changelog | Conditional global variable exposition | |
@thi.ng/hex | changelog | Hex value formatters for U4-64 words | |
@thi.ng/logger | changelog | Basis infrastructure for arbitrary logging | |
@thi.ng/memoize | changelog | Function memoization w/ customizable caching | |
@thi.ng/oquery | changelog | Pattern based query engine for JS objects | |
@thi.ng/parse | changelog | Parser combinators & AST generator/transformer | |
@thi.ng/paths | changelog | Immutable nested object accessors | |
@thi.ng/strings | changelog | Higher-order string formatting utils | |
@thi.ng/system | changelog | Minimal life cycle container for stateful app components | |
@thi.ng/testament | changelog | Minimal test runner | |
@thi.ng/transclude | changelog | Template engine for text document generation |
Project | Version | Changelog | Description |
---|---|---|---|
@thi.ng/dual-algebra | changelog | Dual number algebra / automatic differentiation | |
@thi.ng/dsp | changelog | DSP utils, composable signal gens/processors | |
@thi.ng/fuzzy | changelog | Fuzzy logic primitives & rule inference engine | |
@thi.ng/intervals | changelog | Open/closed intervals, queries, set ops | |
@thi.ng/math | changelog | Assorted common math functions & utilities | |
@thi.ng/matrices | changelog | Matrix operations | |
@thi.ng/sparse | changelog | Sparse matrix & vector impls | |
@thi.ng/vectors | changelog | Fixed & arbitrary-length vector ops |
Project | Version | Changelog | Description |
---|---|---|---|
@thi.ng/colored-noise | changelog | 1D colored noise generators | |
@thi.ng/ksuid | changelog | K-sortable unique identifiers, binary & base-N encoded | |
@thi.ng/lowdisc | changelog | n-D Low discrepancy sequence generators | |
@thi.ng/random | changelog | Seedable PRNG implementations, distributions & utilities | |
@thi.ng/random-fxhash | changelog | PRNG impl & utilities for fxhash projects |
Project | Version | Changelog | Description |
---|---|---|---|
@thi.ng/axidraw | changelog | Minimal, declarative AxiDraw plotter controller | |
@thi.ng/bencode | changelog | Bencode binary format encoding | |
@thi.ng/csv | changelog | Customizable CSV parser/object mapper | |
@thi.ng/dot | changelog | Graphviz DOM & export | |
@thi.ng/dsp-io-wav | changelog | WAV file format exporter | |
@thi.ng/file-io | changelog | Assorted file I/O utils for NodeJS | |
@thi.ng/geom-io-obj | changelog | Wavefront OBJ model parser | |
@thi.ng/hiccup-css | changelog | CSS from nested JS data structures | |
@thi.ng/hiccup-html | changelog | Type-checked HTML5 element wrappers for hiccup | |
@thi.ng/hiccup-markdown | changelog | Hiccup-to-Markdown serialization | |
@thi.ng/hiccup-svg | changelog | hiccup based SVG vocab | |
@thi.ng/iges | changelog | IGES format geometry serialization | |
@thi.ng/markdown-table | changelog | Markdown table generator / formatter | |
@thi.ng/mime | changelog | File extension to MIME type mappings | |
@thi.ng/pixel-io-netpbm | changelog | 1/8/16/24bit NetPBM image format reader/writer | |
@thi.ng/prefixes | changelog | Linked Data, RDF & xmlns prefixes/URLs | |
@thi.ng/sax | changelog | SAX-like XML parser / transducer | |
@thi.ng/tangle | changelog | Literate programming utilities |
Project | Version | Changelog | Description |
---|---|---|---|
@thi.ng/csp | changelog | Channel based async ops | |
@thi.ng/fsm | changelog | FSM / parser primitives | |
@thi.ng/grid-iterators | changelog | 2D grid iterator strategies | |
@thi.ng/iterators | changelog | ES6 generators / iterators | |
@thi.ng/seq | changelog | Lisp/Clojure-style sequence abstraction | |
@thi.ng/transducers | changelog | Composable data transformations | |
@thi.ng/transducers-binary | changelog | Binary data related transducers | |
@thi.ng/transducers-fsm | changelog | Finite state transducer | |
@thi.ng/transducers-hdom | changelog | Transducer based hdom UI updates | |
@thi.ng/transducers-patch | changelog | Patch-based, array & object editing | |
@thi.ng/transducers-stats | changelog | Technical / statistical analysis |
Project | Version | Changelog | Description |
---|---|---|---|
@thi.ng/rstream | changelog | Push-based, reactive event stream primitves | |
@thi.ng/rstream-csp | changelog | Adapter bridge CSP -> rstream | |
@thi.ng/rstream-dot | changelog | Graphviz visualization of rstream topologies | |
@thi.ng/rstream-gestures | changelog | Mouse & touch event stream abstraction | |
@thi.ng/rstream-graph | changelog | Declarative dataflow graph construction | |
@thi.ng/rstream-log | changelog | Hierarchical structured data logging | |
@thi.ng/rstream-log-file | changelog | Log-file output handler | |
@thi.ng/rstream-query | changelog | Triple store & query engine |
Project | Version | Changelog | Description |
---|---|---|---|
@thi.ng/adjacency | changelog | Adjacency matrices & graph algorithms | |
@thi.ng/arrays | changelog | Array utilities | |
@thi.ng/associative | changelog | Alt Set & Map implementations | |
@thi.ng/atom | changelog | Immutable value wrappers, views, history | |
@thi.ng/bitfield | changelog | 1D/2D bit field implementations | |
@thi.ng/cache | changelog | In-memory caches / strategies | |
@thi.ng/cellular | changelog | Highly configurable 1D Cellular automata | |
@thi.ng/dcons | changelog | Doubly-linked list | |
@thi.ng/diff | changelog | Array & object diffing | |
@thi.ng/dgraph | changelog | Dependency graph | |
@thi.ng/ecs | changelog | Entity-Component System | |
@thi.ng/egf | changelog | Extensible Graph Format | |
@thi.ng/gp | changelog | Genetic programming helpers / AST gen | |
@thi.ng/heaps | changelog | Binary & d-ary heap impls | |
@thi.ng/idgen | changelog | Versioned ID generation / free-list | |
@thi.ng/k-means | changelog | K-means clustering of n-D data | |
@thi.ng/ramp | changelog | Parametric, interpolated lookup tables | |
@thi.ng/quad-edge | changelog | Quad-edge, dual-graph data structure | |
@thi.ng/resolve-map | changelog | DAG computations & value resolution | |
@thi.ng/vclock | changelog | Vector clock functions / comparators | |
@thi.ng/zipper | changelog | Immutable tree editing / navigation |
Project | Version | Changelog | Description |
---|---|---|---|
@thi.ng/adapt-dpi | changelog | HDPI canvas adaptation / styling util | |
@thi.ng/dl-asset | changelog | Asset/canvas/file download helpers | |
@thi.ng/hdiff | changelog | String diffing w/ hiccup output (includes CLI) | |
@thi.ng/hdom | changelog | Hiccup based VDOM & diffing | |
@thi.ng/hdom-canvas | changelog | hdom adapter for hiccup-canvas | |
@thi.ng/hdom-components | changelog | hdom based UI components | |
@thi.ng/hdom-mock | changelog | hdom mock implementation (testing / prototyping) | |
@thi.ng/hiccup | changelog | S-expression based HTML/XML serialization | |
@thi.ng/hiccup-canvas | changelog | hiccup interpreter for canvas api | |
@thi.ng/hiccup-carbon-icons | changelog | IBM Carbon icons in hiccup format | |
@thi.ng/imgui | changelog | Immediate mode GUI | |
@thi.ng/interceptors | changelog | Composable event handlers & processor | |
@thi.ng/rdom | changelog | Reactive, diff-less, async UI components | |
@thi.ng/rdom-canvas | changelog | rdom component wrapper for thi.ng/hiccup-canvas | |
@thi.ng/rdom-components | changelog | Unstyled, customizable component collection | |
@thi.ng/router | changelog | Customizable browser & non-browser router | |
@thi.ng/text-canvas | changelog | Text-mode canvas, drawing, tables, charts | |
@thi.ng/text-format | changelog | Color text formatting w/ ANSI & HTML presets |
Project | Version | Changelog | Description |
---|---|---|---|
@thi.ng/color | changelog | Color conversions, gradients | |
@thi.ng/color-palettes | changelog | Collection of image-based color palettes | |
@thi.ng/dgraph-dot | changelog | Dependency graph -> Graphviz | |
@thi.ng/distance-transform | changelog | Image based distance field generation | |
@thi.ng/fuzzy-viz | changelog | Visualization, instrumentation for @thi.ng/fuzzy | |
@thi.ng/geom | changelog | 2D only geometry types & ops | |
@thi.ng/geom-accel | changelog | Spatial indexing data structures | |
@thi.ng/geom-api | changelog | Shared types & interfaces | |
@thi.ng/geom-axidraw | changelog | Shape conversions for AxiDraw pen plotter | |
@thi.ng/geom-arc | changelog | 2D elliptic arc utils | |
@thi.ng/geom-clip-line | changelog | 2D line clipping | |
@thi.ng/geom-clip-poly | changelog | 2D convex polygon clipping | |
@thi.ng/geom-closest-point | changelog | Closest point helpers | |
@thi.ng/geom-fuzz | changelog | Fuzzy 2D shape drawing / filling | |
@thi.ng/geom-hull | changelog | 2D convex hull (Graham scan) | |
@thi.ng/geom-isec | changelog | Point & shape intersection tests | |
@thi.ng/geom-isoline | changelog | 2D contour line extraction | |
@thi.ng/geom-poly-utils | changelog | 2D polygon helpers | |
@thi.ng/geom-resample | changelog | nD polyline / curve resampling | |
@thi.ng/geom-sdf | changelog | 2D SDF creation, conversions, operators, utilities | |
@thi.ng/geom-splines | changelog | nD cubic / quadratic spline ops | |
@thi.ng/geom-subdiv-curve | changelog | nD iterative subdivision curves | |
@thi.ng/geom-tessellate | changelog | nD convex polygon tessellators | |
@thi.ng/geom-trace-bitmap | changelog | bitmap image to vector conversion | |
@thi.ng/geom-voronoi | changelog | 2D iterative delaunay/voronoi | |
@thi.ng/lsys | changelog | Extensible L-System architecture | |
@thi.ng/pixel | changelog | Multi-format pixel buffers | |
@thi.ng/pixel-dither | changelog | Image dithering w/ various algorithm presets | |
@thi.ng/poisson | changelog | nD Poisson disk sampling | |
@thi.ng/porter-duff | changelog | Alpha blending / compositing ops | |
@thi.ng/rasterize | changelog | Shape drawing, filling & rasterization | |
@thi.ng/scenegraph | changelog | Extensible 2D/3D scenegraph | |
@thi.ng/simd | changelog | WebAssembly SIMD vector batch processing | |
@thi.ng/viz | changelog | Declarative & functional data visualization toolkit |
Project | Version | Changelog | Description |
---|---|---|---|
@thi.ng/shader-ast | changelog | AST DSL for x-platform shader code | |
@thi.ng/shader-ast-glsl | changelog | GLSL code generator | |
@thi.ng/shader-ast-js | changelog | JS code generator | |
@thi.ng/shader-ast-optimize | changelog | AST code optimization strategies | |
@thi.ng/shader-ast-stdlib | changelog | 100+ useful AST shader functions | |
@thi.ng/webgl | changelog | WebGL 1/2 / GPGPU facilities | |
@thi.ng/webgl-msdf | changelog | MSDF font rendering | |
@thi.ng/webgl-shadertoy | changelog | Shadertoy-like WebGL setup |
Project | Version | Changelog | Description |
---|---|---|---|
@thi.ng/base-n | changelog | Arbitrary base-n encoding/decoding with presets | |
@thi.ng/binary | changelog | Assorted binary / bitwise ops, utilities | |
@thi.ng/bitstream | changelog | Bitwise input / output streams | |
@thi.ng/dlogic | changelog | Digital logic ops / constructs | |
@thi.ng/leb128 | changelog | WASM based LEB128 varint encoder / decoder | |
@thi.ng/malloc | changelog | Raw & typed array memory pool & allocator | |
@thi.ng/morton | changelog | Z-order-curve / Morton coding | |
@thi.ng/range-coder | changelog | Binary data Range encoder / decoder | |
@thi.ng/rle-pack | changelog | Run-length encoding data compression | |
@thi.ng/soa | changelog | Memory mapped data structures & serialization | |
@thi.ng/unionstruct | changelog | Wrapper for C-like structs / unions | |
@thi.ng/vector-pools | changelog | Data structures for memory mapped vectors | |
@thi.ng/wasm-api | changelog | Modular, extensible JS/WebAssembly bridge API | |
@thi.ng/wasm-api-bindgen | changelog | Polyglot bindings code generator for C/Zig/TS | |
@thi.ng/wasm-api-canvas | changelog | WASM-side Canvas2D API bindings | |
@thi.ng/wasm-api-dom | changelog | WASM-side DOM manipulation | |
@thi.ng/wasm-api-schedule | changelog | WASM-side delayed code execution/scheduling |
Project | Version | Changelog | Description |
---|---|---|---|
@thi.ng/pointfree | changelog | Stack-based DSL & functional composition | |
@thi.ng/pointfree-lang | changelog | Forth-like syntax layer for @thi.ng/pointfree | |
@thi.ng/sexpr | changelog | S-Expression parser & runtime infrastructure |
git clone https://github.com/thi-ng/umbrella.git
cd umbrella
yarn install
yarn build
Once the entire mono-repo has been fully built at least once before, individual packages can then be (re)built like so:
yarn workspace @thi.ng/transducers run build
# or
(cd packages/transducers && yarn build)
Please see the example build instructions in the wiki for further details.
(Most, but not all packages have tests)
Due to various build/config issues/complexities, we're now using our own minimal test runner @thi.ng/testament
yarn test
# or individually
yarn workspace @thi.ng/rstream run test
Autogenerated documentation (using TypeDoc) will be saved under /packages/*/doc/
and is also available at docs.thi.ng.
yarn doc
Furthermore, an experimental tsdoc-based documentation repo provides an alternative markdown output including cross-references between all packages, but currently isn't frequently updated (only every few months):
https://github.com/thi-ng/umbrella-docs-temp
Maintaining a large monorepo like this requires a lot of infrastructure and I'm grateful for the tooling provided by the following projects to simplify those tasks:
Author: thi-ng
Source Code: https://github.com/thi-ng/umbrella
License: Apache-2.0 license
1672390394
Swiftline is a set of tools to help you create command line applications. Swiftline is inspired by highline
Swiftline contains the following:
Usage Installation Examples Docs Tests
Colorize helps styling the strings before printing them to the terminal. You can change the text color, the text background and the text style. Colorize works by extending String
struct to add styling to it.
To change the text color, use either string.f
or string.foreground
:
print("Red String".f.Red)
print("Blue String".foreground.Blue)
To change the text background color, use either string.b
or string.background
:
print("I have a white background".b.White)
print("My background color is green".background.Green)
To change the text background style, use either string.s
or string.style
:
print("I am a bold string".s.Bold)
print("I have an underline".style.Underline)
You can compose foreground, background, and style:
print("I am an underlined red on white string".s.Underline.f.Red.b.White)
Ask, Choose and Agree are used to prompt the user for more information.
Ask presents the user with a prompt and waits for the user input.
let userName = ask("Enter user name?")
userName
will contain the name entered by the user
Ask can be used to ask for value of Int, Double or Float types, to ask for an integer for example:
let age = ask("How old are you?", type: Int.self)
If the user prints something thats not convertible to integer, a new prompt is displayed to him, this prompt will keep displaying until the user enters an Int:
How old are you?
None
You must enter a valid Integer.
? Error
You must enter a valid Integer.
? 5
5
Validations are added by calling addInvalidCase
on AskSettings
.
let name = ask("Who are you?") { settings in
settings.addInvalidCase("Snuffles is not allowed") { value in
value.containsString("Snuffles")
}
}
If the user entered Snuffles
ask will keep displaying the invalid message passed to addInvalidCase
Who are you?
Snuffles
Snuffles is not allowed
? Snuffles
Snuffles is not allowed
? Snowball
Your name is Snowball
AskSettings.confirm
will ask the user to confirm his choice after entering it
let name = ask("Who are you?") { settings in
settings.confirm = true
}
The above will output:
Who are you?
Snuffles
Are you sure? YES
Your name is Snuffles
Choose is used to prompt the user to select an item between several possible items.
To display a choice of programming lanaugage for example:
let choice = choose("Whats your favorite programming language? ",
choices: "Swift", "Objective C", "Ruby", "Python", "Java :S")
This will print:
1. Swift
2. Objective C
3. Ruby
4. Python
5. Java :S
Whats your favorite programming language?
The user can either choose the numbers (1..5) or the item itself. If the user enters a wrong input. A prompt will keep showing until the user makes a correct choice
Whats your favorite programming language? JavaScript
You must choose one of [1, 2, 3, 4, 5, Swift, Objective C, Ruby, Python, Java :S].
? BBB
You must choose one of [1, 2, 3, 4, 5, Swift, Objective C, Ruby, Python, Java :S].
? Swift
You selected Swift, good choice!
You can customize the return value for each choice element. For example if you want to get an Int from the choice, you would do this
let choice = choose("Whats your favorite programming language? ", type: Int.self) { settings in
settings.addChoice("Swift") { 42 }
settings.addChoice("Objective C") { 20 }
}
The number on the left can be changed to letters, here is how you could do that:
let choice = choose("Whats your favorite programming language? ", type: String.self) { settings in
//choice value will be set to GOOD
settings.addChoice("Swift") { "GOOD" }
//choice value will be set to BAD
settings.addChoice("Java") { "BAD" }
settings.index = .Letters
settings.indexSuffix = " ----> "
}
That will print:
a ----> Swift
b ----> Java
Whats your favorite programming language?
Agree is used to ask a user for a Yes/No question. It returns a boolean representing the user input.
let choice = agree("Are you sure you want to `rm -rf /` ?")
If the user enters any invalid input, agree will keep prompting him for a Yes/No question
Are you sure you want to `rm -rf /` ? What!
Please enter "yes" or "no".
Are you sure you want to `rm -rf /` ? Wait
Please enter "yes" or "no".
Are you sure you want to `rm -rf /` ? No
You entered false
Run provides a quick, concise way to run an external command and read its standard output and standard error.
To execute a simple command you would do:
let result = run("ls -all")
print(result.stdout)
result
type is RunResults
, it contains:
exitStatus
: The command exit statusstdout
: The standard output for the command executedstderr
: The standard error for the command executedWhile run("command")
can split the arguments by spaces. Some times argument splitting is not trivial. If you have multiple argument to pass to the command to execute, you should use run(command: String, args: String...)
. The above translates to:
let result = run("ls", args: "-all")
To customize the run function, you can pass in a customization block:
let result = run("ls -all") { settings in
settings.dryRun = true
settings.echo = [.Stdout, .Stderr, .Command]
settings.interactive = false
}
settings
is an instance of RunSettings, which contains the following variables:
settings.dryRun
: defaults to false. If false, the command is actually run. If true, the command is logged to the stdout paramter of resultsettings.echo
: Customize the message printed to stdout, echo
can contain any of the following:EchoSettings.Stdout
: The stdout returned from running the command will be printed to the terminalEchoSettings.Stderr
: The stderr returned from running the command will be printed to the terminalEchoSettings.Command
: The command executed will be printed to the terminalsettings.interactive
: defaults to false. If set to true the command will be executed using system
kernel function and only the exit status will be captured. If set to false, the command will be executed using NSTask
and both stdout and stderr will be captured. Set interactive
to true if you expect the launched command to ask input from the user through the stdin.runWithoutCapture("command")
is a quick way to run a command in interactive mode. The return value is the exit code of that command.
Env is used to read and write the environment variables passed to the script
// Set enviroment variable
Env.set("key1", "value1")
// Get environment variable
Env.get("SomeKey")
// Clear all variables
Env.clear()
// Get all keys and values
Env.keys()
Env.values()
Returns the arguments passed to the script. For example when calling script -f1 val1 -f2 val2 -- val3 val4
Args.all
returns an array of all the raw arguments, in this example it will be ["-f1", "val1", "-f2", "val2", "--", "val3", "val4"
Args.parsed
returns a structure that contains a parsed map of arguments and an array of arguments, for this example:
Args.parsed.parameters
returns ["val3", "val4"]
Args.parsed.flags
returns a dictinary of flags ["f1": "val1", "f2", "val2"]
Args.parsed.command
returns the name of the executable itself "script"
You can install Swiftline using CocoaPods, carthage and Swift package manager
use_frameworks!
pod 'Swiftline'
github 'swiftline/swiftline'
Add swiftline as dependency in your Package.swift
import PackageDescription
let package = Package(name: "YourPackage",
dependencies: [
.Package(url: "https://github.com/Swiftline/Swiftline.git", majorVersion: 0, minor: 3),
]
)
If you want to use swiftline in a script you can use Rome CocoaPods plugin. This plugin builds the framework from the pod file and place them in a Rome directory.
platform :osx, '10.10'
plugin 'cocoapods-rome'
pod 'Swiftline'
To install Swiftline manually, add Pod/Swiftline
directory to your project.
A list of examples can be found here
Tests can be found here. They can be normally run from the Xcode .
Documentation can be found here
interactive
Daniel Beere for creating the logo @DanielBeere check out danielbeere on dribble Omar Abdelhafith current project maintainer @ifnottrue
Author: nsomar
Source Code: https://github.com/nsomar/Swiftline
License: MIT license
1671701460
A color palette is one of the most important aspects of a design system. Designers can use them to create a visual hierarchy, define emotions, and create a unified look and feel. This article will discuss creating a color palette for your design system. We’ll also provide some tips on choosing colors that work well together. Let’s get started!
A color palette is a set of colors used together in a design. A color palette is a group of colors that work well together to provide uniformity in the use of color in your designs and create consistency in how you leverage color in products.
Creating a color palette helps tie everything together and creates harmony in the colors you employ. Designers use color palettes to create a visual hierarchy, define emotions, and create a unified look and feel. A color palette typically consists of three to five colors, although it can have more.
A sound color palette should:
It is crucial to have a color palette for your design system because it will help create consistent branding and visual interest. A color palette can also help to create a visual hierarchy, define emotions, and provide a unified look and feel.
When all of your design elements use the correct colors, they will look more professional and polished. This cohesion is the ultimate goal of a design system, and a palette of defined brand colors keeps things consistent.
Palettes may make your work more appealing aesthetically, but they also help you be more productive. Wouldn’t it be simpler if everyone on your team agreed on the design language?
It helps to have a defined color palette when working with other designers or developers. They can easily see which colors to use when creating new designs or adding to existing ones. Think about how much more scalable your design will be with a single source of truth for color choices.
Let’s look at how to create a color palette for your design system. Creating color palettes does not have to be an intimidating process. Choose the tone and atmosphere you want for your design, and from there, everything gets easier.
That said, you might often find yourself not knowing where to start. We’ve all been there. Fortunately, we created this 11-step guide to help you navigate color palette design.
Building an effective color palette leverages one of the most widespread mental models: Using what you already have (or can easily get) to get to unknowns (or what you don’t have).
In this case, these are your base colors. Base colors refer to the most frequently used colors in your UI and those that distinguish your product.
Such colors set the tone of the design, speak a message or elicit an emotional or psychological response from your audience.
Some of the rules of primary colors include:
You’ll often find most of these colors in your product’s logos, marketing, and overall design language.
Developing your accent colors is much easier once you have defined your primary colors. You can define an accent color as a variation of the base color.
A common practice is to define each accent color in three shades for use in different situations:
You use colors in your interface to communicate discrete things to your audience. This is what designers mean when they talk about semantic colors that highlight important information. For example, you could choose:
Here are a few color scheme options for you the next time you will be building extended palettes:
A naming convention will help you bring all your designers and developers onto the same page and ensure they speak the same design language.
When choosing a naming convention for your color palette, you’re spoilt for choice.
You can use abstract names such as bx7300, but some common approaches include choosing actual color names (such as blue) or numbered names such as 07000.
Just because you can name your colors anything doesn’t mean you should. You’re better off with a standardized naming system that is easy to comprehend.
Some of the rules of naming conventions are:
You’ll never go wrong with choosing a functional name for your color palette. These are names that give the purpose of the color, such as primary green.
Armed with an idea of both your primary and accent colors, you can then proceed and test the accessibility of these colors.
While you’re at it, ensure that your new colors match, and replace or merge with the colors you use in your current user interface.
What you have now is just a set of primary and accent colors in your palette. You’re yet to decide what goes where.
Your next logical step is to assign each of these aspects of your color palettes to global UI elements. These can include:
You have a color palette. Now you need to implement it in your CSS color system. This will help to ensure that your colors are applied consistently throughout your product interface.
Most designers today employ a blend of hexadecimal values, otherwise known as hex codes, to define color palettes.
You can make this effortless by using your list of color variables with a CSS preprocessor.
/*Variable names should be intuitive*/
$primary-color: #bada55;
$secondary-color: #c0ffee;
/*Usage*/
.some-class {
color: $primary-color; /*This will make the element's text color equal to bada55 */ }
After you have all your colors set up as variables, you can then use them throughout your CSS files by calling the variable name. This has the added benefit of making it easy to change colors globally should the need arise.
What effects do the new colors you’ve chosen have on the existing interface?
You’ve no doubt tried the palette on for size in design mockups, but there’s nothing like actual usage for finding points of improvement.
You’re more likely to figure out where colors are too unreadable or too bright, or when the contrast of your buttons isn’t right, when you’re ingesting real information and not glossing over Lorem Ipsum.
There is only one way to find out, and it’s testing the effect of the changes you’ve made on your existing interface.
Spin up a development environment and give your palette some solid real-world usage. Answering the following questions will help:
After introducing your new color palette to the interface, ensure that this new color palette offers enough contrast for accessibility.
We can do this by checking that the elements of our UI have sufficient contrast scores as regulated by the Web Content Accessibility Guidelines.
The easiest way is to use a plugin in your UI design tool of choice. Contrast for Figma is one example. Stark is a more fully-featured accessibility design platform that offers plugins for Figma, Adobe XD, and Sketch. It offers contrast checks on the free plan.
If you’ve been working on this project on your own, you’ll have to introduce it to other product designers somewhere down the road.
This can be done in a few ways, but the most important thing is to communicate your design decisions early and often.
A great way to do this is by writing a short blog post or creating a screencast that goes over the new colors, how they were chosen, and how they should be used.
At this stage, your color palette is ripe to be introduced to other stakeholders of the design process, such as your colleagues, team members, partners, or clients.
Two heads are better than one, and design is no exception. Don’t be afraid of getting ideas and suggestions from stakeholders as you choose your color palette.
If you designed the color palette on your own, ensure you introduce it to your team and receive any suggestions from your colleagues.
Congratulations, you’re almost done. However, before you go, there are some final touches you have to make before your palette is ready.
You should:
One thing to remember is that choosing a color palette isn’t a science, and anyone that tries to sell you on one single formula is lying.
Most of the time, your eye will be the judge, and when you can’t trust it, you have your team members for consultation.
While finalizing, search for any inconsistencies, tweaks, or improvements that you can make.
Designing color palettes shouldn’t be giving anyone sleepless nights.
If you want to go beyond implementation and learn to design color palettes that harmonize beautifully and convey the emotional tone of your brand, then it’s time to pick up some color theory.
In the second section of The Principles of Beautiful Web Design, we teach a condensed masterclass in color theory that will rapidly make you dangerous with a color picker. Learn:
Original article source at: https://www.sitepoint.com/
1671451572
Color wheels are useful in many situations and building one in Groovy is a great exercise to learn both how the wheel works and the, well, grooviness of Groovy.
Every so often, I find myself needing to calculate complementary colors. For example, I might be making a line graph in a web app or bar graphs for a report. When this happens, I want to use complementary colors to have the maximum "visual difference" between the lines or bars.
Online calculators can be useful in calculating two or maybe three complementary colors, but sometimes I need a lot more–for instance, maybe 10 or 15.
Many online resources explain how to do this and offer formulas, but I think it's high time for a Groovy color calculator. So please follow along. First, you might need to install Java and Groovy.
Groovy is based on Java and requires a Java installation as well. Both a recent/decent version of Java and Groovy might be in your Linux distribution's repositories. Or you can install Groovy by following the instructions on the above link.
A nice alternative for Linux users is SDKMan, which can get multiple versions of Java, Groovy, and many other related tools. For this article, I'm using SDK's releases of:
Before you start coding, look at a real color wheel. If you open GIMP (the GNU Image Manipulation Program) and look on the upper left-hand part of the screen, you'll see the controls to set the foreground and background colors, circled in red on the image below:
(Chris Hermansen, CC BY-SA 4.0)
If you click on the upper left square (the foreground color), a window will open that looks like this:
(Chris Hermansen, CC BY-SA 4.0)
If it doesn't quite look like that, click on the fourth from the left button on the top left row, which looks like a circle with a triangle inscribed in it.
The ring around the triangle represents a nearly continuous range of colors. In the image above, starting from the triangle pointer (the black line that interrupts the circle on the left), the colors shade from blue into cyan into green, yellow, orange, red, magenta, violet, and back to blue. This is the color wheel. If you pick two colors opposite each other on that wheel, you will have two complementary colors. If you choose 17 colors evenly spaced around that wheel, you'll have 17 colors that are as distinct as possible.
Make sure you have selected the HSV button in the top right of the window, then look at the sliders marked H, S, and V, respectively. These are hue, saturation, and value. When choosing contrasting colors, the hue is the interesting parameter.
Its value runs from zero to 360 degrees; in the image above, it's 192.9 degrees.
You can use this color wheel to calculate the complementary color to another manually–just add 180 to your color's value, giving you 372.9. Next, subtract 360, leaving 17.9 degrees. Type that 17.9 into the H box, replacing the 192.9, and poof, you have its complementary color:
(Chris Hermansen, CC BY-SA 4.0)
If you inspect the text box labeled HTML notation you'll see that the color you started with was #0080a3, and its complement is #a33100. Look at the fields marked Current and Old to see the two colors complementing each other.
There is a most excellent and detailed article on Wikipedia explaining HSL (hue, saturation, and lightness) and HSV (hue, saturation, and value) color models and how to convert between them and the RGB standard most of us know.
I'll automate this in Groovy. Because you might want to use this in various ways, create a Color class that provides constructors to create an instance of Color and then several methods to query the color of the instance in HSV and RGB.
Here's the Color class, with an explanation following:
1 /**
2 * This class based on the color transformation calculations
3 * in https://en.wikipedia.org/wiki/HSL_and_HSV
4 *
5 * Once an instance of Color is created, it can be transformed
6 * between RGB triplets and HSV triplets and converted to and
7 * from hex codes.
8 */
9 public class Color {
10 /**
11 * May as well keep the color as both RGB and HSL triplets
12 * Keep each component as double to avoid as many rounding
13 * errors as possible.
14 */
15 private final Map rgb // keys 'r','g','b'; values 0-1,0-1,0-1 double
16 private final Map hsv // keys 'h','s','v'; values 0-360,0-1,0-1 double
17 /**
18 * If constructor provided a single int, treat it as a 24-bit RGB representation
19 * Throw exception if not a reasonable unsigned 24 bit value
20 */
21 public Color(int color) {
22 if (color < 0 || color > 0xffffff) {
23 throw new IllegalArgumentException('color value must be between 0x000000 and 0xffffff')
24 } else {
25 this.rgb = [r: ((color & 0xff0000) >> 16) / 255d, g: ((color & 0x00ff00) >> 8) / 255d, b: (color & 0x0000ff) / 255d]
26 this.hsv = rgb2hsv(this.rgb)
27 }
28 }
29 /**
30 * If constructor provided a Map, treat it as:
31 * - RGB if map keys are 'r','g','b'
32 * - Integer and in range 0-255 ⇒ scale
33 * - Double and in range 0-1 ⇒ use as is
34 * - HSV if map keys are 'h','s','v'
35 * - Integer and in range 0-360,0-100,0-100 ⇒ scale
36 * - Double and in range 0-360,0-1,0-1 ⇒ use as is
37 * Throw exception if not according to above
38 */
39 public Color(Map triplet) {
40 def keySet = triplet.keySet()
41 def types = triplet.values().collect { it.class }
42 if (keySet == ['r','g','b'] as Set) {
43 def minV = triplet.min { it.value }.value
44 def maxV = triplet.max { it.value }.value
45 if (types == [Integer,Integer,Integer] && 0 <= minV && maxV <= 255) {
46 this.rgb = [r: triplet.r / 255d, g: triplet.g / 255d, b: triplet.b / 255d]
47 this.hsv = rgb2hsv(this.rgb)
48 } else if (types == [Double,Double,Double] && 0d <= minV && maxV <= 1d) {
49 this.rgb = triplet
50 this.hsv = rgb2hsv(this.rgb)
51 } else {
52 throw new IllegalArgumentException('rgb triplet must have integer values between (0,0,0) and (255,255,255) or double values between (0,0,0) and (1,1,1)')
53 }
54 } else if (keySet == ['h','s','v'] as Set) {
55 if (types == [Integer,Integer,Integer] && 0 <= triplet.h && triplet.h <= 360
56 && 0 <= triplet.s && triplet.s <= 100 && 0 <= triplet.v && triplet.v <= 100) {
57 this.hsv = [h: triplet.h as Double, s: triplet.s / 100d, v: triplet.v / 100d]
58 this.rgb = hsv2rgb(this.hsv)
59 } else if (types == [Double,Double,Double] && 0d <= triplet.h && triplet.h <= 360d
60 && 0d <= triplet.s && triplet.s <= 1d && 0d <= triplet.v && triplet.v <= 1d) {
61 this.hsv = triplet
62 this.rgb = hsv2rgb(this.hsv)
63 } else {
64 throw new IllegalArgumentException('hsv triplet must have integer values between (0,0,0) and (360,100,100) or double values between (0,0,0) and (360,1,1)')
65 }
66 } else {
67 throw new IllegalArgumentException('triplet must be a map with keys r,g,b or h,s,v')
68 }
69 }
70 /**
71 * Get the color representation as a 24 bit integer which can be
72 * rendered in hex in the familiar HTML form.
73 */
74 public int getHex() {
75 (Math.round(this.rgb.r * 255d) << 16) +
76 (Math.round(this.rgb.g * 255d) << 8) +
77 Math.round(this.rgb.b * 255d)
78 }
79 /**
80 * Get the color representation as a map with keys r,g,b
81 * and the corresponding double values in the range 0-1
82 */
83 public Map getRgb() {
84 this.rgb
85 }
86 /**
87 * Get the color representation as a map with keys r,g,b
88 * and the corresponding int values in the range 0-255
89 */
90 public Map getRgbI() {
91 this.rgb.collectEntries {k, v -> [(k): Math.round(v*255d)]}
92 }
93 /**
94 * Get the color representation as a map with keys h,s,v
95 * and the corresponding double values in the ranges 0-360,0-1,0-1
96 */
97 public Map getHsv() {
98 this.hsv
99 }
100 /**
101 * Get the color representation as a map with keys h,s,v
102 * and the corresponding int values in the ranges 0-360,0-100,0-100
103 */
104 public Map getHsvI() {
105 [h: Math.round(this.hsv.h), s: Math.round(this.hsv.s*100d), v: Math.round(this.hsv.v*100d)]
106 }
107 /**
108 * Internal routine to convert an RGB triple to an HSV triple
109 * Follows the Wikipedia section https://en.wikipedia.org/wiki/HSL_and_HSV#Hue_and_chroma
110 * (almost) - note that the algorithm given there does not adjust H for G < B
111 */
112 private static def rgb2hsv(Map rgbTriplet) {
113 def max = rgbTriplet.max { it.value }
114 def min = rgbTriplet.min { it.value }
115 double c = max.value - min.value
116 if (c) {
117 double h
118 switch (max.key) {
119 case 'r': h = ((60d * (rgbTriplet.g - rgbTriplet.b) / c) + 360d) % 360d; break
120 case 'g': h = ((60d * (rgbTriplet.b - rgbTriplet.r) / c) + 120d) % 360d; break
121 case 'b': h = ((60d * (rgbTriplet.r - rgbTriplet.g) / c) + 240d) % 360d; break
122 }
123 double v = max.value // hexcone model
124 double s = max.value ? c / max.value : 0d
125 [h: h, s: s, v: v]
126 } else {
127 [h: 0d, s: 0d, v: 0d]
128 }
129 }
130 /**
131 * Internal routine to convert an HSV triple to an RGB triple
132 * Follows the Wikipedia section https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_RGB
133 */
134 private static def hsv2rgb(Map hsvTriplet) {
135 double c = hsvTriplet.v * hsvTriplet.s
136 double hp = hsvTriplet.h / 60d
137 double x = c * (1d - Math.abs(hp % 2d - 1d))
138 double m = hsvTriplet.v - c
139 if (hp < 1d) [r: c + m, g: x + m, b: 0d + m]
140 else if (hp < 2d) [r: x + m, g: c + m, b: 0d + m]
141 else if (hp < 3d) [r: 0d + m, g: c + m, b: x + m]
142 else if (hp < 4d) [r: 0d + m, g: x + m, b: c + m]
143 else if (hp < 5d) [r: x + m, g: 0d + m, b: c + m]
144 else if (hp < 6d) [r: c + m, g: 0d + m, b: x + m]
145 }
146 }
The Color class definition, which begins on line 9 and ends on line 146, looks a lot like a Java class definition (at first glance, anyway) that would do the same thing. But this is Groovy, so you have no imports up at the beginning, just comments. Plus, the details illustrate some more Groovyness.
Line 15 creates the private final variable rgb that contains the color value supplied to the class constructor. You'll keep this value as Map with keys r
, g
, and b
to access the RGB values. Keep the values as double values between 0 and 1 so that 0 would indicate a hexadecimal value of #00 or an integer value of 0 and 1 would mean a hexadecimal value of #ff or an integer value of 255. Use double to avoid accumulating rounding errors when converting inside the class.
Similarly, line 16 creates the private final variable hsv that contains the same color value but in HSV format–also a Map, but with keys h
, s
, and v
to access the HSV values, which will be kept as double values between 0 and 360 (hue) and 0 and 1 (saturation and value).
Lines 21-28 define a Color constructor to be called when passing in an int argument. For example, you might use this as:
def blue = new Color(0x0000ff)
Lines 39-69 define another Color constructor to be called when passing in either an RGB or HSV triple as a Map. You might use this as:
def green = new Color([r: 0, g: 255, b: 0])
or
def cyan = new Color([h: 180, s: 100, v: 100])
Or similarly with double values scaled between 0 and 1 instead of integers between 0 and 255 in the RGB case and between 0 and 360, 0 and 1, and 0 and 1 for hue, saturation, and value, respectively.
This constructor looks complicated, and in a way, it is. It checks the keySet() of the map argument to decide whether it denotes an RGB or HSV tuple. It checks the class of the values passed in to determine whether the values are to be interpreted as integers or double values and, therefore, whether they are scaled into 0-1 (or 0-360 for hue).
Arguments that can't be sorted out using this checking are deemed incorrect, and an exception is thrown.
Worth noting is the handy streamlining provided by Groovy:
def types = triplet.values().collect { it.class }
This uses the values() method on the map to get the values as a List and then the collect() method on that List to get the class of each value so that they can later be checked against [Integer,Integer,Integer] or [Double,Double,Double] to ensure that arguments meet expectations.
Here is another useful streamlining provided by Groovy:
def minV = triplet.min { it.value }.value
The min() method is defined on Map; it iterates over the Map and returns the MapEntry—a (key, value) pair—having the minimum value encountered. The .value on the end selects the value field from that MapEntry, which gives something to check against later to determine whether the values need to be normalized.
Both rely on the Groovy Closure, similar to a Java lambda–a kind of anonymous procedure defined where it is called. For example, collect() takes a single Closure argument and passes it to each MapEntry encountered, known as the parameter within the closure body. Also, the various implementations of the Groovy Collection interface, including here Map, define the collect() and min() methods that iterate over the elements of the Collection and call the Closure argument. Finally, the syntax of Groovy supports compact and low-ceremony invocations of these various features.
Lines 70-106 define five "getters" that return the color used to create the instance in one of five formats:
r
, g
, b
and corresponding double values in the range 0-1.r
, g
, b
and corresponding int values in the range 0-255.h
, s
, v
and corresponding double values in the range 0-360, 0-1 and 0-1, respectively.h
, s
, v
and corresponding int values in the range 0-360, 0-100 and 0-100, respectively.Lines 112-129 define a static private (internal) method rgb2hsv() that converts an RGB triplet to an HSV triplet. This follows the algorithm described in the Wikipedia article section on Hue and chroma, except that the algorithm there yields negative hue values when the green value is less than the blue value, so the version is modified slightly. This code isn't particularly Groovy other than using the max() and min() Map methods and returning a Map instance declaratively without a return statement.
This method is used by the two getter methods to return the Color instance value in the correct form. Since it doesn't refer to any instance fields, it is static.
Similarly, lines 134-145 define another private (internal) method hsv2rgb(), that converts an HSV triplet to an RGB triplet, following the algorithm described in the Wikipedia article section on HSV to RGB conversion. The constructor uses this method to convert HSV triple arguments into RGB triples. Since it doesn't refer to any instance fields, it is static.
That's it. Here's an example of how to use this class:
1 def favBlue = new Color(0x0080a3)
2 def favBlueRgb = favBlue.rgb
3 def favBlueHsv = favBlue.hsv
4 println "favBlue hex = ${sprintf('0x%06x',favBlue.hex)}"
5 println "favBlue rgbt = ${favBlue.rgb}"
6 println "favBlue hsvt = ${favBlue.hsv}"
7 int spokeCount = 8
8 double dd = 360d / spokeCount
9 double d = favBlue.hsv.h
10 for (int spoke = 0; spoke < spokeCount; spoke++) {
11 def color = new Color(h: d, s: favBlue.hsv.s, v: favBlue.hsv.v)
12 println "spoke $spoke $d° hsv ${color.hsv}"
13 println " hex ${sprintf('0x%06x',color.hex)} hsvI ${color.hsvI} rgbI ${color.rgbI}"
14 d = (d + dd) % 360d
15 }
As my starting value, I've chosen the lighter blue from the opensource.com header #0080a3, and I'm printing a set of seven more colors that give maximum separation from the original blue. I call each position going around the color wheel a spoke and compute its position in degrees in the variable d, which is incremented each time through the loop by the number of degrees dd between each spoke.
As long as Color.groovy
and this test script are in the same directory, you can compile and run them as follows:
$ groovy test1Color.groovy
favBlue hex = 0x0080a3
favBlue rgbt = [r:0.0, g:0.5019607843137255, b:0.6392156862745098]
favBlue hsvt = [h:192.88343558282207, s:1.0, v:0.6392156862745098]
spoke 0 192.88343558282207° hsv [h:192.88343558282207, s:1.0, v:0.6392156862745098]
hex 0x0080a3 hsvI [h:193, s:100, v:64] rgbI [r:0, g:128, b:163]
spoke 1 237.88343558282207° hsv [h:237.88343558282207, s:1.0, v:0.6392156862745098]
hex 0x0006a3 hsvI [h:238, s:100, v:64] rgbI [r:0, g:6, b:163]
spoke 2 282.8834355828221° hsv [h:282.8834355828221, s:1.0, v:0.6392156862745098]
hex 0x7500a3 hsvI [h:283, s:100, v:64] rgbI [r:117, g:0, b:163]
spoke 3 327.8834355828221° hsv [h:327.8834355828221, s:1.0, v:0.6392156862745098]
hex 0xa30057 hsvI [h:328, s:100, v:64] rgbI [r:163, g:0, b:87]
spoke 4 12.883435582822074° hsv [h:12.883435582822074, s:1.0, v:0.6392156862745098]
hex 0xa32300 hsvI [h:13, s:100, v:64] rgbI [r:163, g:35, b:0]
spoke 5 57.883435582822074° hsv [h:57.883435582822074, s:1.0, v:0.6392156862745098]
hex 0xa39d00 hsvI [h:58, s:100, v:64] rgbI [r:163, g:157, b:0]
spoke 6 102.88343558282207° hsv [h:102.88343558282207, s:1.0, v:0.6392156862745098]
hex 0x2fa300 hsvI [h:103, s:100, v:64] rgbI [r:47, g:163, b:0]
spoke 7 147.88343558282207° hsv [h:147.88343558282207, s:1.0, v:0.6392156862745098]
hex 0x00a34c hsvI [h:148, s:100, v:64] rgbI [r:0, g:163, b:76]
You can see the degree position of the spokes reflected in the HSV triple. I've also printed the hex RGB value and the int version of the RGB and HSV triples.
I could have built this in Java. Had I done so, I probably would have created separate RgbTriple and HsvTriple helper classes because Java doesn't provide the declarative syntax for Map. That would have made finding the min and max values more verbose. So, as usual, the Java would have been more lengthy without improving readability. There would have been three constructors, though, which might be a more straightforward proposition.
I could have used 0-1 for the hue as I did for saturation and value, but somehow I like 0-360 better.
Finally, I could have added–and I may still do so one day–other conversions, such as HSL.
Color wheels are useful in many situations and building one in Groovy is a great exercise to learn both how the wheel works and the, well, grooviness of Groovy. Take your time; the code above is long. However, you can build your own practical color calculator and learn a lot along the way.
The Apache Groovy language site provides a good tutorial-level overview of working with Collection, particularly Map classes. This documentation is quite concise and easy to follow, at least partly because the facility it is documenting has been designed to be itself concise and easy to use!
Original article source at: https://opensource.com/