From 6bb06317e4a439157bac128ee8873038e3877c96 Mon Sep 17 00:00:00 2001 From: erics118 <52634785+erics118@users.noreply.github.com> Date: Sun, 17 Sep 2023 00:09:52 -0400 Subject: [PATCH] feat: better docs/examples and color support --- .../paintingcanvas/animation/Animatable.java | 173 +++++++++++------ .../paintingcanvas/animation/Animation.java | 159 ++++++++++++---- .../animation/AnimationBuilder.java | 18 +- .../java/paintingcanvas/animation/Easing.java | 53 +++++- .../animation/OpacityAnimation.java | 1 - .../java/paintingcanvas/canvas/Canvas.java | 16 +- .../paintingcanvas/canvas/CanvasPanel.java | 4 +- .../java/paintingcanvas/drawable/Circle.java | 11 +- .../paintingcanvas/drawable/Drawable.java | 179 +++++++++--------- .../java/paintingcanvas/drawable/Ellipse.java | 8 +- .../java/paintingcanvas/drawable/Line.java | 60 +++--- .../java/paintingcanvas/drawable/Path.java | 8 +- .../paintingcanvas/drawable/Rectangle.java | 9 +- .../java/paintingcanvas/drawable/Square.java | 9 +- .../java/paintingcanvas/drawable/Text.java | 9 +- .../paintingcanvas/drawable/Triangle.java | 8 +- src/main/java/paintingcanvas/misc/Misc.java | 24 +++ 17 files changed, 484 insertions(+), 265 deletions(-) diff --git a/src/main/java/paintingcanvas/animation/Animatable.java b/src/main/java/paintingcanvas/animation/Animatable.java index 2095430..3836745 100644 --- a/src/main/java/paintingcanvas/animation/Animatable.java +++ b/src/main/java/paintingcanvas/animation/Animatable.java @@ -1,6 +1,7 @@ package paintingcanvas.animation; import paintingcanvas.drawable.Drawable; +import paintingcanvas.misc.Hue; import java.awt.*; @@ -25,14 +26,14 @@ private AnimationBuilder addAnimation(Animation animation, double duration) { * *
{@code
      * Circle c = new Circle(200, 200, 50);
-     * // the circle will move to (100, 100), and then to (200, 200)
-     * c.moveTo(100, 100, 3).moveTo(200, 200, 3);
+     * // the circle will slowly move to (100, 100) over 3 seconds
+     * c.moveTo(100, 100, 3);
      * }
* - * @param x the x-position to move to - * @param y the y-position to move to + * @param x the x position to move to + * @param y the y position to move to * @param duration the number of seconds it lasts - * @return an {@code this} + * @return an {@link AnimationBuilder} */ default AnimationBuilder moveTo(int x, int y, double duration) { return this.addAnimation(Animation.moveTo(x, y), duration); @@ -44,15 +45,15 @@ default AnimationBuilder moveTo(int x, int y, double duration) { * *
{@code
      * Circle c = new Circle(200, 200, 50);
-     * // the circle will turn red, and then blue
-     * c.colorTo(255, 0, 0, 3).colorTo(0, 0, 255, 3);
+     * // the circle will slowly turn red over 3 seconds
+     * c.colorTo(255, 0, 0, 3);
      * }
* * @param r red (0-255) * @param g green (0-255) * @param b blue (0-255) * @param duration the number of seconds it lasts - * @return an {@code this} + * @return an {@link AnimationBuilder} */ default AnimationBuilder colorTo(int r, int g, int b, double duration) { return this.addAnimation(Animation.colorTo(r, g, b), duration); @@ -60,18 +61,38 @@ default AnimationBuilder colorTo(int r, int g, int b, double duration) { /** * Change the color of {@code this} to the specified {@code color} over {@code duration} seconds. - * See Wikipedia - * for how this works. + * See Wikipedia for how this works. * *
{@code
      * Circle c = new Circle(200, 200, 50);
-     * // the circle will turn red, and then blue
-     * c.colorTo(0xFF0000, 3).colorTo(0x0000FF, 3);
+     * // the circle will slowly turn red with with 100/255 opacity over three seconds
+     * c.colorTo(255, 0, 0, 100, 3);
      * }
* - * @param hex The number describing the RGB color + * @param r red (0-255) + * @param g green (0-255) + * @param b blue (0-255) + * @param a alpha (0-255) * @param duration the number of seconds it lasts - * @return an {@code this} + * @return an {@link AnimationBuilder} + */ + default AnimationBuilder colorTo(int r, int g, int b, int a, double duration) { + return this.addAnimation(Animation.colorTo(r, g, b, a), duration); + } + + /** + * Change the color of {@code this} to the specified {@code color} over {@code duration} seconds. + * See Wikipedia for how this works. + * + *
{@code
+     * Circle c = new Circle(200, 200, 50);
+     * // the circle will slowly turn red over three seconds
+     * c.colorTo(0xFF0000, 3);
+     * }
+ * + * @param hex the number describing the RGB color + * @param duration the number of seconds it lasts + * @return an {@link AnimationBuilder} */ default AnimationBuilder colorTo(int hex, double duration) { return this.addAnimation(Animation.colorTo(hex), duration); @@ -79,150 +100,182 @@ default AnimationBuilder colorTo(int hex, double duration) { /** * Change the color of {@code this} to the specified {@code color} over {@code duration} seconds. - * See {@link Color} - * for the full list of colors, and constructors for this class * *
{@code
      * Circle c = new Circle(200, 200, 50);
-     * // the circle will turn red, and then blue
-     * c.colorTo(Color.RED, 3).colorTo(Color.BLUE, 3);
+     * // the circle will slowly turn red over 3 seconds
+     * c.colorTo(0xFF0000, 3);
+     * }
+ * + * @param hue the hue + * @param duration the number of seconds it lasts + * @return a {@link ColorAnimation} + */ + default AnimationBuilder colorTo(Hue hue, double duration) { + return this.addAnimation(Animation.colorTo(hue), duration); + } + + /** + * Change the color of {@code this} to the specified {@code color} over {@code duration} seconds. + * + *
{@code
+     * Circle c = new Circle(200, 200, 50);
+     * // the circle will slowly turn red over 3 seconds
+     * // then, the circle will slowly turn blue over 3 seconds
+     * c.colorTo("red", 3).colorTo("#0000FF", 3);
+     * }
+ * + * @param name the hue name or the hex code + * @param duration the number of seconds it lasts + * @return an {@link AnimationBuilder} + */ + default AnimationBuilder colorTo(String name, double duration) { + return this.addAnimation(Animation.colorTo(name), duration); + } + + /** + * Change the color of {@code this} to the specified {@code color} over {@code duration} seconds. + * See {@link Color} for the full list of colors, and constructors for this class + * + *
{@code
+     * Circle c = new Circle(200, 200, 50);
+     * // the circle will turn slowly red over 3 seconds
+     * c.colorTo(Color.RED, 3);
      * }
* - * @param color The color to fade to + * @param color the color to fade to * @param duration the number of seconds it lasts - * @return an {@code this} + * @return an {@link AnimationBuilder} */ default AnimationBuilder colorTo(Color color, double duration) { return this.addAnimation(Animation.colorTo(color), duration); } /** - * Fades {@code this} out over @{code duration} seconds. + * Fade {@code this} out over {@code duration} seconds. * *
{@code
      * Circle c = new Circle(200, 200, 50);
-     * // the circle will fade out, then in
-     * c.fadeOut(3).fadeIn(3);
+     * // the circle will slowly fade out over 3 seconds
+     * c.fadeOut(3);
      * }
* - * @param duration the amount of time it takes to fade out - * @return an {@code this} - * @see #fadeIn(double) + * @param duration the number of seconds it lasts + * @return an {@link AnimationBuilder} */ default AnimationBuilder fadeOut(double duration) { return this.addAnimation(Animation.fadeOut(), duration); } /** - * Fades {@code this} in over @{code duration} seconds. + * Fade {@code this} in over {@code duration} seconds. * *
{@code
      * Circle c = new Circle(200, 200, 50);
-     * // the circle will fade out, then in
+     * // the circle will slowly fade out over 3 seconds
+     * // then, fade back in over 3 seconds
      * c.fadeOut(3).fadeIn(3);
      * }
* - * @param duration the amount of time it takes to fade out - * @return an {@code this} - * @see #fadeOut(double) + * @param duration the number of seconds it lasts + * @return an {@link AnimationBuilder} */ default AnimationBuilder fadeIn(double duration) { return this.addAnimation(Animation.fadeIn(), duration); } /** - * Rotates {@code this} to the specified angle°. + * Rotate {@code this} to the specified {@code angle} degrees over {@code duration} seconds. * If you supply an angle {@code > 360} it will make more than one full rotation. * *
{@code
      * Square s = new Square(200, 200, 50);
-     * // the square will rotate one turn counter-clockwise, then 2 turns clockwise
-     * c.rotateTo(360, 3).colorTo(-360, 3);
+     * // the square will slowly rotate one turn counter-clockwise over 3 seconds
+     * // then, slowly rotate two turns clockwise over 3 seconds
+     * c.rotateTo(360, 3).rotateTo(-360, 3);
      * }
* - * @param angle The absolute angle to rotate to in degrees. + * @param angle the absolute angle to rotate to in degrees. * @param duration the number of seconds it lasts - * @return an {@code this} + * @return an {@link AnimationBuilder} */ default AnimationBuilder rotateTo(int angle, double duration) { return this.addAnimation(Animation.rotateTo(angle), duration); } /** - * Rotates {@code this} by angle°. + * Rotate {@code this} by {@code angle} degrees over {@code duration} seconds. + * If you supply an angle {@code > 360} it will make more than one full rotation. * *
{@code
      * Square s = new Square(200, 200, 50);
-     * // the square will rotate one turn counter-clockwise, then one turns clockwise
-     * c.rotateTo(360, 3).colorTo(-360, 3);
+     * // the square will slowly rotate one turn counter-clockwise over 3 seconds
+     * // then, slowly rotate one turn clockwise over 3 seconds
+     * c.rotateBy(360, 3).rotateBy(-360, 3);
      * }
* - * @param angle The relative angle to rotate to in degrees. + * @param angle the relative angle to rotate to in degrees. * @param duration the number of seconds it lasts - * @return an {@code this} + * @return an {@link AnimationBuilder} */ default AnimationBuilder rotateBy(int angle, double duration) { return this.addAnimation(Animation.rotateBy(angle), duration); } /** - * This method moves {@code this} by the specified {@code x} and {@code y} + * Move {@code this} by the specified {@code x} and {@code y} over {@code duration} seconds. * *
{@code
      * Circle c = new Circle(200, 200, 50);
-     * // the circle will move down 100, and then right 200
+     * // the circle will slowly move down 100 over 3 seconds
+     * // then, slowly move right over 3 seconds
      * c.moveBy(0, 100, 3).moveBy(200, 0, 3);
      * }
* * @param x the x to move by * @param y the y to move by * @param duration the number of seconds it lasts - * @return an {@code this} + * @return an {@link AnimationBuilder} */ default AnimationBuilder moveBy(int x, int y, double duration) { return this.addAnimation(Animation.moveBy(x, y), duration); } /** - *

- * This method moves {@code this} by the specified {@code x} horizontally. + * Move {@code this} by the specified {@code x} horizontally over {@code duration} seconds. * Positive values move right, negative values move left. - *

* This method is equivalent to {@code moveBy(x, 0, duration)} - *

* *
{@code
      * Circle c = new Circle(200, 200, 50);
-     * // the circle will move right 300 pixels over 3 seconds
-     * c.moveHorizontalBy(0, 100, 3);
+     * // the circle will move slowly right 300 pixels over 3 seconds
+     * c.moveHorizontalBy(100, 3);
      * }
* * @param x the x to move by * @param duration the number of seconds it lasts - * @return an {@code this} + * @return an {@link AnimationBuilder} */ default AnimationBuilder moveHorizontalBy(int x, double duration) { - return this.addAnimation(Animation.moveBy(x, 0).relative(), duration); + return this.addAnimation(Animation.moveHorizontalBy(x), duration); } /** - *

- * This method moves {@code this} by the specified {@code x} horizontally. - * Positive values move right, negative values move left. - *

+ * Move {@code this} by the specified {@code y} vertically over {@code duration} seconds. + * Positive values move down, negative values move up. * This method is equivalent to {@code moveBy(0, y, duration)} - *

+ * *
{@code
      * Circle c = new Circle(200, 200, 50);
      * // the circle will move right 300 pixels over 3 seconds
-     * c.moveHorizontalBy(0, 100, 3);
+     * c.moveVerticalBy(100, 3);
      * }
* * @param y the y to move by * @param duration the number of seconds it lasts - * @return an {@code this} + * @return an {@link AnimationBuilder} */ default AnimationBuilder moveVerticalBy(int y, double duration) { - return this.addAnimation(Animation.moveBy(0, y).relative(), duration); + return this.addAnimation(Animation.moveVerticalBy(y), duration); } } diff --git a/src/main/java/paintingcanvas/animation/Animation.java b/src/main/java/paintingcanvas/animation/Animation.java index 95ed951..3eeb053 100644 --- a/src/main/java/paintingcanvas/animation/Animation.java +++ b/src/main/java/paintingcanvas/animation/Animation.java @@ -1,6 +1,8 @@ package paintingcanvas.animation; import paintingcanvas.drawable.Drawable; +import paintingcanvas.misc.Hue; +import paintingcanvas.misc.Misc; import java.awt.*; @@ -35,17 +37,16 @@ protected Animation() { } /** - * Creates an animation that moves {@code this} to the specified {@code x} and {@code y} - * over {@code duration} seconds + * Create an animation that moves {@code this} to the specified {@code x} and {@code y} * *
{@code
      * Circle c = new Circle(200, 200, 50);
-     * // the circle will move to (100, 100), and then to (200, 200)
-     * c.moveTo(100, 100, 3).moveTo(200, 200, 3);
+     * // the circle will slowly move to (100, 100) over 3 seconds
+     * c.animate().add(Animation.moveTo(100, 100), 3);
      * }
* - * @param x the x-position to move to - * @param y the y-position to move to + * @param x the x position to move to + * @param y the y position to move to * @return a {@link MovementAnimation} */ public static MovementAnimation moveTo(int x, int y) { @@ -53,13 +54,13 @@ public static MovementAnimation moveTo(int x, int y) { } /** - * Creates an animation that changes the color of {@code this} to the specified {@code color} over {@code duration} seconds. + * Create an animation that changes the color of {@code this} to the specified {@code color}. * See Wikipedia for how this works. * *
{@code
      * Circle c = new Circle(200, 200, 50);
-     * // the circle will turn red, and then blue
-     * c.colorTo(255, 0, 0, 3).colorTo(0, 0, 255, 3);
+     * // the circle will slowly turn red over 3 seconds
+     * c.animate().add(Animation.colorTo(255, 0, 0), 3);
      * }
* * @param r red (0-255) @@ -72,16 +73,36 @@ public static ColorAnimation colorTo(int r, int g, int b) { } /** - * Creates an animation that changes the color of {@code this} to the specified {@code color} over {@code duration} seconds. + * Create an animation that changes the color of {@code this} to the specified {@code color}. + * See Wikipedia for how this works. + * + *
{@code
+     * Circle c = new Circle(200, 200, 50);
+     * // the circle will slowly turn red with with 100/255 opacity over three seconds
+     * c.animate().add(Animation.colorTo(255, 0, 0), 3);
+     * }
+ * + * @param r red (0-255) + * @param g green (0-255) + * @param b blue (0-255) + * @param a alpha (0-255) + * @return a {@link ColorAnimation} + */ + public static ColorAnimation colorTo(int r, int g, int b, int a) { + return new ColorAnimation(new Color(r, g, b, a)); + } + + /** + * Create an animation that changes the color of {@code this} to the specified {@code color}. * See Wikipedia for how this works. * *
{@code
      * Circle c = new Circle(200, 200, 50);
-     * // the circle will turn red, and then blue
-     * c.colorTo(0xFF0000, 3).colorTo(0x0000FF, 3);
+     * // the circle will slowly turn red over three seconds
+     * c.animate().add(Animation.colorTo(0xFF0000), 3);
      * }
* - * @param hex The number describing the RGB color + * @param hex the number describing the RGB color * @return a {@link ColorAnimation} */ public static ColorAnimation colorTo(int hex) { @@ -89,17 +110,49 @@ public static ColorAnimation colorTo(int hex) { } /** - * Creates an animation that changes the color of {@code this} to the specified {@code color} over {@code duration} seconds. - * See {@link Color} - * for the full list of colors, and constructors for this class + * Create an animation that changes the color of {@code this} to the specified {@code color}. * *
{@code
      * Circle c = new Circle(200, 200, 50);
      * // the circle will turn red, and then blue
-     * c.colorTo(Color.RED, 3).colorTo(Color.BLUE, 3);
+     * c.colorTo(0xFF0000, 3).colorTo(0x0000FF, 3);
+     * }
+ * + * @param hue the hue + * @return a {@link ColorAnimation} + */ + public static ColorAnimation colorTo(Hue hue) { + return new ColorAnimation(hue.getColor()); + } + + /** + * Create an animation that changes the color of {@code this} to the specified {@code color}. + * + *
{@code
+     * Circle c = new Circle(200, 200, 50);
+     * // the circle will slowly turn red over 3 seconds
+     * // then, the circle will slowly turn blue over 3 seconds
+     * c.animate().add(Animation.colorTo("red"), 3).add(Animation.colorTo("#0000FF"), 3);
      * }
* - * @param color The color to fade to + * @param name the hue name or the hex code + * @return a {@link ColorAnimation} + */ + public static ColorAnimation colorTo(String name) { + return new ColorAnimation(Misc.stringToColor(name)); + } + + /** + * Create an animation that changes the color of {@code this} to the specified {@code color}. + * See {@link Color} for the full list of colors, and constructors for this class + * + *
{@code
+     * Circle c = new Circle(200, 200, 50);
+     * // the circle will turn slowly red over 3 seconds
+     * c.animate().add(Animation.colorTo(Color.RED, 3));
+     * }
+ * + * @param color the color to fade to * @return an {@link Animation} */ public static Animation colorTo(Color color) { @@ -107,12 +160,12 @@ public static Animation colorTo(Color color) { } /** - * Creates an animation that fades {@code this} out over @{code duration} seconds. + * Create an animation that fades {@code this} out. * *
{@code
      * Circle c = new Circle(200, 200, 50);
-     * // the circle will fade out, then in
-     * c.fadeOut(3).fadeIn(3);
+     * // the circle will slowly fade out over 3 seconds
+     * c.animate().add(Animation.fadeOut(), 3);
      * }
* * @return an {@link OpacityAnimation} @@ -123,12 +176,13 @@ public static OpacityAnimation fadeOut() { } /** - * Creates an animation that fades {@code this} in over @{code duration} seconds. + * Create an animation that fades {@code this} in. * *
{@code
      * Circle c = new Circle(200, 200, 50);
-     * // the circle will fade out, then in
-     * c.fadeOut(3).fadeIn(3);
+     * // the circle will slowly fade out over 3 seconds
+     * // then, fade back in over 3 seconds
+     * c.animate().add(Animation.fadeOut(), 3).add(Animation.fadeIn(), 3);
      * }
* * @return an {@link OpacityAnimation} @@ -139,13 +193,14 @@ public static OpacityAnimation fadeIn() { } /** - * Creates an animation that rotates {@code this} to the specified angle°. + * Create an animation that rotates {@code this} to the specified {@code angle} degrees. * If you supply an angle {@code > 360} it will make more than one full rotation. * *
{@code
      * Square s = new Square(200, 200, 50);
-     * // the square will rotate one turn counter-clockwise, then 2 turns clockwise
-     * c.rotateTo(360, 3).colorTo(-360, 3);
+     * // the square will slowly rotate one turn counter-clockwise over 3 seconds
+     * // then, slowly rotate two turns clockwise over 3 seconds
+     * c.animate().add(Animation.rotateTo(360), 3).add(Animation.rotateTo(-360), 3);
      * }
* * @param angle The absolute angle to rotate to in degrees. @@ -156,12 +211,13 @@ public static RotationAnimation rotateTo(int angle) { } /** - * Creates an animation that rotates {@code this} by angle°. + * Create an animation that rotates {@code this} by {@code angle} degrees. * *
{@code
      * Square s = new Square(200, 200, 50);
-     * // the square will rotate one turn counter-clockwise, then one turns clockwise
-     * c.rotateTo(360, 3).colorTo(-360, 3);
+     * // the square will slowly rotate one turn counter-clockwise over 3 seconds
+     * // then, slowly rotate one turn clockwise over 3 seconds
+     * c.animate().add(Animation.rotateBy(360), 3).add(Animation.rotateBy(-360), 3);
      * }
* * @param angle The relative angle to rotate to in degrees. @@ -172,12 +228,13 @@ public static RotationAnimation rotateBy(int angle) { } /** - * Creates an animation that moves {@code this} by the specified {@code x} and {@code y} + * Create an animation that moves {@code this} by the specified {@code x} and {@code y} * *
{@code
      * Circle c = new Circle(200, 200, 50);
-     * // the circle will move down 100, and then right 200
-     * c.moveTo(0, 100, 3).moveTo(200, 0, 3);
+     * // the circle will slowly move down 100 over 3 seconds
+     * // then, slowly move right over 3 seconds
+     * c.animate().add(Animation.moveTo(0, 100), 3).add(Animation.moveTo(200, 0), 3);
      * }
* * @param x the x to move by @@ -188,6 +245,42 @@ public static MovementAnimation moveBy(int x, int y) { return new MovementAnimation(new Point(x, y)).relative(); } + /** + * Create an animation that moves {@code this} by the specified {@code x} horizontally. + * Positive values move right, negative values move left. + * This method is equivalent to {@code moveBy(x, 0)} + * + *
{@code
+     * Circle c = new Circle(200, 200, 50);
+     * // the circle will move slowly right 300 pixels over 3 seconds
+     * c.animate().add(Animation.moveHorizontalBy(100), 3);
+     * }
+ * + * @param x the x to move by + * @return an {@link AnimationBuilder} + */ + public static MovementAnimation moveHorizontalBy(int x) { + return new MovementAnimation(new Point(x, 0)).relative(); + } + + /** + * Create an animation that moves {@code this} by the specified {@code y} vertically. + * Positive values move down, negative values move up. + * This method is equivalent to {@code moveBy(0, y)} + * + *
{@code
+     * Circle c = new Circle(200, 200, 50);
+     * // the circle will move right 300 pixels over 3 seconds
+     * c.animate().add(Animation.moveVerticalBy(100), 3);
+     * }
+ * + * @param y the y to move by + * @return an {@link AnimationBuilder} + */ + public static MovementAnimation moveVerticalBy(int y) { + return new MovementAnimation(new Point(0, y)).relative(); + } + /** * Internal method that is called to help copy this object */ diff --git a/src/main/java/paintingcanvas/animation/AnimationBuilder.java b/src/main/java/paintingcanvas/animation/AnimationBuilder.java index 80941be..a55641b 100644 --- a/src/main/java/paintingcanvas/animation/AnimationBuilder.java +++ b/src/main/java/paintingcanvas/animation/AnimationBuilder.java @@ -23,7 +23,7 @@ public AnimationBuilder(Drawable drawable) { } /** - * Add a new animation to the element. + * Add a new animation to the element and wait for it to finish. *
{@code
      * // these animations will run one after the other
      * obj.animate()
@@ -31,9 +31,9 @@ public AnimationBuilder(Drawable drawable) {
      *    .add(Animation.colorTo(Color.BLUE), 100, TimeUnit.Frames);
      * }
* - * @param animation The animation type to add - * @param duration The amount of time the animation will last - * @param unit The unit of time used for {@code duration} + * @param animation the animation type to add + * @param duration the amount of time the animation will last + * @param unit the unit of time used for {@code duration} * @return this to allow method chaining */ public AnimationBuilder add(Animation animation, double duration, TimeUnit unit) { @@ -69,12 +69,12 @@ public AnimationBuilder add(Animation animation, double duration) { } /** - * Add the animation alongside / with the previous animation. + * Add the animation to run at the same time as the previous animation, without waiting for it to finish. *
{@code
      * // these animations will run at the same time
      * obj.animate()
-     *    .add(Animation.moveTo(100, 100), 100, TimeUnit.Frames)
-     *    .add(Animation.colorTo(Color.BLUE), 100, TimeUnit.Frames);
+     *    .with(Animation.moveTo(100, 100), 100, TimeUnit.Frames)
+     *    .with(Animation.colorTo(Color.BLUE), 100, TimeUnit.Frames);
      * }
* * @param animation The animation type to add @@ -95,11 +95,11 @@ public AnimationBuilder with(Animation animation, double duration, TimeUnit unit } /** - * Add the animation alongside / with the previous animation. + * Add the animation to run at the same time as the previous animation, without waiting for it to finish. *
{@code
      * // these animations will run at the same time
      * obj.animate()
-     *    .add(Animation.moveTo(100, 100), 10)
+     *    .with(Animation.moveTo(100, 100), 10)
      *    .with(Animation.colorTo(Color.BLUE), 10);
      * }
* diff --git a/src/main/java/paintingcanvas/animation/Easing.java b/src/main/java/paintingcanvas/animation/Easing.java index c1de9f8..d24aa4a 100644 --- a/src/main/java/paintingcanvas/animation/Easing.java +++ b/src/main/java/paintingcanvas/animation/Easing.java @@ -12,7 +12,7 @@ */ public interface Easing { /** - * Linear easing: A.K.A no easing. + * Linear easing, aka no easing. * * @return an {@code Easing} object representing this easing. */ @@ -21,7 +21,7 @@ static Easing linear() { } /** - * easeIn: Start out slow then accelerate up + * Ease in * * @param n the degree * @return an {@code Easing} object representing this easing. @@ -31,7 +31,7 @@ static Easing easeIn(double n) { } /** - * easeOut: Start out fast then Slow down + * Ease out * * @param n the degree * @return an {@code Easing} object representing this easing. @@ -41,7 +41,7 @@ static Easing easeOut(double n) { } /** - * easeInOut: Accelerate up then slow down + * Exponentially ease in and out * * @param n the degree * @return an {@code Easing} object representing this easing. @@ -53,26 +53,56 @@ static Easing easeInOut(double n) { }; } + /** + * Ease in sinusoidally + * + * @return an {@code Easing} object representing this easing. + */ static Easing easeInSine() { return t -> 1 - Math.cos((t * Math.PI) / 2); } + /** + * Ease out sinusoidally + * + * @return an {@code Easing} object representing this easing. + */ static Easing easeOutSine() { return t -> Math.sin((t * Math.PI) / 2); } + /** + * Ease in and out sinusoidally + * + * @return an {@code Easing} object representing this easing. + */ static Easing easeInOutSine() { return t -> -(Math.cos(Math.PI * t) - 1) / 2; } + /** + * Ease in quadratically + * + * @return an {@code Easing} object representing this easing. + */ static Easing easeInQuad() { return t -> t * t; } + /** + * Ease out quadratically + * + * @return an {@code Easing} object representing this easing. + */ static Easing easeOutQuad() { return t -> 1 - (1 - t) * (1 - t); } + /** + * Ease in and out quadratically + * + * @return an {@code Easing} object representing this easing. + */ static Easing easeInOutQuad() { return t -> { if (t < 0.5) return 2 * t * t; @@ -80,14 +110,29 @@ static Easing easeInOutQuad() { }; } + /** + * Ease in cubically + * + * @return an {@code Easing} object representing this easing. + */ static Easing easeInCubic() { return t -> t * t * t; } + /** + * Ease out cubically + * + * @return an {@code Easing} object representing this easing. + */ static Easing easeOutCubic() { return t -> 1 - Math.pow(1 - t, 3); } + /** + * Ease in and out cubically + * + * @return an {@code Easing} object representing this easing. + */ static Easing easeInOutCubic() { return t -> { if (t < 0.5) return 4 * t * t * t; diff --git a/src/main/java/paintingcanvas/animation/OpacityAnimation.java b/src/main/java/paintingcanvas/animation/OpacityAnimation.java index ff0caae..bae2d47 100644 --- a/src/main/java/paintingcanvas/animation/OpacityAnimation.java +++ b/src/main/java/paintingcanvas/animation/OpacityAnimation.java @@ -37,7 +37,6 @@ protected void updateAnimation(Drawable> drawable, double Color color = drawable.getColor(); int alpha = Misc.clamp(0, (int) (start + (end - start) * t), 255); -// System.err.println(end); drawable.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha)); Color outlineColor = drawable.getOutlineColor(); diff --git a/src/main/java/paintingcanvas/canvas/Canvas.java b/src/main/java/paintingcanvas/canvas/Canvas.java index 23e68db..14c4de8 100644 --- a/src/main/java/paintingcanvas/canvas/Canvas.java +++ b/src/main/java/paintingcanvas/canvas/Canvas.java @@ -15,21 +15,21 @@ */ public class Canvas { /** - * the fps of the canvas + * The FPS of the canvas */ public static final int fps = 30; public static Canvas globalInstance; /** - * the initial size of the Canvas + * The initial size of the Canvas */ public final Dimension startSize; public final Point2D.Float translation; /** - * the elements that are currently on the canvas + * The elements that are currently on the canvas */ public final List> elements = new Vector<>(); /** - * the list of animations that are currently running + * The list of animations that are currently running */ public final List animations = new Vector<>(); /** @@ -70,7 +70,7 @@ public Canvas() { } /** - * Initializes the canvas + * Initialize the canvas * * @param width the width of the canvas * @param height the height of the canvas @@ -81,7 +81,7 @@ public Canvas(int width, int height, String title) { } /** - * Initializes the canvas + * Initialize the canvas with more options * * @param width the width of the canvas * @param height the height of the canvas @@ -189,7 +189,7 @@ public void sleep() { * @param seconds The number of seconds to sleep for */ public void sleep(double seconds) { - // if the time is short: just thread.sleep + // if the time is short, just Thread.sleep if (seconds < 0.1) { try { Thread.sleep((long) (seconds * 1000)); @@ -197,7 +197,7 @@ public void sleep(double seconds) { throw new RuntimeException(e); } } - // otherwise wait for the frame count to reach the specified frame + // otherwise, wait for the frame count to reach the specified frame else { int targetFrame = frame + (int) (seconds * fps); synchronized (frameSync) { diff --git a/src/main/java/paintingcanvas/canvas/CanvasPanel.java b/src/main/java/paintingcanvas/canvas/CanvasPanel.java index f6f6c3d..d235fe2 100644 --- a/src/main/java/paintingcanvas/canvas/CanvasPanel.java +++ b/src/main/java/paintingcanvas/canvas/CanvasPanel.java @@ -28,7 +28,6 @@ public class CanvasPanel extends JPanel { jframe = new JFrame(); jframe.setTitle(title); -// jframe.setLayout(null); jframe.add(this); jframe.pack(); jframe.setLocationRelativeTo(null); @@ -71,7 +70,7 @@ public void paintComponent(Graphics g) { i--; // unblock if no more animations - if (canvas.animations.size() != 0) continue; + if (!canvas.animations.isEmpty()) continue; synchronized (canvas.animationSync) { canvas.animationSync.notifyAll(); } @@ -85,7 +84,6 @@ public void paintComponent(Graphics g) { ig.setColor(canvas.options.backgroundColor); ig.fillRect(0, 0, getWidth(), getHeight()); synchronized (canvas.translation) { -// System.out.println(canvas.translation); ig.translate((int) canvas.translation.x, (int) canvas.translation.y); } diff --git a/src/main/java/paintingcanvas/drawable/Circle.java b/src/main/java/paintingcanvas/drawable/Circle.java index acdf3f8..f544475 100644 --- a/src/main/java/paintingcanvas/drawable/Circle.java +++ b/src/main/java/paintingcanvas/drawable/Circle.java @@ -1,6 +1,6 @@ package paintingcanvas.drawable; -import paintingcanvas.misc.Hue; +import paintingcanvas.misc.Misc; import java.awt.*; @@ -51,11 +51,12 @@ public Circle(int centerX, int centerY, int radius, Color color) { } /** - * Create a new Circle element with a certain color by name - * (see {@link Hue} for list of all valid names) + * Create a new Circle element with a hue name or hex code + * @see Misc#stringToColor(String) + * *
{@code
      * // Create a new red Circle centered at (100, 100) with a radius of 20.
-     * Circle circle = new Circle(100, 100, 20, new Color(255, 0, 0));
+     * Circle circle = new Circle(100, 100, 20, "red");
      * }
* * @param centerX The X-position of the circle @@ -64,7 +65,7 @@ public Circle(int centerX, int centerY, int radius, Color color) { * @param color The name of the color (case-insensitive) */ public Circle(int centerX, int centerY, int radius, String color) { - this(centerX, centerY, radius, Hue.getColor(color)); + this(centerX, centerY, radius, Misc.stringToColor(color)); } @Override diff --git a/src/main/java/paintingcanvas/drawable/Drawable.java b/src/main/java/paintingcanvas/drawable/Drawable.java index 7915487..ec7173d 100644 --- a/src/main/java/paintingcanvas/drawable/Drawable.java +++ b/src/main/java/paintingcanvas/drawable/Drawable.java @@ -4,6 +4,7 @@ import paintingcanvas.animation.AnimationBuilder; import paintingcanvas.canvas.Canvas; import paintingcanvas.misc.Hue; +import paintingcanvas.misc.Misc; import java.awt.*; @@ -26,23 +27,23 @@ public abstract class Drawable> implements Animatable { */ boolean filled = true; /** - * The color of the object + * the color of the object */ Color color; /** - * The X-position of the object + * the X-position of the object */ int x; /** - * The Y-position of the object + * the Y-position of the object */ int y; /** - * The color of the outline + * the color of the outline */ Color outlineColor = Color.BLACK; /** - * The stroke of the outline + * the stroke of the outline */ Stroke outlineStroke; @@ -74,7 +75,7 @@ public abstract class Drawable> implements Animatable { * * @param color the color of the outline * @param thickness the thickness of the outline - * @return The original object to allow method chaining + * @return the original object to allow method chaining */ public T setOutline(int thickness, Color color) { synchronized (Canvas.drawableSync) { @@ -98,7 +99,7 @@ public T setOutline(int thickness, Color color) { * } * * @param color the color of the outline - * @return The original object to allow method chaining + * @return the original object to allow method chaining */ public T setOutline(Color color) { synchronized (Canvas.drawableSync) { @@ -121,7 +122,7 @@ public T setOutline(Color color) { * } * * @param thickness the thickness of the outline - * @return The original object to allow method chaining + * @return the original object to allow method chaining */ public T setOutline(int thickness) { return this.setOutline(thickness, outlineColor); @@ -130,7 +131,7 @@ public T setOutline(int thickness) { /** * Removes the outline from the shape * - * @return The original object to allow method chaining + * @return the original object to allow method chaining */ public T removeOutline() { this.outlineStroke = null; @@ -149,7 +150,7 @@ public T removeOutline() { * } * * @param g Graphics context - * @return The object's center-point + * @return the object's center-point */ public Point center(Graphics g) { return new Point(this.x, this.y); @@ -161,7 +162,7 @@ public Point center(Graphics g) { * This calls the draw methods, but does some extra steps beforehand to lay it out correctly *

* - * @param g The graphics context to draw the object with + * @param g the graphics context to draw the object with */ public void render(Graphics g) { if (!this.visible) return; @@ -196,14 +197,14 @@ private void renderOutline(Graphics2D gc) { /** * the color is set to `color` * - * @param gc The graphics context to draw the object with + * @param gc the graphics context to draw the object with */ protected abstract void drawFilled(Graphics2D gc); /** * the color is set to `outlineColor`, the stroke is set to `outlineStroke` * - * @param gc The graphics context to draw the object with + * @param gc the graphics context to draw the object with */ protected abstract void drawOutline(Graphics2D gc); @@ -216,7 +217,7 @@ private void renderOutline(Graphics2D gc) { * o.hide(); * } * - * @return The original object to allow method chaining + * @return the original object to allow method chaining * @see #show() */ public T hide() { @@ -231,7 +232,7 @@ public T hide() { * o.show(); * } * - * @return The original object to allow method chaining + * @return the original object to allow method chaining * @see #hide() */ public T show() { @@ -254,7 +255,7 @@ public int getX() { * Set the X-position of the object * * @param x the new X-position of the Object - * @return The original object to allow method chaining + * @return the original object to allow method chaining * @see #getX() * @see #setY(int) */ @@ -280,7 +281,7 @@ public int getY() { * Set the Y-position of the element * * @param y the new Y-position of the Object - * @return The original object to allow method chaining + * @return the original object to allow method chaining * @see #setX(int) * @see #getY() */ @@ -294,7 +295,7 @@ public T setY(int y) { /** * Get the position of the element * - * @return The position of the element as a {@link Point} + * @return the position of the element as a {@link Point} * @see #setPos(int, int) */ public Point getPos() { @@ -304,9 +305,9 @@ public Point getPos() { /** * Set the position of the element. * - * @param x The new absolute X-position of the element - * @param y The new absolute Y-position of the element - * @return The original object to allow method chaining + * @param x the new absolute X-position of the element + * @param y the new absolute Y-position of the element + * @return the original object to allow method chaining * @see #getPos() * @see #setX(int) * @see #setY(int) @@ -330,9 +331,9 @@ public T setPos(int x, int y) { * c.move(-10, -10); * } * - * @param x The x to move by - * @param y The y to move by - * @return The original object to allow method chaining + * @param x the x to move by + * @param y the y to move by + * @return the original object to allow method chaining * @see #setPos(int, int) * @see #moveHorizontal(int) * @see #moveVertical(int) @@ -354,8 +355,8 @@ public T move(int x, int y) { * c.moveHorizontal(10); * } * - * @param x The x to move by - * @return The original object to allow method chaining + * @param x the x to move by + * @return the original object to allow method chaining * @see #setPos(int, int) * @see #moveVertical(int) */ @@ -375,8 +376,8 @@ public T moveHorizontal(int x) { * c.moveVertical(10); * } * - * @param y The y to move by - * @return The original object to allow method chaining + * @param y the y to move by + * @return the original object to allow method chaining * @see #setPos(int, int) * @see #moveHorizontal(int) */ @@ -388,72 +389,77 @@ public T moveVertical(int y) { } /** - * Set the color of the element with RGB. + * Get the current color of an element as a {@link Color} + * + * @return the {@link Color} of the element + */ + public Color getColor() { + return this.color; + } + + /** + * Set the color of {@code this} to the specified {@code color}. + * See Wikipedia for how this works. + * *

{@code
      * Circle o = new Circle(100, 100, 20);
      * o.setColor(255, 0, 0); // Set color to red
      * }
* - * @param r The red component of the color (0-255) - * @param g The green component of the color (0-255) - * @param b The blue component of the color (0-255) - * @return The original object to allow method chaining + * @param r red (0-255) + * @param g green (0-255) + * @param b blue (0-255) + * @return the original object to allow method chaining */ public T setColor(int r, int g, int b) { return this.setColor(new Color(r, g, b)); } /** - * Set the color of the element with RGBA. + * Set the color of {@code this} to the specified {@code color} + * See Wikipedia for how this works. + * *
{@code
      * Circle o = new Circle(100, 100, 20);
      * o.setColor(255, 0, 0); // Set color to red
      * }
* - * @param r The red component of the color (0-255) - * @param g The green component of the color (0-255) - * @param b The blue component of the color (0-255) - * @return The original object to allow method chaining + * @param r red (0-255) + * @param g green (0-255) + * @param b blue (0-255) + * @param a alpha (0-255) + * @return the original object to allow method chaining */ public T setColor(int r, int g, int b, int a) { return this.setColor(new Color(r, g, b, a)); } /** - * Get the current color of an element as a {@link Color} - * - * @return The {@link Color} of the element - */ - public Color getColor() { - return this.color; - } - - /** - * Set the color of the object with a {@link Color} object. + * Set the color of {@code this} to the specified {@code color}. + * See Wikipedia for how this works. + * *
{@code
      * Circle o = new Circle(100, 100, 20);
-     * o.setColor(Color.RED); // Set color to red
+     * // 0xFF0000 is hex for (255, 0, 0), which is red
+     * o.setColor(0xFF0000);
      * }
* - * @param color color. - * @return The original object to allow method chaining + * @param hex the number describing the RGB color + * @return the original object to allow method chaining */ - public T setColor(Color color) { - synchronized (Canvas.drawableSync) { - this.color = color; - } - return getThis(); + public T setColor(int hex) { + return setColor(hex >> 16 & 0xff, hex >> 8 & 0xff, hex & 0xff); } - /** + /** * Set the color of the object with a {@link Hue} object. *
{@code
      * Circle o = new Circle(100, 100, 20);
      * o.setColor(Hue.GREEN); // Set color to red
      * }
* - * @param color color. - * @return The original object to allow method chaining + * @param hue the hue + * @return the original object to allow method chaining */ public T setColor(Hue hue) { synchronized (Canvas.drawableSync) { @@ -463,8 +469,9 @@ public T setColor(Hue hue) { } /** - * Set the color of the object with a certain color by name, or by a hex code. string. - * (see {@link Hue} for list of all valid names) + * Set the color of the object with a hue name or hex code. + * @see Misc#stringToColor(String) + * *
{@code
      * Circle o = new Circle(100, 100, 20);
      * o.setColor("red"); // Set color to red
@@ -472,35 +479,32 @@ public T setColor(Hue hue) {
      * o.setColor("#FF0000"); // Set color to red, in a different way
      * }
* - * @param color The name of the color (case-insensitive) - * @return The original object to allow method chaining + * @param name the string describing the hue or the hex code + * @return the original object to allow method chaining */ public T setColor(String name) { - try { - var color = Color.decode(name); - return setColor(color); - } catch (Exception e) { - return setColor(Hue.getColor(name)); - } + return setColor(Misc.stringToColor(name)); } /** - * Set the color of the object with a 8-bit RGB hex literal. + * Set the color of the object with a {@link Color} object. *
{@code
-     *     Circle o = new Circle(100, 100, 20);
-     * // 0xFF0000 is hex for (255, 0, 0), which is red
-     * o.setColor(0xFF0000);
+     * Circle o = new Circle(100, 100, 20);
+     * o.setColor(Color.RED); // Set color to red
      * }
* - * @param hex The color as a hex literal - * @return The original object to allow method chaining + * @param color color. + * @return the original object to allow method chaining */ - public T setColor(int hex) { - return setColor(hex >> 16 & 0xff, hex >> 8 & 0xff, hex & 0xff); + public T setColor(Color color) { + synchronized (Canvas.drawableSync) { + this.color = color; + } + return getThis(); } /** - * Rotate this element by rotation°. + * Rotate this element by {@code rotation} degrees. *
{@code
      * Circle o = new Circle(100, 100, 20);
      *
@@ -510,7 +514,7 @@ public T setColor(int hex) {
      * }
* * @param rotation Change in rotation. (Degrees) - * @return The original object to allow method chaining + * @return the original object to allow method chaining * @see #setRotation(double) */ public T rotate(double rotation) { @@ -529,7 +533,7 @@ public T rotate(double rotation) { * assert i == 90; * } * - * @return The rotation of the object + * @return the rotation of the object * @see #rotate(double) */ public double getRotation() { @@ -537,14 +541,14 @@ public double getRotation() { } /** - * Set an elements rotation to rotation°. + * Set an elements rotation to {@code rotation} degrees. *
{@code
      * Circle o = new Circle(100, 100, 20);
      * o.setRotation(90); // Sets the elements rotation to 90°
      * }
* * @param rotation Absolute rotation. (Degrees) - * @return The original object to allow method chaining + * @return the original object to allow method chaining * @see #rotate(double) */ public T setRotation(double rotation) { @@ -564,8 +568,8 @@ public T setRotation(double rotation) { * c.setFilled(false); * } * - * @param filled The value to set {@code this.filled} to - * @return The original object to allow method chaining + * @param filled the value to set {@code this.filled} to + * @return the original object to allow method chaining * @see #setOutline(int) */ public T setFilled(boolean filled) { @@ -576,9 +580,8 @@ public T setFilled(boolean filled) { } /** - *

* Erase this object from the canvas. This object will be gone and cannot* be added back! - *

+ *

* * It can be added back just don't tell anyone shhhh *

*/ @@ -591,7 +594,7 @@ public void erase() { /** * Gets the outline color * - * @return The outline color + * @return the outline color */ public Color getOutlineColor() { return this.outlineColor; @@ -600,7 +603,7 @@ public Color getOutlineColor() { /** * Gets the outline stroke * - * @return The outline stroke + * @return the outline stroke */ public Stroke getOutlineStroke() { return this.outlineStroke; diff --git a/src/main/java/paintingcanvas/drawable/Ellipse.java b/src/main/java/paintingcanvas/drawable/Ellipse.java index 0f2f5de..c915545 100644 --- a/src/main/java/paintingcanvas/drawable/Ellipse.java +++ b/src/main/java/paintingcanvas/drawable/Ellipse.java @@ -1,6 +1,6 @@ package paintingcanvas.drawable; -import paintingcanvas.misc.Hue; +import paintingcanvas.misc.Misc; import java.awt.*; @@ -59,8 +59,8 @@ public Ellipse(int centerX, int centerY, int width, int height, Color color) { } /** - * Create a new Ellipse element with a certain color by name - * (see {@link Hue} for list of all valid names) + * Create a new Ellipse element with a hue name or hex code + * @see Misc#stringToColor(String) *
{@code
      * // Create a new red ellipse centered at (100, 100) with width 20 and height 30
      * Ellipse ellipse = new Ellipse(100, 100, 20, 30, "red");
@@ -73,7 +73,7 @@ public Ellipse(int centerX, int centerY, int width, int height, Color color) {
      * @param color   The name of the color (case-insensitive)
      */
     public Ellipse(int centerX, int centerY, int width, int height, String color) {
-        this(centerX, centerY, width, height, Hue.getColor(color));
+        this(centerX, centerY, width, height, Misc.stringToColor(color));
     }
 
     @Override
diff --git a/src/main/java/paintingcanvas/drawable/Line.java b/src/main/java/paintingcanvas/drawable/Line.java
index 1bef9f0..493ccda 100644
--- a/src/main/java/paintingcanvas/drawable/Line.java
+++ b/src/main/java/paintingcanvas/drawable/Line.java
@@ -1,6 +1,6 @@
 package paintingcanvas.drawable;
 
-import paintingcanvas.misc.Hue;
+import paintingcanvas.misc.Misc;
 
 import java.awt.*;
 
@@ -9,7 +9,7 @@
  */
 public class Line extends Drawable {
     /**
-     * The offset of the endpoint from the startpoint (x, y)
+     * the offset of the endpoint from the startpoint (x, y)
      */
     public Point endOffset;
 
@@ -20,10 +20,10 @@ public class Line extends Drawable {
      * Line line = new Line(100, 100, 200, 200);
      * }
* - * @param x1 The X-position of the startpoint - * @param y1 The Y-position of the startpoint - * @param x2 The X-position of the endpoint - * @param y2 The Y-position of the endpoint + * @param x1 the X-position of the startpoint + * @param y1 the Y-position of the startpoint + * @param x2 the X-position of the endpoint + * @param y2 the Y-position of the endpoint */ public Line(int x1, int y1, int x2, int y2) { super(x1, y1, Color.BLACK); @@ -38,11 +38,11 @@ public Line(int x1, int y1, int x2, int y2) { * Line line = new Line(100, 100, 200, 200, new Color(255, 0, 0)); * } * - * @param x1 The X-position of the startpoint - * @param y1 The Y-position of the startpoint - * @param x2 The X-position of the endpoint - * @param y2 The Y-position of the endpoint - * @param color The color of the line + * @param x1 the X-position of the startpoint + * @param y1 the Y-position of the startpoint + * @param x2 the X-position of the endpoint + * @param y2 the Y-position of the endpoint + * @param color the color of the line */ @SuppressWarnings("unused") public Line(int x1, int y1, int x2, int y2, Color color) { @@ -52,22 +52,22 @@ public Line(int x1, int y1, int x2, int y2, Color color) { } /** - * Create a new Line element colored a certain color by name - * (see {@link Hue} for list of all valid names) + * Create a new Line element colored a hue name or hex code + * @see Misc#stringToColor(String) *
{@code
      * // Create a new Line from (100, 100) to (200, 200)
      * Line line = new Line(100, 100, 200, 200, "red");
      * }
* - * @param x1 The X-position of the startpoint - * @param y1 The Y-position of the startpoint - * @param x2 The X-position of the endpoint - * @param y2 The Y-position of the endpoint - * @param color The name of the color (case-insensitive) + * @param x1 the X-position of the startpoint + * @param y1 the Y-position of the startpoint + * @param x2 the X-position of the endpoint + * @param y2 the Y-position of the endpoint + * @param color the name of the color (case-insensitive) */ @SuppressWarnings("unused") public Line(int x1, int y1, int x2, int y2, String color) { - this(x1, y1, x2, y2, Hue.getColor(color)); + this(x1, y1, x2, y2, Misc.stringToColor(color)); } @Override @@ -78,9 +78,9 @@ public Line setOutline(int thickness, Color color) { } /** - * DO NOT USE, Overridden + * DO NOT USE, Overridden, as there is nothing to fill in a line * - * @param filled The value to set {@code this.filled} to + * @param filled the value to set {@code this.filled} to * @return {@code this} */ @Override @@ -92,7 +92,7 @@ public Line setFilled(boolean filled) { * Set the stroke of the line * * @param stroke a {@code Stroke} object to define this line's stroke - * @return The original object to allow method chaining + * @return the original object to allow method chaining */ @SuppressWarnings("unused") public Line setStroke(Stroke stroke) { @@ -103,8 +103,8 @@ public Line setStroke(Stroke stroke) { /** * Set the thickness of the line * - * @param thickness The thickness of the line in pixels - * @return The original object to allow method chaining + * @param thickness the thickness of the line in pixels + * @return the original object to allow method chaining */ public Line setThickness(int thickness) { this.outlineStroke = new BasicStroke(thickness); @@ -148,9 +148,9 @@ public Point getStartpoint() { /** * Get the startpoint of the line * - * @param x The new X-position of the startpoint - * @param y The new Y-position of the startpoint - * @return The original object to allow method chaining + * @param x the new X-position of the startpoint + * @param y the new Y-position of the startpoint + * @return the original object to allow method chaining */ public Line setStartpoint(int x, int y) { this.x = x; @@ -161,9 +161,9 @@ public Line setStartpoint(int x, int y) { /** * Set the endpoint of the line * - * @param x The new X-position of the endpoint - * @param y The new Y-position of the endpoint - * @return The original object to allow method chaining + * @param x the new X-position of the endpoint + * @param y the new Y-position of the endpoint + * @return the original object to allow method chaining */ public Line setEndpoint(int x, int y) { this.endOffset = new Point(this.x - x, this.y - y); diff --git a/src/main/java/paintingcanvas/drawable/Path.java b/src/main/java/paintingcanvas/drawable/Path.java index f708477..00e36c1 100644 --- a/src/main/java/paintingcanvas/drawable/Path.java +++ b/src/main/java/paintingcanvas/drawable/Path.java @@ -1,6 +1,6 @@ package paintingcanvas.drawable; -import paintingcanvas.misc.Hue; +import paintingcanvas.misc.Misc; import java.awt.*; import java.awt.geom.Path2D; @@ -57,8 +57,8 @@ public Path(Color color) { } /** - * Create a new Path element with a certain color by name - * (see {@link Hue} for list of all valid names). The path is initially empty. + * Create a new Path element with a hue name or hex code + * @see Misc#stringToColor(String) * *
{@code
      * Path path = new Path("red").lineTo(100, 100)
@@ -71,7 +71,7 @@ public Path(Color color) {
      * @param color The name of the color (case-insensitive)
      */
     public Path(String color) {
-        this(Hue.getColor(color));
+        this(Misc.stringToColor(color));
     }
 
     /**
diff --git a/src/main/java/paintingcanvas/drawable/Rectangle.java b/src/main/java/paintingcanvas/drawable/Rectangle.java
index e853b9c..fd5f47a 100644
--- a/src/main/java/paintingcanvas/drawable/Rectangle.java
+++ b/src/main/java/paintingcanvas/drawable/Rectangle.java
@@ -1,6 +1,6 @@
 package paintingcanvas.drawable;
 
-import paintingcanvas.misc.Hue;
+import paintingcanvas.misc.Misc;
 
 import java.awt.*;
 
@@ -60,8 +60,9 @@ public Rectangle(int centerX, int centerY, int width, int height, Color color) {
     }
 
     /**
-     * Create a new Rectangle element with a certain color by name
-     * (see {@link Hue} for list of all valid names)
+     * Create a new Rectangle element with a hue name or hex code
+     * @see Misc#stringToColor(String)
+     *
      * 
{@code
      * // Create a new red Rectangle centered at (100, 100) with a width of 20 and a height of 30
      * Rectangle rectangle = new Rectangle(100, 100, 20, 30, "red");
@@ -74,7 +75,7 @@ public Rectangle(int centerX, int centerY, int width, int height, Color color) {
      * @param color   The name of the color (case-insensitive)
      */
     public Rectangle(int centerX, int centerY, int width, int height, String color) {
-        this(centerX, centerY, width, height, Hue.getColor(color));
+        this(centerX, centerY, width, height, Misc.stringToColor(color));
     }
 
     @Override
diff --git a/src/main/java/paintingcanvas/drawable/Square.java b/src/main/java/paintingcanvas/drawable/Square.java
index c235051..f8f5528 100644
--- a/src/main/java/paintingcanvas/drawable/Square.java
+++ b/src/main/java/paintingcanvas/drawable/Square.java
@@ -1,6 +1,6 @@
 package paintingcanvas.drawable;
 
-import paintingcanvas.misc.Hue;
+import paintingcanvas.misc.Misc;
 
 import java.awt.*;
 
@@ -51,8 +51,9 @@ public Square(int centerX, int centerY, int size, Color color) {
     }
 
     /**
-     * Create a new Square element with a certain color by name
-     * (see {@link Hue} for list of all valid names)
+     * Create a new Square element with a hue name or hex code
+     * @see Misc#stringToColor(String)
+     *
      * 
{@code
      * // Create a red square centered at (100, 100) with a side length of 30px
      * Square square = new Square(100, 100, 30, "red");
@@ -64,7 +65,7 @@ public Square(int centerX, int centerY, int size, Color color) {
      * @param color   The name of the color of the square (case-insensitive)
      */
     public Square(int centerX, int centerY, int size, String color) {
-        this(centerX, centerY, size, Hue.getColor(color));
+        this(centerX, centerY, size, Misc.stringToColor(color));
     }
 
     @Override
diff --git a/src/main/java/paintingcanvas/drawable/Text.java b/src/main/java/paintingcanvas/drawable/Text.java
index ae7e3b4..361e080 100644
--- a/src/main/java/paintingcanvas/drawable/Text.java
+++ b/src/main/java/paintingcanvas/drawable/Text.java
@@ -1,6 +1,6 @@
 package paintingcanvas.drawable;
 
-import paintingcanvas.misc.Hue;
+import paintingcanvas.misc.Misc;
 
 import java.awt.*;
 
@@ -66,8 +66,9 @@ public Text(int x, int y, String text, Color color) {
 
     /**
      * 

- * Create a new Text element with a certain color by name - * (see {@link Hue} for list of all valid names). + * Create a new Text element with a hue name or hex code + * @see Misc#stringToColor(String) + * * The default font size is 30, and the default font is comic sans :) *

* It probably won't work on replit however. Comic sans is not installed on @@ -83,7 +84,7 @@ public Text(int x, int y, String text, Color color) { * @param color The name of the color of the text (case-insensitive) */ public Text(int x, int y, String text, String color) { - this(x, y, text, Hue.getColor(color)); + this(x, y, text, Misc.stringToColor(color)); } @Override diff --git a/src/main/java/paintingcanvas/drawable/Triangle.java b/src/main/java/paintingcanvas/drawable/Triangle.java index b57bb5c..aa2e587 100644 --- a/src/main/java/paintingcanvas/drawable/Triangle.java +++ b/src/main/java/paintingcanvas/drawable/Triangle.java @@ -1,6 +1,6 @@ package paintingcanvas.drawable; -import paintingcanvas.misc.Hue; +import paintingcanvas.misc.Misc; import java.awt.*; @@ -59,8 +59,8 @@ public Triangle(int centerX, int centerY, int width, int height, Color color) { } /** - * Create a new Triangle element with a certain color by name - * (see {@link Hue} for list of all valid names) + * Create a new Triangle element with a hue name or hex code + * @see Misc#stringToColor(String) *

{@code
      * // Create a new Triangle centered at (100, 100) that is 20px wide and 30px tall
      * Triangle triangle = new Triangle(100, 100, 20, 30, new Color(255, 0, 0));
@@ -73,7 +73,7 @@ public Triangle(int centerX, int centerY, int width, int height, Color color) {
      * @param color   The name of the color of the triangle
      */
     public Triangle(int centerX, int centerY, int width, int height, String color) {
-        this(centerX, centerY, width, height, Hue.getColor(color));
+        this(centerX, centerY, width, height, Misc.stringToColor(color));
     }
 
     private java.awt.Polygon getPolygon() {
diff --git a/src/main/java/paintingcanvas/misc/Misc.java b/src/main/java/paintingcanvas/misc/Misc.java
index 89e5b21..bb630dd 100644
--- a/src/main/java/paintingcanvas/misc/Misc.java
+++ b/src/main/java/paintingcanvas/misc/Misc.java
@@ -1,5 +1,9 @@
 package paintingcanvas.misc;
 
+import paintingcanvas.animation.ColorAnimation;
+
+import java.awt.*;
+
 public class Misc {
     public static  N clamp(N min, N val, N max) {
         if (val.doubleValue() > max.doubleValue()) return max;
@@ -11,4 +15,24 @@ public static  boolean equality(N a, N b, N error) {
         var err = error.doubleValue() / 2;
         return Math.max(a.doubleValue(), b.doubleValue()) - err <= Math.min(a.doubleValue(), b.doubleValue()) + err;
     }
+
+    /**
+     * Set the color of the object with a certain color by name, or by a hex code. string.
+     * @see Hue for list of all valid names
+     *
+     * @param name the string describing the hue or the hex code
+     * @return the color
+     *
+     */
+    public static Color stringToColor(String name) {
+        try {
+            // prepend the "#" if necessary, and try to decode it as a hex code
+            String colorName = name.startsWith("#") ? name : ("#" + name);
+            return Color.decode(colorName);
+        } catch (Exception e) {
+            // otherwise, try to decode it as a Hue
+            // this function will also throw again if it isn't a valid Hue
+            return Hue.getColor(name);
+        }
+    }
 }
\ No newline at end of file