-
Notifications
You must be signed in to change notification settings - Fork 1
Animation
Now that you've got some graphics on the screen, you might want to make it a bit more dynamic. Lucky for you,
there's a built in animation system that's simple™, easy™, and capable™. The following methods are defined
in Animatable
.
Animation Methods | Paramteters | Description |
---|---|---|
colorTo() |
(int r, int g, int b, double duration) |
Fades from an element's current color, to the defined one using RGB to define the color |
colorTo() |
(int hex, double duration) |
Fades from an element's current color, to the defined one using 8-bit RGB hex literal to define the color |
colorTo() |
(Color color, double duration) |
Fades from an element's current color, to the defined one using a Color to define the color. |
rotateTo() |
(int degrees, double duration) |
Rotates an element to degrees degrees. So, rotateTo(360) would do a 360° counter-clockwise flip if the object was originally at 0° rotation. |
rotateBy() |
(int degrees, double duration) |
Rotates an element from its current rotation, to it's current rotation + degrees . Positive is counter-clockwise, negative is clockwise. |
moveTo() |
(int x, int y, double duration) |
Moves an element from its current position, to this specific x and y position. This is absolute movement, so if an element is at 100, 100 and you call moveTo(0, 100) it moves to 0, 100 . |
moveBy() |
(int x, int y, double duration) |
Moves an element x pixels horizontally, and y pixels vertically. This is relative movement, so if an element is at 100, 100 and you call moveTo(0, 100) it moves to 100, 200 . |
moveHorizontalBy() |
(int x, int y, double duration) |
Moves an element x pixels horizontally, equivalent to moveBy(x, 0)
|
moveVerticalBy() |
(int x, int y, double duration) |
Moves an element y pixels vertically, equivalent to moveBy(0, y)
|
fadeIn() |
(double duration) |
Fades an element in if it has been faded out before |
fadeOut() |
(double duration) |
Fades an element out, basically making it dissapear |
Also, unless specified otherwise, duration is in seconds.
These methods can be called on AnimationBuilder or Drawable, and queue animations one after another.
Circle c = new Circle(100, 100, 50);
c.moveTo(0, 0, 3); // move to (0, 0) over 3 seconds
c.colorTo(new Color(255, 0, 0), 1) // make the circle red over one second
c.fadeOut(5.3); // fade out the circle over 5.3 seconds
c.fadeIn(1); // fade in the circle over 1 second
Remember, even thoughduration
is a double, integers will auto-convert into doubles so you can use them instead. So.wait(3)
and.wait(3.23)
are both valid.
Now that system is all well and good but it does not allow you to run multiple animations at the same time. To do this you need to learn how animation scheduling works!
To start assigning animations to a shape, you first need to call .animate()
on it.
Circle circle = new Circle(100, 100, 40); // create a new circle
circle.animate() // animate the circle
.add(Animation.ColorTo(255, 0, 0), 3) // add an animation to make it red over 3 seconds
.with(Animation.moveTo(100, 200), 3); // while the circle is turning red, also move it to (100, 200)
// over the next 3 seconds.
You may notice another static method being called to define the animation. These are defined in
the Animation
class, and simply return the corrosponding animation. They are the same as
the ones defined in Animatable
, but do not include a duration parameter.
Notice the add()
method being called. There are multiple methods available that you can use
to schedule animations, defined in the AnimationBuilder
class.
Method | Parameters | Description |
---|---|---|
add() |
(Animation, double duration) |
Waits until all previously scheduled animations have wrapped up, then schedules Animation for duration seconds after previous animations have wrapped up |
with() |
(Animation, double duration) |
Schedules the next animation alongside the previous animation |
schedule() |
(double time, Animation, double duration) |
Schedules the animation at some point in the future, with() and add() are unaffected |
wait() |
(double delay) |
Schedules the next animations delay seconds after it normally would |
add, with, schedule, and wait all take an optional extra parameter, which sets the time unit. By default it's seconds, but it can also be set toTimeUnit.Frames
Circle circle = new Circle(100, 100, 40);
Square square = new Square(0, 0, 50);
circle.animate()
.add(Animation.colorTo(Color.RED), 3, TimeUnit.Seconds);
square.animate()
// by default, we run at 30 fps
.with(Animation.moveTo(100, 100), 90, TimeUnit.Frames)
Please remember that these methods schedule animations, and don't actually wait for the animation to finish. If you want to run some code after all your scheduled animations finish, remember to use.sleep()
Canvas canvas = new Canvas(); Circle circle = new Circle(100, 100, 40); circle.moveBy(0, 100, 3); System.out.println("I will run before the animation finishes"); circle.moveBy(100, 0, 3); canvas.sleep(); System.out.println("I will run after the animation finishes");
Now that probably wasn't very easy to understand, but hopefully this explanation will help:
Square square = new Square(0, 0, 40); Imagine a timeline: +1 is 1 second into the future, +2 is 2 seconds into the future etc. |
|
Square square = new Square(0, 0, 40);
square.animate()
.add(Animation.moveTo(100, 0), 4); Notice the green and blue markers,
|
|
Square square = new Square(0, 0, 40);
square.animate()
.add(Animation.moveTo(100, 0), 4)
.add(Animation.colorTo(Color.RED), 4); Now it should be obvious how you can keep chaining together |
|
Square square = new Square(0, 0, 40);
square.animate()
.add(Animation.moveTo(100, 0), 4)
.with(Animation.colorTo(Color.RED), 5); As you can see, instead of adding the next animation after the
Also note that the |
|
Square square = new Square(0, 0, 40);
square.animate()
.add(Animation.moveTo(100, 0), 4)
.with(Animation.colorTo(Color.RED), 5)
.wait(1); Now here, the |
|
Square square = new Square(0, 0, 40);
square.animate()
.add(Animation.moveTo(100, 0), 4)
.with(Animation.colorTo(Color.RED), 5)
.wait(1)
.with(Animation.rotateTo(360), 3); Now if you have followed along so far this should make sense. Notice
how |
|
Square square = new Square(0, 0, 40);
square.animate()
.add(Animation.moveTo(100, 0), 4)
.with(Animation.colorTo(Color.RED), 5)
.wait(1)
.with(Animation.rotateTo(360), 3)
.add(Animation.colorTo(Color.BLUE), 4); Again, if you have followed along so far this should make sense.
Now this is getting a bit complicated is there a more flexible
way to assign animations? Yes there is! If you remember
Square square = new Square(0, 0, 40);
square.animate()
.schedule(0, Animation.moveTo(100, 0), 4)
.schedule(0, Animation.colorTo(Color.RED), 5)
.schedule(1, Animation.rotateTo(360), 3)
.schedule(6, Animation.colorTo(Color.BLUE), 4);
|
And that's basically all there is to know about animations!