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/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/hsl_color.dart b/lib/hsl_color.dart deleted file mode 100644 index 2a83f5d..0000000 --- a/lib/hsl_color.dart +++ /dev/null @@ -1,12 +0,0 @@ -class HslColor { - double h; - double s; - double l; - double a; - - HslColor({this.h, this.s, this.l, this.a = 0.0}); - - String toString() { - return "HSL(h: $h, s: $s, l: $l, a: $a)"; - } -} 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 74% rename from lib/conversion.dart rename to lib/src/conversion.dart index 12f8a81..f6ee8e7 100644 --- a/lib/conversion.dart +++ b/lib/src/conversion.dart @@ -7,8 +7,11 @@ 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); @@ -37,9 +40,7 @@ HslColor rgbToHsl( return HslColor(h: h, s: s, l: l); } -Color hslToColor(HslColor hsl) { - return hslToRgb(hsl); -} +Color hslToColor(HslColor hsl) => hslToRgb(hsl); Color hslToRgb(HslColor hsl) { double r; @@ -59,21 +60,23 @@ Color hslToRgb(HslColor hsl) { b = _hue2rgb(p, q, h - 1 / 3); } return Color.fromARGB( - hsl.a.round(), (r * 255).round(), (g * 255).round(), (b * 255).round()); + hsl.a.round(), + (r * 255).round(), + (g * 255).round(), + (b * 255).round(), + ); } -HSVColor colorToHsv(Color color) { - return HSVColor.fromColor(color); -} +HSVColor colorToHsv(Color color) => HSVColor.fromColor(color); -HSVColor rgbToHsv( - {@required int r, @required int g, @required int b, @required int a}) { - return colorToHsv(Color.fromARGB(a, r, g, b)); -} +HSVColor rgbToHsv({ + @required int r, + @required int g, + @required int b, + @required int a, +}) => colorToHsv(Color.fromARGB(a, r, g, b)); -Color hsvToColor(HSVColor hsv) { - return hsv.toColor(); -} +Color hsvToColor(HSVColor hsv) => hsv.toColor(); double _hue2rgb(double p, double q, double t) { if (t < 0) t += 1; diff --git a/lib/src/hsl_color.dart b/lib/src/hsl_color.dart new file mode 100644 index 0000000..7e7962e --- /dev/null +++ b/lib/src/hsl_color.dart @@ -0,0 +1,15 @@ +class HslColor { + double h; + double s; + double l; + double a; + + HslColor({ + @required this.h, + @required this.s, + @required this.l, + this.a = 0.0, + }); + + String toString() => "HSL(h: $h, s: $s, l: $l, a: $a)"; +} diff --git a/lib/tinycolor.dart b/lib/src/tinycolor.dart similarity index 55% rename from lib/tinycolor.dart rename to lib/src/tinycolor.dart index 06e429d..338bafc 100644 --- a/lib/tinycolor.dart +++ b/lib/src/tinycolor.dart @@ -23,52 +23,38 @@ class TinyColor { Color.fromARGB(color.alpha, color.red, color.green, color.blue); } - factory TinyColor.fromRGB( - {@required int r, @required int g, @required int b, int a = 100}) { - return TinyColor(Color.fromARGB(a, r, g, b)); - } + factory TinyColor.fromRGB({ + @required int r, + @required int g, + @required int b, + int a = 100, + }) => TinyColor(Color.fromARGB(a, r, g, b)); - factory TinyColor.fromHSL(HslColor hsl) { - return TinyColor(hslToColor(hsl)); - } + factory TinyColor.fromHSL(HslColor hsl) => TinyColor(hslToColor(hsl)); - factory TinyColor.fromHSV(HSVColor hsv) { - return TinyColor(hsv.toColor()); - } + factory TinyColor.fromHSV(HSVColor hsv) => TinyColor(hsv.toColor()); - factory TinyColor.fromString(String string) { - return TinyColor(Pigment.fromString(string)); - } + factory TinyColor.fromString(String string) => TinyColor(Pigment.fromString(string)); - bool isDark() { - return this.getBrightness() < 128.0; - } + bool isDark() => getBrightness() < 128.0; - bool isLight() { - return !this.isDark(); - } + bool isLight() => !isDark(); - double getBrightness() { - return (_color.red * 299 + _color.green * 587 + _color.blue * 114) / 1000; - } + double getBrightness() => (_color.red * 299 + _color.green * 587 + _color.blue * 114) / 1000; - double getLuminance() { - return _color.computeLuminance(); - } + double getLuminance() => _color.computeLuminance(); 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; } - HSVColor toHsv() { - return colorToHsv(_color); - } + HSVColor toHsv() => colorToHsv(_color); HslColor toHsl() { final hsl = rgbToHsl( @@ -77,12 +63,14 @@ class TinyColor { b: _color.blue.toDouble(), ); return HslColor( - h: hsl.h * 360, s: hsl.s, l: hsl.l, a: _color.alpha.toDouble()); + h: hsl.h * 360, + s: hsl.s, + l: hsl.l, + a: _color.alpha.toDouble(), + ); } - TinyColor clone() { - return TinyColor(_color); - } + TinyColor clone() => TinyColor(_color); TinyColor lighten([int amount = 10]) { final hsl = this.toHsl(); @@ -103,62 +91,63 @@ class TinyColor { } TinyColor darken([int amount = 10]) { - final hsl = this.toHsl(); + final hsl = toHsl(); hsl.l -= amount / 100; hsl.l = clamp01(hsl.l); return TinyColor.fromHSL(hsl); } - TinyColor tint([int amount = 10]) { - return this.mix(input: Color.fromRGBO(255, 255, 255, 1.0)); - } + TinyColor tint([int amount = 10]) => 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)); - } + TinyColor shade([int amount = 10]) => mix( + input: Color.fromRGBO(0, 0, 0, 1.0), + amount: amount, + ); TinyColor desaturate([int amount = 10]) { - final hsl = this.toHsl(); + final hsl = toHsl(); hsl.s -= amount / 100; hsl.s = clamp01(hsl.s); return TinyColor.fromHSL(hsl); } TinyColor saturate([int amount = 10]) { - final hsl = this.toHsl(); + final hsl = toHsl(); hsl.s += amount / 100; hsl.s = clamp01(hsl.s); return TinyColor.fromHSL(hsl); } - TinyColor greyscale() { - return desaturate(100); - } + TinyColor greyscale() => desaturate(100); TinyColor spin(double amount) { - final hsl = this.toHsl(); + final hsl = toHsl(); final hue = (hsl.h + amount) % 360; hsl.h = hue < 0 ? 360 + hue : hue; 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); } TinyColor complement() { - final hsl = this.toHsl(); + final hsl = toHsl(); hsl.h = (hsl.h + 180) % 360; return TinyColor.fromHSL(hsl); } - Color get color { - return _color; - } + Color get color => _color; } diff --git a/lib/util.dart b/lib/src/util.dart similarity index 59% rename from lib/util.dart rename to lib/src/util.dart index c23393c..ada1aa5 100644 --- a/lib/util.dart +++ b/lib/src/util.dart @@ -1,4 +1,3 @@ -import 'dart:core'; import 'dart:math' as Math; double bound01(double n, double max) { @@ -9,13 +8,10 @@ double bound01(double n, double max) { } if (max == 360) { - n = (n < 0 ? n % max + max : n % max) / max; + return (n < 0 ? n % max + max : n % max) / max; } else { - n = (n % max) / max; + return (n % max) / max; } - return n; } -double clamp01(double val) { - return Math.min(1.0, Math.max(0.0, val)); -} +double clamp01(double val) => Math.min(1.0, Math.max(0.0, val)); 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.yaml b/pubspec.yaml index 1bb06c5..3493701 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ -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" 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", () {