diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..3b38583 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,33 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Environment (please complete the following information)** + - Package version [e.g. 22] + - Dart version [e.g. 2.12.0] + - Flutter version [e.g. 2.2.0] + - Target platform for Flutter [e.g. Android, iOS, web, etc.] + +**Additional context** +Add any other context about the problem here (including error message, logs). diff --git a/.github/ISSUE_TEMPLATE/vulnerability-report.md b/.github/ISSUE_TEMPLATE/vulnerability-report.md new file mode 100644 index 0000000..515f089 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/vulnerability-report.md @@ -0,0 +1,33 @@ +--- +name: Vulnerability report +about: Report any vulnerability you have found. +title: '' +labels: vulnerability +assignees: '' + +--- + +**Describe the vulnerability** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Environment (please complete the following information)** + - Package version [e.g. 22] + - Dart version [e.g. 2.12.0] + - Flutter version [e.g. 2.2.0] + - Target platform for Flutter [e.g. Android, iOS, web, etc.] + +**Additional context** +Add any other context about the problem here (including error message, logs). diff --git a/.gitignore b/.gitignore index 9172bce..b76b3d1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,205 @@ -.DS_Store -.dart_tool/ -.idea +# See https://www.dartlang.org/guides/libraries/private-files +# Files and directories created by pub +.dart_tool/ .packages -.pub/ +build/ +# If you're building an application, you may want to check-in your pubspec.lock +pubspec.lock + +# Directory created by dartdoc +# If you don't generate documentation locally you can remove this line. +doc/api/ + +# dotenv environment variables file +.env* + +# Avoid committing generated Javascript files: +*.dart.js +*.info.json # Produced by the --dump-info flag. +*.js # When generated by dart2js. Don't specify *.js if your + # project includes source files written in JavaScript. +*.js_ +*.js.deps +*.js.map + +.flutter-plugins +.flutter-plugins-dependencies + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## User settings +xcuserdata/ + +## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) +*.xcscmblueprint +*.xccheckout + +## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) build/ -ios/.generated/ -ios/Flutter/Generated.xcconfig -ios/Runner/GeneratedPluginRegistrant.* +DerivedData/ +*.moved-aside +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 + +## Gcc Patch +/*.gcno diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7b6e330 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..a84f1b5 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..797acea --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/tinycolor2.iml b/.idea/tinycolor2.iml new file mode 100644 index 0000000..ae9af97 --- /dev/null +++ b/.idea/tinycolor2.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index b854253..a7256f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,32 @@ -## [1.0.3] -* Added Color class extension method for direct usage -## [1.0.2] -* Fixed compatibility issues with dart 2.1 and pigment 1.0.3 -## [1.0.1] -* Fixed HSLColor class name duplicate definition. -* Updated package description -## [1.0.0] -* Initial port of tinycolor2 +# Changelog + +## [2.0.0] - TBD + +### Changed +* Forked as a community version `tinycolor2` + +### Fixed +* #2, #6, #10 from upstream at [PR #5](https://github.com/TinyCommunity/tinycolor2/pull/5) + +## [1.0.3] - 2020-08-27 + +### Added +* Color class extension method for direct usage + +## [1.0.2] - 2018-08-17 + +### Fixed +* Compatibility issues with dart 2.1 and pigment 1.0.3 + +## [1.0.1] - 2018-08-04 + +### Fixed +* HSLColor class name duplicate definition + +### Changed +* Package description + +## [1.0.0] - 2018-08-04 + +### Added +* Initial port of tinycolor2 diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..3e83b0b --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,14 @@ +# Security Policy + +## Supported Versions + +The following versions are currently being supported with security updates. + +| Version | Supported | +| ------- | ------------------ | +| 2.0.x | :white_check_mark: | +| < 2.0 | :x: | + +## Reporting a Vulnerability + +To report any security issues, please open an issue [here](https://github.com/TinyCommunity/tinycolor2/issues/new/choose). diff --git a/lib/color_extension.dart b/lib/src/color_extension.dart similarity index 92% rename from lib/color_extension.dart rename to lib/src/color_extension.dart index af86a7b..235d4b2 100644 --- a/lib/color_extension.dart +++ b/lib/src/color_extension.dart @@ -1,13 +1,13 @@ import 'package:flutter/painting.dart'; import 'tinycolor.dart'; -/// Extends the Color class to allow direct TinyColor manipulation nativly +/// Extends the Color class to allow direct TinyColor manipulation natively extension TinyColorExtension on Color { /// Converts standard Color to TinyColor object TinyColor toTinyColor() => TinyColor(this); HSVColor toHsv() => TinyColor(this).toHsv(); - + HslColor toHsl() => TinyColor(this).toHsl(); /// Lighten the color a given amount, from 0 to 100. Providing 100 will always return white. @@ -26,7 +26,8 @@ extension TinyColorExtension on Color { Color shade([int amount = 10]) => TinyColor(this).shade(amount).color; /// Desaturate the color a given amount, from 0 to 100. Providing 100 will is the same as calling greyscale. - Color desaturate([int amount = 10]) => TinyColor(this).desaturate(amount).color; + Color desaturate([int amount = 10]) => + TinyColor(this).desaturate(amount).color; /// Saturate the color a given amount, from 0 to 100. Color saturate([int amount = 10]) => TinyColor(this).saturate(amount).color; @@ -53,5 +54,6 @@ extension TinyColorExtension on Color { Color get compliment => TinyColor(this).complement().color; /// Blends the color with another color a given amount, from 0 - 100, default 50. - Color mix(Color toColor, [int amount = 50]) => TinyColor(this).mix(input: toColor, amount: amount).color; + Color mix(Color toColor, [int amount = 50]) => + TinyColor(this).mix(input: toColor, amount: amount).color; } diff --git a/lib/conversion.dart b/lib/src/conversion.dart similarity index 90% rename from lib/conversion.dart rename to lib/src/conversion.dart index 12f8a81..760ab0d 100644 --- a/lib/conversion.dart +++ b/lib/src/conversion.dart @@ -2,13 +2,11 @@ import 'dart:math' as Math; import 'dart:ui'; import 'package:flutter/painting.dart'; -import 'package:meta/meta.dart'; import 'hsl_color.dart'; import 'util.dart'; -HslColor rgbToHsl( - {@required double r, @required double g, @required double b}) { +HslColor rgbToHsl({required double r, required double g, required double b}) { r = bound01(r, 255.0); g = bound01(g, 255.0); b = bound01(b, 255.0); @@ -67,7 +65,7 @@ HSVColor colorToHsv(Color color) { } HSVColor rgbToHsv( - {@required int r, @required int g, @required int b, @required int a}) { + {required int r, required int g, required int b, required int a}) { return colorToHsv(Color.fromARGB(a, r, g, b)); } diff --git a/lib/hsl_color.dart b/lib/src/hsl_color.dart similarity index 64% rename from lib/hsl_color.dart rename to lib/src/hsl_color.dart index 2a83f5d..0abf1d5 100644 --- a/lib/hsl_color.dart +++ b/lib/src/hsl_color.dart @@ -4,7 +4,7 @@ class HslColor { double l; double a; - HslColor({this.h, this.s, this.l, this.a = 0.0}); + HslColor({required this.h, required this.s, required this.l, this.a = 0.0}); String toString() { return "HSL(h: $h, s: $s, l: $l, a: $a)"; diff --git a/lib/tinycolor.dart b/lib/src/tinycolor.dart similarity index 70% rename from lib/tinycolor.dart rename to lib/src/tinycolor.dart index 06e429d..3d842c9 100644 --- a/lib/tinycolor.dart +++ b/lib/src/tinycolor.dart @@ -2,7 +2,6 @@ import 'dart:math' as Math; import 'dart:ui'; import 'package:flutter/painting.dart'; -import 'package:meta/meta.dart'; import 'package:pigment/pigment.dart'; import 'conversion.dart'; @@ -13,18 +12,15 @@ export 'hsl_color.dart'; export 'color_extension.dart'; class TinyColor { - Color originalColor; + final Color originalColor; Color _color; - TinyColor(Color color) { - this.originalColor = - Color.fromARGB(color.alpha, color.red, color.green, color.blue); - this._color = - Color.fromARGB(color.alpha, color.red, color.green, color.blue); - } + TinyColor(Color color) + : this.originalColor = color, + _color = color.clone(); factory TinyColor.fromRGB( - {@required int r, @required int g, @required int b, int a = 100}) { + {required int r, required int g, required int b, int a = 100}) { return TinyColor(Color.fromARGB(a, r, g, b)); } @@ -57,12 +53,12 @@ class TinyColor { } TinyColor setAlpha(int alpha) { - _color.withAlpha(alpha); + _color = _color.withAlpha(alpha); return this; } TinyColor setOpacity(double opacity) { - _color.withOpacity(opacity); + _color = _color.withOpacity(opacity); return this; } @@ -80,6 +76,8 @@ class TinyColor { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: _color.alpha.toDouble()); } + String toHex8() => _color.value.toRadixString(16).padLeft(8, '0'); + TinyColor clone() { return TinyColor(_color); } @@ -110,11 +108,11 @@ class TinyColor { } TinyColor tint([int amount = 10]) { - return this.mix(input: Color.fromRGBO(255, 255, 255, 1.0)); + return this.mix(input: Color.fromRGBO(255, 255, 255, 1.0), amount: amount); } TinyColor shade([int amount = 10]) { - return this.mix(input: Color.fromRGBO(0, 0, 0, 1.0)); + return this.mix(input: Color.fromRGBO(0, 0, 0, 1.0), amount: amount); } TinyColor desaturate([int amount = 10]) { @@ -142,13 +140,13 @@ class TinyColor { return TinyColor.fromHSL(hsl); } - TinyColor mix({@required Color input, int amount = 50}) { - final int p = (amount / 100).round(); + TinyColor mix({required Color input, int amount = 50}) { + final p = amount / 100.0; final color = Color.fromARGB( - (input.alpha - _color.alpha) * p + _color.alpha, - (input.red - _color.red) * p + _color.red, - (input.green - _color.green) * p + _color.green, - (input.blue - _color.blue) * p + _color.blue); + ((input.alpha - _color.alpha) * p + _color.alpha).round(), + ((input.red - _color.red) * p + _color.red).round(), + ((input.green - _color.green) * p + _color.green).round(), + ((input.blue - _color.blue) * p + _color.blue).round()); return TinyColor(color); } @@ -161,4 +159,23 @@ class TinyColor { Color get color { return _color; } + + @override + bool operator ==(Object other) => + identical(this, other) || + other is TinyColor && + runtimeType == other.runtimeType && + color == other.color; + + @override + int get hashCode => color.hashCode; + + @Deprecated('Use == instead.') + bool equals(Object other) => this == other; +} + +extension _ on Color { + Color clone() { + return Color.fromARGB(alpha, red, green, blue); + } } diff --git a/lib/util.dart b/lib/src/util.dart similarity index 100% rename from lib/util.dart rename to lib/src/util.dart diff --git a/lib/tinycolor2.dart b/lib/tinycolor2.dart new file mode 100644 index 0000000..9104354 --- /dev/null +++ b/lib/tinycolor2.dart @@ -0,0 +1,7 @@ +library tinycolor2; + +export 'src/color_extension.dart'; +export 'src/conversion.dart'; +export 'src/hsl_color.dart'; +export 'src/tinycolor.dart'; +export 'src/util.dart'; diff --git a/pubspec.lock b/pubspec.lock deleted file mode 100644 index 544bf47..0000000 --- a/pubspec.lock +++ /dev/null @@ -1,154 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.2" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - characters: - dependency: transitive - description: - name: characters - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.13" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.8" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pigment: - dependency: "direct main" - description: - name: pigment - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.5" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.17" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.9.0-14.0.dev <3.0.0" - flutter: ">=1.12.0 <3.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 1bb06c5..9584564 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,17 +1,16 @@ -name: tinycolor +name: tinycolor2 description: Flutter Color manipulation and conversion, ported from JS tinycolor2 -version: 1.0.3 -homepage: https://github.com/FooStudio/tinycolor +version: 2.0.0 +homepage: https://github.com/TinyCommunity/tinycolor2 environment: - sdk: ">=2.6.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.12.0 <3.0.0" dependencies: - pigment: ^1.0.3 - meta: ^1.2.2 flutter: sdk: flutter + pigment: ^1.0.4 dev_dependencies: flutter_test: diff --git a/test/tinycolor_test.dart b/test/tinycolor_test.dart new file mode 100644 index 0000000..093cebe --- /dev/null +++ b/test/tinycolor_test.dart @@ -0,0 +1,27 @@ +import 'dart:ui'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:tinycolor2/tinycolor2.dart'; + +void main() { + test( + "setAlpha updates alpha value of color", + () { + TinyColor color = TinyColor(Color(0xFFFFFFFF)); + color.setAlpha(0x00); + expect(color.color.alpha, 0x00); + }, + ); + + test( + "setOpacity updates opacity value of color", + () { + TinyColor color = TinyColor(Color(0xFFFFFFFF).withOpacity(1.0)); + color.setOpacity(0.5); + + // underlying dart implementation converts the opacity value to an + // int, then back into a double. Thus some precision is loss. + expect(color.color.opacity, moreOrLessEquals(0.5, epsilon: 1e-2)); + }, + ); +} diff --git a/test/util_test.dart b/test/util_test.dart index eb7120a..e050c33 100644 --- a/test/util_test.dart +++ b/test/util_test.dart @@ -1,6 +1,5 @@ import 'package:flutter_test/flutter_test.dart'; -//import 'package:test/test.dart'; -import 'package:tinycolor/util.dart'; +import 'package:tinycolor2/tinycolor2.dart'; void main() { test("bound01 values", () {