Added Animation
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
package org.openautonomousconnection.oacswing.animated;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
public class AnimationPath extends ArrayList<KeyFrame> {
|
||||
@Getter @Setter
|
||||
private int inbetweens;
|
||||
|
||||
private int animationIterator = 0;
|
||||
|
||||
private int subFrameIterator = 0;
|
||||
|
||||
public AnimationPath(int inbetweens, Collection<KeyFrame> keyFrames) {
|
||||
this.addAll(keyFrames);
|
||||
this.inbetweens = inbetweens;
|
||||
}
|
||||
|
||||
public AnimationPath(int inbetweens, KeyFrame... keyFrames) {
|
||||
this.addAll(Arrays.stream(keyFrames).toList());
|
||||
this.inbetweens = inbetweens;
|
||||
}
|
||||
|
||||
public AnimationPath(int inbetweens) {
|
||||
this.inbetweens = inbetweens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get next keyframe according to current path iterator, depending on the current frame
|
||||
* @return next keyframe in order, depending on the current frame
|
||||
*/
|
||||
public KeyFrame getNext() {
|
||||
if(this.subFrameIterator >= this.inbetweens) {
|
||||
this.subFrameIterator = 0;
|
||||
this.animationIterator++;
|
||||
}
|
||||
|
||||
if(this.animationIterator >= this.size())
|
||||
return null;
|
||||
|
||||
this.subFrameIterator++;
|
||||
|
||||
KeyFrame current = this.get(this.animationIterator);
|
||||
|
||||
KeyFrame next = this.getNextInOrder();
|
||||
|
||||
// How far the transition should be finished
|
||||
|
||||
double transition = (double) this.subFrameIterator / this.inbetweens;
|
||||
|
||||
return inBetween(current, next, transition);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get next keyframe according to current path iterator, not depending on the current frame
|
||||
* @return next keyframe in order, not depending on the current frame
|
||||
*/
|
||||
public KeyFrame getNextInOrder() {
|
||||
int i = this.animationIterator + 1;
|
||||
|
||||
if(i >= this.size())
|
||||
i--;
|
||||
|
||||
return this.get(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset animation path iterator to start
|
||||
*/
|
||||
public void reset() {
|
||||
this.subFrameIterator = 0;
|
||||
this.animationIterator = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method needed to get in-betweens
|
||||
* @param point point to multiply
|
||||
* @param scalar scalar to multiply with
|
||||
* @return scalar product point
|
||||
*/
|
||||
private static Point multiply(Point point, double scalar) {
|
||||
int x = Math.toIntExact(Math.round(point.x * scalar));
|
||||
int y = Math.toIntExact(Math.round(point.y * scalar));
|
||||
|
||||
return new Point(x, y);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add two points together; also needed for in-betweens
|
||||
* @param point augend
|
||||
* @param addend addend
|
||||
* @return sum of both points
|
||||
*/
|
||||
private static Point add(Point point, Point addend) {
|
||||
return new Point(point.x + addend.x, point.y + addend.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts one point from another; also needed for in-betweens
|
||||
* @param point minuend
|
||||
* @param subtrahend subtrahend
|
||||
* @return sum of both points
|
||||
*/
|
||||
private static Point subtract(Point point, Point subtrahend) {
|
||||
return new Point(point.x - subtrahend.x, point.y - subtrahend.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find in-between with given scalar
|
||||
* @param kf1 first frame
|
||||
* @param kf2 next frame
|
||||
* @param scalar factor (ideally between 0 and 1, representing 0% transition to 100% transition)
|
||||
* @return in-between frame
|
||||
*/
|
||||
private static KeyFrame inBetween(KeyFrame kf1, KeyFrame kf2, double scalar) {
|
||||
// position
|
||||
|
||||
Point difference = subtract(kf2.position(), kf1.position());
|
||||
|
||||
Point pos = add(kf1.position(), multiply(difference, scalar));
|
||||
|
||||
// scale
|
||||
|
||||
int width, height;
|
||||
|
||||
int dW = kf2.width() - kf1.width();
|
||||
int dH = kf2.height() - kf1.height();
|
||||
|
||||
width = Math.toIntExact(Math.round(kf1.width() + dW * scalar));
|
||||
|
||||
height = Math.toIntExact(Math.round(kf1.height() + dH * scalar));
|
||||
|
||||
return new KeyFrame(pos, width, height);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user