From 3438e8437e36d21442da9d7107b28177329097eb Mon Sep 17 00:00:00 2001 From: Sowren Sen <80112748+nemoitis@users.noreply.github.com> Date: Mon, 20 Feb 2023 13:14:17 +0600 Subject: [PATCH 01/14] build svg from blade views --- resources/views/elements/circle.blade.php | 1 + resources/views/elements/rectangle.blade.php | 1 + resources/views/elements/svg.blade.php | 32 +++++++++ src/Enums/Shape.php | 11 +++ src/Svg.php | 71 ++------------------ src/SvgAvatarGeneratorServiceProvider.php | 6 ++ 6 files changed, 58 insertions(+), 64 deletions(-) create mode 100644 resources/views/elements/circle.blade.php create mode 100644 resources/views/elements/rectangle.blade.php create mode 100644 resources/views/elements/svg.blade.php diff --git a/resources/views/elements/circle.blade.php b/resources/views/elements/circle.blade.php new file mode 100644 index 0000000..e2b2a06 --- /dev/null +++ b/resources/views/elements/circle.blade.php @@ -0,0 +1 @@ + diff --git a/resources/views/elements/rectangle.blade.php b/resources/views/elements/rectangle.blade.php new file mode 100644 index 0000000..5fe0755 --- /dev/null +++ b/resources/views/elements/rectangle.blade.php @@ -0,0 +1 @@ + diff --git a/resources/views/elements/svg.blade.php b/resources/views/elements/svg.blade.php new file mode 100644 index 0000000..a616f8e --- /dev/null +++ b/resources/views/elements/svg.blade.php @@ -0,0 +1,32 @@ +@php + /** + * @var Sowren\SvgAvatarGenerator\SvgAvatarGenerator $generator + * @var string $gradientId + */ +@endphp + + + + + + + + + @include($generator->getShape()->render()) + + {{ $generator->getInitials() }} + + diff --git a/src/Enums/Shape.php b/src/Enums/Shape.php index 39f24bf..e57fbc4 100644 --- a/src/Enums/Shape.php +++ b/src/Enums/Shape.php @@ -6,4 +6,15 @@ enum Shape { case CIRCLE; case RECTANGLE; + + /** + * Render corresponding XML element. + */ + public function render(): string + { + return match ($this) { + self::CIRCLE => "svg::elements.circle", + self::RECTANGLE => "svg::elements.rectangle", + }; + } } diff --git a/src/Svg.php b/src/Svg.php index 8b44f8e..5455360 100644 --- a/src/Svg.php +++ b/src/Svg.php @@ -2,8 +2,8 @@ namespace Sowren\SvgAvatarGenerator; -use Sowren\SvgAvatarGenerator\Enums\Shape; use Str; +use View; class Svg { @@ -20,74 +20,17 @@ public function __construct( public function __toString(): string { - return $this->svgElement(); + return $this->render(); } /** * Build the output SVG. */ - protected function svgElement(): string + protected function render(): string { - try { - $svg = << - - - - - - - {$this->getElement($this->generator->getShape())} - - {$this->generator->getInitials()} - - - SVG; - } catch (\Exception $e) { - logger($e->getMessage()); - $svg = ''; - } - - return $svg; - } - - /** - * Find SVG element of the given shape. - */ - protected function getElement(Shape $shape): string - { - return match ($shape) { - Shape::RECTANGLE => $this->rectangleElement(), - default => $this->circleElement(), - }; - } - - /** - * The circle element of SVG markup. - */ - protected function circleElement(): string - { - return ""; - } - - /** - * The rectangle element of SVG markup. - */ - protected function rectangleElement(): string - { - return ""; + return View::make('svg::elements.svg', [ + 'generator' => $this->generator, + 'gradientId' => $this->gradientId + ])->render(); } } diff --git a/src/SvgAvatarGeneratorServiceProvider.php b/src/SvgAvatarGeneratorServiceProvider.php index 72d58af..c7c9ec0 100644 --- a/src/SvgAvatarGeneratorServiceProvider.php +++ b/src/SvgAvatarGeneratorServiceProvider.php @@ -19,4 +19,10 @@ public function configurePackage(Package $package): void ->hasConfigFile('svg-avatar') ->hasRoute('web'); } + + public function bootingPackage() + { + // We are not going to publish these views + $this->loadViewsFrom(__DIR__.'/../resources/views', 'svg'); + } } From c70ec9a737929b37ee05545718a0b8d51c2c4cfc Mon Sep 17 00:00:00 2001 From: Sowren Sen <80112748+nemoitis@users.noreply.github.com> Date: Sat, 25 Feb 2023 23:56:53 +0600 Subject: [PATCH 02/14] multiple gradient support --- config/svg-avatar.php | 44 +++++++++++++--- src/SvgAvatarGenerator.php | 102 ++++++++++++++++++++++--------------- src/Tool.php | 98 +++++++++++++++++++++++++++++++++++ 3 files changed, 198 insertions(+), 46 deletions(-) create mode 100644 src/Tool.php diff --git a/config/svg-avatar.php b/config/svg-avatar.php index 838965a..d381724 100644 --- a/config/svg-avatar.php +++ b/config/svg-avatar.php @@ -84,15 +84,47 @@ | Gradient Colors |-------------------------------------------------------------------------- | - | Who doesn't admire a nice gradient for background color? For now, - | mixture of two colors are supported. You can provide same color - | to achieve a flat background. + | Who doesn't admire a nice gradient for background color? You can set + | a single gradient color or multiple sets of gradients to achieve + | more dynamic effect. | - | Type: array - | Default: ['#3A1C71', '#FDBB2D'] + | A fixed single gradient can be set by configuring list of hex colors. + | For example, setting ['#FF0000', '#00FF00', '#0000FF'] will make a + | gradient consisting red/green/blue color always. + | + | To set multiple gradients, you have to configure sets of colors. For + | example, setting [['#FF0000', '#00FF00'], '#0000FF'] will randomly + | generate a gradient of either red/green or blue background. + | + | You can provide same color to achieve a flat background. + | + | NOTE: Number of colors in a set—regardless of single multiple set—must + | be consistent with gradient offsets. + | + | Type: array + | Default: ['#3A1C71', '#4F46E5', '#FDBB2D'] + | + */ + 'gradient_colors' => ['#3A1C71', '#4F46E5', '#FDBB2D'], + + /* + |-------------------------------------------------------------------------- + | Gradient Stops + |-------------------------------------------------------------------------- + | + | Specify the stopping positions of gradient colors. Number of colors + | in a set—regardless of single multiple set—must be consistent + | with number of gradient stops. If you set more colors than + | stops, the extra colors will be omitted, and if you set + | fewer colors then stops, the last color in the set + | will be repeated. + | + | Type: array + | Default: [0, .5, 1] + | Allowed: 0 to 1 | */ - 'gradient_colors' => ['#3A1C71', '#FDBB2D'], + 'gradient_stops' => [0, .5, 1], /* |-------------------------------------------------------------------------- diff --git a/src/SvgAvatarGenerator.php b/src/SvgAvatarGenerator.php index 4cb71d3..355b3d6 100755 --- a/src/SvgAvatarGenerator.php +++ b/src/SvgAvatarGenerator.php @@ -2,8 +2,7 @@ namespace Sowren\SvgAvatarGenerator; -use Exception; -use Illuminate\Support\Str; +use Arr; use Sowren\SvgAvatarGenerator\Enums\FontWeight; use Sowren\SvgAvatarGenerator\Enums\Shape; use Sowren\SvgAvatarGenerator\Exceptions\InvalidFontSizeException; @@ -13,6 +12,8 @@ class SvgAvatarGenerator { + use Tool; + /** * Initials to be put in SVG. */ @@ -49,10 +50,20 @@ class SvgAvatarGenerator protected int $gradientRotation; /** - * Colors used for gradient, use same colors for a plain SVG. + * Colors used to portray gradient. */ protected array $gradientColors; + /** + * Positions of gradient color stops. + */ + protected array $gradientStops; + + /** + * Picked set of gradient color and offset. + */ + protected array $gradientSet; + /** * Array to hold default config. */ @@ -271,51 +282,63 @@ public function getGradientColors(): array } /** - * Set the two colors (hex) for gradient, use same color for - * a plain or flat SVG output. + * Set the colors (hex) for gradient. Colors can either be passed + * as single or in pairs for random gradient generation. + * + * Examples: + * + * Passing ('red', 'green', 'blue') will be considered as single + * set of colors and will generate a gradient consisting these + * three colors. + * + * Passing (['red', 'green'], 'blue') will be considered as two + * different sets of colors and will generate random gradient + * consisting either red/green or blue background. */ - public function setGradientColors(string $firstColor, string $secondColor): static + public function setGradientColors(string|array ...$colors): static { - $this->gradientColors[0] = $firstColor; - $this->gradientColors[1] = $secondColor; + $this->gradientColors = $colors; return $this; } /** - * Extract initials from given text/name. If only one word is given, - * it will look for second capital character in the word, else - * the consecutive second character will be taken. - * - * @throws MissingTextException + * Get the gradient colors. */ - protected function extractInitials(): static + public function getGradientStops(): array { - $name = $this->text; - - if (Str::contains($name, ' ')) { - // If name has more than one part then break each part upto each space - $parts = Str::of($name)->explode(' '); - } else { - // If name has only one part then try to find out if there are - // any uppercase letters in the string. Then break the string - // upto each uppercase letters, this allows to pass names in - // studly case, e.g. 'SowrenSen'. If no uppercase letter is - // found, $parts will have only one item in the array. - $parts = Str::of($name)->kebab()->replace('-', ' ')->explode(' '); - } + return $this->gradientStops; + } - try { - $firstInitial = $parts->first()[0]; + /** + * Set stop positions of gradients. + */ + public function setGradientStops(int|float ...$offsets): static + { + $this->gradientStops = $offsets; - // If only one part is found, take the second letter as second - // initial, else take the first letter of the last part. - $secondInitial = ($parts->count() === 1) ? $parts->first()[1] : $parts->last()[0]; - } catch (Exception) { - throw MissingTextException::create(); - } + return $this; + } + + /** + * Returns the picked combination of colors + * for gradient. + */ + public function getGradientSet(): array + { + return $this->gradientSet; + } + + /** + * Set combination of colors and offsets. + */ + protected function setGradientSet(): static + { + // Choose one randomly from the list + // of prepared gradient sets. + $set = Arr::random($this->zip()); - $this->setInitials(strtoupper($firstInitial.$secondInitial)); + $this->gradientSet = $set; return $this; } @@ -336,10 +359,8 @@ protected function build(): void ->setFontWeight($this->config['font_weight']) ->setForeground($this->config['foreground']) ->setGradientRotation($this->config['gradient_rotation']) - ->setGradientColors( - $this->config['gradient_colors'][0], - $this->config['gradient_colors'][1] - ); + ->setGradientColors(...$this->config['gradient_colors']) + ->setGradientStops(...$this->config['gradient_stops']); } /** @@ -350,6 +371,7 @@ protected function build(): void public function render(): Svg { $this->extractInitials(); + $this->setGradientSet(); return new Svg($this); } diff --git a/src/Tool.php b/src/Tool.php new file mode 100644 index 0000000..1ad1287 --- /dev/null +++ b/src/Tool.php @@ -0,0 +1,98 @@ +text; + + if (Str::contains($name, ' ')) { + // If name has more than one part then break each part upto each space + $parts = Str::of($name)->explode(' '); + } else { + // If name has only one part then try to find out if there are + // any uppercase letters in the string. Then break the string + // upto each uppercase letters, this allows to pass names in + // studly case, e.g. 'SowrenSen'. If no uppercase letter is + // found, $parts will have only one item in the array. + $parts = Str::of($name)->kebab()->replace('-', ' ')->explode(' '); + } + + try { + $firstInitial = $parts->first()[0]; + + // If only one part is found, take the second letter as second + // initial, else take the first letter of the last part. + $secondInitial = ($parts->count() === 1) ? $parts->first()[1] : $parts->last()[0]; + } catch (Exception) { + throw MissingTextException::create(); + } + + $this->setInitials(strtoupper($firstInitial . $secondInitial)); + } + + + /** + * Creates sets of colors and offsets to form the gradients. + */ + public function zip(): array + { + $colors = $this->getGradientColors(); + $offsets = $this->getGradientStops(); + + $hasMultipleSet = count(Arr::where($colors, fn ($color) => is_array($color))) > 0; + + return $hasMultipleSet + ? $this->zipMultiple($colors, $offsets) + : $this->zipOne($colors, $offsets); + } + + /** + * Zip one set of colors to offsets. + */ + private function zipOne($colors, $offsets): array + { + $set = []; + + foreach ($offsets as $key => $offset) { + $set[] = ['color' => $colors[$key] ?? $colors[count($colors) - 1], 'offset' => $offset]; + } + + return [$set]; + } + + /** + * Zip multiple sets of colors to offsets. + */ + private function zipMultiple($colors, $offsets): array + { + $gradientSets = []; + foreach ($colors as $gradColors) { + $set = []; + foreach ($offsets as $key => $offset) { + $color = is_array($gradColors) + ? $gradColors[$key] ?? $gradColors[count($gradColors) - 1] + : $gradColors; + + $set [] = ['color' => $color, 'offset' => $offset]; + } + $gradientSets[] = $set; + } + + return $gradientSets; + } +} From d52d453d6836adf30627bb044910da3a291c16f4 Mon Sep 17 00:00:00 2001 From: Sowren Sen <80112748+nemoitis@users.noreply.github.com> Date: Sat, 25 Feb 2023 23:57:14 +0600 Subject: [PATCH 03/14] dynamic stop positions --- resources/views/elements/linear-gradient.blade.php | 12 ++++++++++++ resources/views/elements/svg.blade.php | 5 +---- 2 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 resources/views/elements/linear-gradient.blade.php diff --git a/resources/views/elements/linear-gradient.blade.php b/resources/views/elements/linear-gradient.blade.php new file mode 100644 index 0000000..f49c937 --- /dev/null +++ b/resources/views/elements/linear-gradient.blade.php @@ -0,0 +1,12 @@ +@php + /** + * @var Sowren\SvgAvatarGenerator\SvgAvatarGenerator $generator + * @var string $gradientId + */ +@endphp + + + @foreach($generator->getGradientSet() as $set) + + @endforeach + diff --git a/resources/views/elements/svg.blade.php b/resources/views/elements/svg.blade.php index a616f8e..1dcaa14 100644 --- a/resources/views/elements/svg.blade.php +++ b/resources/views/elements/svg.blade.php @@ -12,10 +12,7 @@ xmlns:xlink="http://www.w3.org/1999/xlink" > - - - - + @include('svg::elements.linear-gradient') @include($generator->getShape()->render()) Date: Sat, 25 Feb 2023 17:57:51 +0000 Subject: [PATCH 04/14] Fix styling --- src/Enums/Shape.php | 4 ++-- src/Svg.php | 2 +- src/Tool.php | 7 +++---- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Enums/Shape.php b/src/Enums/Shape.php index e57fbc4..823e4bb 100644 --- a/src/Enums/Shape.php +++ b/src/Enums/Shape.php @@ -13,8 +13,8 @@ enum Shape public function render(): string { return match ($this) { - self::CIRCLE => "svg::elements.circle", - self::RECTANGLE => "svg::elements.rectangle", + self::CIRCLE => 'svg::elements.circle', + self::RECTANGLE => 'svg::elements.rectangle', }; } } diff --git a/src/Svg.php b/src/Svg.php index 5455360..133be18 100644 --- a/src/Svg.php +++ b/src/Svg.php @@ -30,7 +30,7 @@ protected function render(): string { return View::make('svg::elements.svg', [ 'generator' => $this->generator, - 'gradientId' => $this->gradientId + 'gradientId' => $this->gradientId, ])->render(); } } diff --git a/src/Tool.php b/src/Tool.php index 1ad1287..7f0c2f0 100644 --- a/src/Tool.php +++ b/src/Tool.php @@ -2,10 +2,10 @@ namespace Sowren\SvgAvatarGenerator; -use Str; use Arr; use Exception; use Sowren\SvgAvatarGenerator\Exceptions\MissingTextException; +use Str; trait Tool { @@ -42,10 +42,9 @@ protected function extractInitials(): void throw MissingTextException::create(); } - $this->setInitials(strtoupper($firstInitial . $secondInitial)); + $this->setInitials(strtoupper($firstInitial.$secondInitial)); } - /** * Creates sets of colors and offsets to form the gradients. */ @@ -88,7 +87,7 @@ private function zipMultiple($colors, $offsets): array ? $gradColors[$key] ?? $gradColors[count($gradColors) - 1] : $gradColors; - $set [] = ['color' => $color, 'offset' => $offset]; + $set[] = ['color' => $color, 'offset' => $offset]; } $gradientSets[] = $set; } From 60a695a648fffc83f8e824b3c6ecbd889324a128 Mon Sep 17 00:00:00 2001 From: Sowren Sen <80112748+nemoitis@users.noreply.github.com> Date: Sun, 26 Feb 2023 00:11:53 +0600 Subject: [PATCH 05/14] zipper tests --- tests/ZipperTest.php | 68 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 tests/ZipperTest.php diff --git a/tests/ZipperTest.php b/tests/ZipperTest.php new file mode 100644 index 0000000..54a737d --- /dev/null +++ b/tests/ZipperTest.php @@ -0,0 +1,68 @@ +setGradientColors('red', 'green', 'blue') + ->setGradientStops(0, .5, 1); + + expect($generator->zip())->toBe([ + [ + ['color' => 'red', 'offset' => 0], + ['color' => 'green', 'offset' => .5], + ['color' => 'blue', 'offset' => 1] + ] + ]); +}); + +it('can make gradient set from multiple sets of colors', function() { + $generator = new SvgAvatarGenerator(); + $generator->setGradientColors(['red', 'green', 'yellow'], 'blue') + ->setGradientStops(0, .5, 1); + + expect($generator->zip())->toBe([ + [ + ['color' => 'red', 'offset' => 0], + ['color' => 'green', 'offset' => .5], + ['color' => 'yellow', 'offset' => 1] + ], + [ + ['color' => 'blue', 'offset' => 0], + ['color' => 'blue', 'offset' => .5], + ['color' => 'blue', 'offset' => 1] + ] + ]); +}); + +it('will omit additional colors set more than offsets', function() { + $generator = new SvgAvatarGenerator(); + $generator->setGradientColors(['red', 'green', 'yellow']) + ->setGradientStops(0, 1); + + expect($generator->zip())->toBe([ + [ + ['color' => 'red', 'offset' => 0], + ['color' => 'green', 'offset' => 1], // yellow after green is omitted + ] + ]); +}); + +it('will repeat last color if set fewer than offsets', function() { + $generator = new SvgAvatarGenerator(); + $generator->setGradientColors(['red', 'green'], 'blue') + ->setGradientStops(0, .5, 1); + + expect($generator->zip())->toBe([ + [ + ['color' => 'red', 'offset' => 0], + ['color' => 'green', 'offset' => .5], + ['color' => 'green', 'offset' => 1], // repeating green + ], + [ + ['color' => 'blue', 'offset' => 0], + ['color' => 'blue', 'offset' => .5], // repeating blue + ['color' => 'blue', 'offset' => 1], // repeating blue + ] + ]); +}); From 0e5d0c6f2d7afcc779a0c3880bb794c6ea111b58 Mon Sep 17 00:00:00 2001 From: sowrensen Date: Sat, 25 Feb 2023 18:13:49 +0000 Subject: [PATCH 06/14] Fix styling --- tests/ZipperTest.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/ZipperTest.php b/tests/ZipperTest.php index 54a737d..2252faa 100644 --- a/tests/ZipperTest.php +++ b/tests/ZipperTest.php @@ -2,7 +2,7 @@ use Sowren\SvgAvatarGenerator\SvgAvatarGenerator; -it('can make gradient set from single set of colors', function() { +it('can make gradient set from single set of colors', function () { $generator = new SvgAvatarGenerator(); $generator->setGradientColors('red', 'green', 'blue') ->setGradientStops(0, .5, 1); @@ -11,12 +11,12 @@ [ ['color' => 'red', 'offset' => 0], ['color' => 'green', 'offset' => .5], - ['color' => 'blue', 'offset' => 1] - ] + ['color' => 'blue', 'offset' => 1], + ], ]); }); -it('can make gradient set from multiple sets of colors', function() { +it('can make gradient set from multiple sets of colors', function () { $generator = new SvgAvatarGenerator(); $generator->setGradientColors(['red', 'green', 'yellow'], 'blue') ->setGradientStops(0, .5, 1); @@ -25,18 +25,18 @@ [ ['color' => 'red', 'offset' => 0], ['color' => 'green', 'offset' => .5], - ['color' => 'yellow', 'offset' => 1] + ['color' => 'yellow', 'offset' => 1], ], [ ['color' => 'blue', 'offset' => 0], ['color' => 'blue', 'offset' => .5], - ['color' => 'blue', 'offset' => 1] - ] + ['color' => 'blue', 'offset' => 1], + ], ]); }); -it('will omit additional colors set more than offsets', function() { - $generator = new SvgAvatarGenerator(); +it('will omit additional colors set more than offsets', function () { + $generator = new SvgAvatarGenerator(); $generator->setGradientColors(['red', 'green', 'yellow']) ->setGradientStops(0, 1); @@ -44,12 +44,12 @@ [ ['color' => 'red', 'offset' => 0], ['color' => 'green', 'offset' => 1], // yellow after green is omitted - ] + ], ]); }); -it('will repeat last color if set fewer than offsets', function() { - $generator = new SvgAvatarGenerator(); +it('will repeat last color if set fewer than offsets', function () { + $generator = new SvgAvatarGenerator(); $generator->setGradientColors(['red', 'green'], 'blue') ->setGradientStops(0, .5, 1); @@ -63,6 +63,6 @@ ['color' => 'blue', 'offset' => 0], ['color' => 'blue', 'offset' => .5], // repeating blue ['color' => 'blue', 'offset' => 1], // repeating blue - ] + ], ]); }); From fcb4871ea77803dd6025f7e62cea9d1c6fd0fedd Mon Sep 17 00:00:00 2001 From: Sowren Sen <80112748+nemoitis@users.noreply.github.com> Date: Sun, 26 Feb 2023 13:07:50 +0600 Subject: [PATCH 07/14] shape tests --- tests/ShapeTest.php | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 tests/ShapeTest.php diff --git a/tests/ShapeTest.php b/tests/ShapeTest.php new file mode 100644 index 0000000..0f08aa5 --- /dev/null +++ b/tests/ShapeTest.php @@ -0,0 +1,26 @@ +asCircle()->render(); + + expect($generator->getShape()) + ->toBe(Shape::CIRCLE) + ->and($generator->getShape()->render()) + ->toContain('circle'); +}); + +it('will make a rectangular shaped svg', function() { + $generator = new SvgAvatarGenerator('Walter White'); + + $generator->asRectangle()->render(); + + expect($generator->getShape()) + ->toBe(Shape::RECTANGLE) + ->and($generator->getShape()->render()) + ->toContain('rectangle'); +}); From 8198e0c0e3d15c24c25c573c0118c6c0270e521c Mon Sep 17 00:00:00 2001 From: Sowren Sen <80112748+nemoitis@users.noreply.github.com> Date: Sun, 26 Feb 2023 13:35:38 +0600 Subject: [PATCH 08/14] shape tests --- config/svg-avatar.php | 8 +++---- .../InvalidGradientStopException.php | 12 ++++++++++ src/Http/Controllers/SvgController.php | 2 ++ src/SvgAvatarGenerator.php | 8 +++++++ tests/ExceptionTest.php | 23 ++++++++++++++----- 5 files changed, 43 insertions(+), 10 deletions(-) create mode 100644 src/Exceptions/InvalidGradientStopException.php diff --git a/config/svg-avatar.php b/config/svg-avatar.php index d381724..2f28766 100644 --- a/config/svg-avatar.php +++ b/config/svg-avatar.php @@ -102,10 +102,10 @@ | be consistent with gradient offsets. | | Type: array - | Default: ['#3A1C71', '#4F46E5', '#FDBB2D'] + | Default: ['#3A1C71', '#FDBB2D'] | */ - 'gradient_colors' => ['#3A1C71', '#4F46E5', '#FDBB2D'], + 'gradient_colors' => ['#3A1C71', '#FDBB2D'], /* |-------------------------------------------------------------------------- @@ -120,11 +120,11 @@ | will be repeated. | | Type: array - | Default: [0, .5, 1] + | Default: [0, 1] | Allowed: 0 to 1 | */ - 'gradient_stops' => [0, .5, 1], + 'gradient_stops' => [0, 1], /* |-------------------------------------------------------------------------- diff --git a/src/Exceptions/InvalidGradientStopException.php b/src/Exceptions/InvalidGradientStopException.php new file mode 100644 index 0000000..3d43df9 --- /dev/null +++ b/src/Exceptions/InvalidGradientStopException.php @@ -0,0 +1,12 @@ + 1) { + throw InvalidGradientStopException::create($offsets); + } + $this->gradientStops = $offsets; return $this; @@ -349,6 +356,7 @@ protected function setGradientSet(): static * @throws InvalidFontSizeException * @throws InvalidGradientRotationException * @throws InvalidSvgSizeException + * @throws InvalidGradientStopException */ protected function build(): void { diff --git a/tests/ExceptionTest.php b/tests/ExceptionTest.php index 104b7d1..b9a0747 100644 --- a/tests/ExceptionTest.php +++ b/tests/ExceptionTest.php @@ -1,37 +1,38 @@ 8]); new SvgAvatarGenerator('Rob Stark'); })->throws(InvalidSvgSizeException::class); -it('will throw exception if svg size larger than maximum is provided', function () { +it('will throw exception if svg size greater than maximum is provided', function () { config(['svg-avatar.size' => 1024]); new SvgAvatarGenerator('Jon Snow'); })->throws(InvalidSvgSizeException::class); -it('will throw exception if font size smaller than minimum is provided', function () { +it('will throw exception if font size less than minimum is provided', function () { config(['svg-avatar.font_size' => 9]); new SvgAvatarGenerator('Sansa Stark'); })->throws(InvalidFontSizeException::class); -it('will throw exception if font size larger than maximum is provided', function () { +it('will throw exception if font size greater than maximum is provided', function () { config(['svg-avatar.font_size' => 51]); new SvgAvatarGenerator('Arya Stark'); })->throws(InvalidFontSizeException::class); -it('will throw exception if gradient rotation smaller than minimum is provided', function () { +it('will throw exception if gradient rotation less than minimum is provided', function () { config(['svg-avatar.gradient_rotation' => -1]); new SvgAvatarGenerator('Brandon Stark'); })->throws(InvalidGradientRotationException::class); -it('will throw exception if gradient rotation larger than maximum is provided', function () { +it('will throw exception if gradient rotation greater than maximum is provided', function () { config(['svg-avatar.gradient_rotation' => 361]); new SvgAvatarGenerator('Rickon Stark'); })->throws(InvalidGradientRotationException::class); @@ -40,3 +41,13 @@ $generator = new SvgAvatarGenerator(); $generator->getInitials(); })->throws(MissingTextException::class); + +it('it will throw exception if gradient stop less than minimum is provided', function() { + config(['svg-avatar.gradient_stops' => [-1, 1]]); + new SvgAvatarGenerator('Lyanna Stark'); +})->throws(InvalidGradientStopException::class); + +it('it will throw exception if gradient stop greater than maximum is provided', function() { + config(['svg-avatar.gradient_stops' => [0, 2]]); + new SvgAvatarGenerator('Benjen Stark'); +})->throws(InvalidGradientStopException::class); From 481362c89e7101a63fbbc46c97dc4dcc2fabb9a4 Mon Sep 17 00:00:00 2001 From: sowrensen Date: Sun, 26 Feb 2023 07:36:26 +0000 Subject: [PATCH 09/14] Fix styling --- src/Exceptions/InvalidGradientStopException.php | 3 ++- src/Http/Controllers/SvgController.php | 2 +- src/SvgAvatarGenerator.php | 3 ++- tests/ExceptionTest.php | 6 +++--- tests/ShapeTest.php | 4 ++-- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Exceptions/InvalidGradientStopException.php b/src/Exceptions/InvalidGradientStopException.php index 3d43df9..888dd39 100644 --- a/src/Exceptions/InvalidGradientStopException.php +++ b/src/Exceptions/InvalidGradientStopException.php @@ -6,7 +6,8 @@ class InvalidGradientStopException extends \Exception { public static function create(array $offsets): InvalidGradientStopException { - $values = implode(',', $offsets); + $values = implode(',', $offsets); + return new self("Invalid value [{$values}] for gradient stop is provided. Gradient stops must be between 0 and 1."); } } diff --git a/src/Http/Controllers/SvgController.php b/src/Http/Controllers/SvgController.php index 85a1c00..5f1d52d 100644 --- a/src/Http/Controllers/SvgController.php +++ b/src/Http/Controllers/SvgController.php @@ -5,8 +5,8 @@ use Illuminate\Http\Request; use Illuminate\Http\Response; use Sowren\SvgAvatarGenerator\Exceptions\InvalidFontSizeException; -use Sowren\SvgAvatarGenerator\Exceptions\InvalidGradientStopException; use Sowren\SvgAvatarGenerator\Exceptions\InvalidGradientRotationException; +use Sowren\SvgAvatarGenerator\Exceptions\InvalidGradientStopException; use Sowren\SvgAvatarGenerator\Exceptions\InvalidSvgSizeException; use Sowren\SvgAvatarGenerator\Exceptions\MissingTextException; use Sowren\SvgAvatarGenerator\SvgAvatarGenerator; diff --git a/src/SvgAvatarGenerator.php b/src/SvgAvatarGenerator.php index 547355f..51e445b 100755 --- a/src/SvgAvatarGenerator.php +++ b/src/SvgAvatarGenerator.php @@ -6,8 +6,8 @@ use Sowren\SvgAvatarGenerator\Enums\FontWeight; use Sowren\SvgAvatarGenerator\Enums\Shape; use Sowren\SvgAvatarGenerator\Exceptions\InvalidFontSizeException; -use Sowren\SvgAvatarGenerator\Exceptions\InvalidGradientStopException; use Sowren\SvgAvatarGenerator\Exceptions\InvalidGradientRotationException; +use Sowren\SvgAvatarGenerator\Exceptions\InvalidGradientStopException; use Sowren\SvgAvatarGenerator\Exceptions\InvalidSvgSizeException; use Sowren\SvgAvatarGenerator\Exceptions\MissingTextException; @@ -314,6 +314,7 @@ public function getGradientStops(): array /** * Set stop positions of gradients. + * * @throws InvalidGradientStopException */ public function setGradientStops(int|float ...$offsets): static diff --git a/tests/ExceptionTest.php b/tests/ExceptionTest.php index b9a0747..2627053 100644 --- a/tests/ExceptionTest.php +++ b/tests/ExceptionTest.php @@ -1,8 +1,8 @@ getInitials(); })->throws(MissingTextException::class); -it('it will throw exception if gradient stop less than minimum is provided', function() { +it('it will throw exception if gradient stop less than minimum is provided', function () { config(['svg-avatar.gradient_stops' => [-1, 1]]); new SvgAvatarGenerator('Lyanna Stark'); })->throws(InvalidGradientStopException::class); -it('it will throw exception if gradient stop greater than maximum is provided', function() { +it('it will throw exception if gradient stop greater than maximum is provided', function () { config(['svg-avatar.gradient_stops' => [0, 2]]); new SvgAvatarGenerator('Benjen Stark'); })->throws(InvalidGradientStopException::class); diff --git a/tests/ShapeTest.php b/tests/ShapeTest.php index 0f08aa5..5232ee6 100644 --- a/tests/ShapeTest.php +++ b/tests/ShapeTest.php @@ -3,7 +3,7 @@ use Sowren\SvgAvatarGenerator\Enums\Shape; use Sowren\SvgAvatarGenerator\SvgAvatarGenerator; -it('will make a circular shaped svg', function() { +it('will make a circular shaped svg', function () { $generator = new SvgAvatarGenerator('Walter White'); $generator->asCircle()->render(); @@ -14,7 +14,7 @@ ->toContain('circle'); }); -it('will make a rectangular shaped svg', function() { +it('will make a rectangular shaped svg', function () { $generator = new SvgAvatarGenerator('Walter White'); $generator->asRectangle()->render(); From 2855726b232c40a1c4b5c877ce21d57f3c5ed7fa Mon Sep 17 00:00:00 2001 From: Sowren Sen <80112748+nemoitis@users.noreply.github.com> Date: Tue, 28 Feb 2023 15:31:24 +0600 Subject: [PATCH 10/14] updated changelog and readme --- CHANGELOG.md | 11 +++++++++++ README.md | 12 +++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eed8325..c2f00dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ All notable changes to `svg-avatar-generator` will be documented in this file. +## 1.1.0 + +- Support for setting multiple set of gradient colors. +- Random gradient generation from presets in config. +- `setGradientColors()` method on `SvgAvatarGenerator` class now accepts multiple integer/array arguments. +- Option to set gradient stops via `setGradientStops()` method. +- New `$gradientSet` attribute—with related getters and setters—which holds the randomly picked gradient set. +- Use blade templates to create SVG instead of PHP heredoc. +- New `render()` method on `Shape` enum class. +- Moved some helper methods to `Tool` trait. + ## 1.0.0 - Initial release diff --git a/README.md b/README.md index d3eb23d..fc0b62e 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,8 @@ Well, this package has some subtle advantages over available packages, here's a - [x] Unlike some other available options, doesn't require heavy-weight image processing libraries like **Intervention**. 🧺 - [x] Doesn't have any binary dependency, so nothing needs to be installed on server. 🗃️ -- [x] Support for gradient background. 🦜 +- [x] Supports gradient background. 🦜 +- [x] Supports random gradients based on presets. 🦚 - [x] Ability to customize initials. ✍🏼 ## Requirements @@ -83,8 +84,13 @@ Svg::for('John Doe') ->setSize(64) ->setFontSize(40) ->setFontWeight(FontWeight::SEMIBOLD) - ->setForeground('#E6C6A3') - ->setGradientColors('#3A1C71', '#FDBB2D') + ->setForeground('#FFFFFF') + ->setGradientColors( // set of 3 different gradients + ['#4158D0', '#C850C0', '#FFCC70'], + ['#00DBDE', '#FC00FF'], + ['#FF9A8B', '#FF6A88', '#FF99AC'] + ) + ->setGradientStops(0, .5, 1) ->setGradientRotation(120) ->render(); ``` From e5f35a32919b822c713bf3a949dc776a3978fcdb Mon Sep 17 00:00:00 2001 From: Sowren Sen <80112748+nemoitis@users.noreply.github.com> Date: Tue, 28 Feb 2023 15:33:54 +0600 Subject: [PATCH 11/14] wip --- CHANGELOG.md | 4 ++-- README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2f00dd..5c0e271 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,8 @@ All notable changes to `svg-avatar-generator` will be documented in this file. ## 1.1.0 -- Support for setting multiple set of gradient colors. -- Random gradient generation from presets in config. +- Support for setting multiple sets of gradient colors. +- Random gradient generation from defined presets in config. - `setGradientColors()` method on `SvgAvatarGenerator` class now accepts multiple integer/array arguments. - Option to set gradient stops via `setGradientStops()` method. - New `$gradientSet` attribute—with related getters and setters—which holds the randomly picked gradient set. diff --git a/README.md b/README.md index fc0b62e..6127e10 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Well, this package has some subtle advantages over available packages, here's a 🧺 - [x] Doesn't have any binary dependency, so nothing needs to be installed on server. 🗃️ - [x] Supports gradient background. 🦜 -- [x] Supports random gradients based on presets. 🦚 +- [x] Supports random gradients based on defined presets in config. 🦚 - [x] Ability to customize initials. ✍🏼 ## Requirements From 54be806c4951743a6e57792a80f7f6a6037abdd2 Mon Sep 17 00:00:00 2001 From: Sowren Sen <80112748+nemoitis@users.noreply.github.com> Date: Tue, 28 Feb 2023 15:35:31 +0600 Subject: [PATCH 12/14] moved Tool into Concerns directory --- src/{ => Concerns}/Tool.php | 4 ++-- src/SvgAvatarGenerator.php | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) rename src/{ => Concerns}/Tool.php (98%) diff --git a/src/Tool.php b/src/Concerns/Tool.php similarity index 98% rename from src/Tool.php rename to src/Concerns/Tool.php index 7f0c2f0..e25de42 100644 --- a/src/Tool.php +++ b/src/Concerns/Tool.php @@ -1,11 +1,11 @@ Date: Tue, 28 Feb 2023 09:35:58 +0000 Subject: [PATCH 13/14] Fix styling --- src/Concerns/Tool.php | 2 +- src/SvgAvatarGenerator.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Concerns/Tool.php b/src/Concerns/Tool.php index e25de42..295bca9 100644 --- a/src/Concerns/Tool.php +++ b/src/Concerns/Tool.php @@ -3,9 +3,9 @@ namespace Sowren\SvgAvatarGenerator\Concerns; use Arr; -use Str; use Exception; use Sowren\SvgAvatarGenerator\Exceptions\MissingTextException; +use Str; trait Tool { diff --git a/src/SvgAvatarGenerator.php b/src/SvgAvatarGenerator.php index 317d642..556b716 100755 --- a/src/SvgAvatarGenerator.php +++ b/src/SvgAvatarGenerator.php @@ -3,14 +3,14 @@ namespace Sowren\SvgAvatarGenerator; use Arr; -use Sowren\SvgAvatarGenerator\Enums\Shape; use Sowren\SvgAvatarGenerator\Concerns\Tool; use Sowren\SvgAvatarGenerator\Enums\FontWeight; -use Sowren\SvgAvatarGenerator\Exceptions\MissingTextException; -use Sowren\SvgAvatarGenerator\Exceptions\InvalidSvgSizeException; +use Sowren\SvgAvatarGenerator\Enums\Shape; use Sowren\SvgAvatarGenerator\Exceptions\InvalidFontSizeException; -use Sowren\SvgAvatarGenerator\Exceptions\InvalidGradientStopException; use Sowren\SvgAvatarGenerator\Exceptions\InvalidGradientRotationException; +use Sowren\SvgAvatarGenerator\Exceptions\InvalidGradientStopException; +use Sowren\SvgAvatarGenerator\Exceptions\InvalidSvgSizeException; +use Sowren\SvgAvatarGenerator\Exceptions\MissingTextException; class SvgAvatarGenerator { From e04f03d35fcbbb76e8641ae0d35fa32d79f1eb41 Mon Sep 17 00:00:00 2001 From: Sowren Sen <13097375+sowrensen@users.noreply.github.com> Date: Tue, 28 Feb 2023 20:17:17 +0600 Subject: [PATCH 14/14] Update README.md updated readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6127e10..34c4606 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,7 @@ You can define the second initial using studly case. For example, ## Sample Output - + ## Testing