com.enterprisemath.utils.image.CompositeImageAnimation Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of em-utils Show documentation
Show all versions of em-utils Show documentation
Collection of utility classes for large scale projects focusing on robust and testable code.
package com.enterprisemath.utils.image;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang3.builder.ToStringBuilder;
import com.enterprisemath.utils.DomainUtils;
import com.enterprisemath.utils.ValidationUtils;
/**
* Implementation of image animation which composes several animations together.
* Precondition is that all of the animations in the composition have
* same number of frames and same frame duration.
*
* @author radek.hecl
*
*/
public class CompositeImageAnimation implements ImageAnimation {
/**
* Builder object.
*/
public static class Builder {
/**
* Frame width.
*/
private Integer frameWidth;
/**
* Frame height.
*/
private Integer frameHeight;
/**
* Sub animations.
*/
private List subAnimations = new ArrayList();
/**
* Sets frame width.
*
* @param frameWidth frame width
* @return this instance
*/
public Builder setFrameWidth(Integer frameWidth) {
this.frameWidth = frameWidth;
return this;
}
/**
* Sets frame height.
*
* @param frameHeight frame height
* @return this instance
*/
public Builder setFrameHeight(Integer frameHeight) {
this.frameHeight = frameHeight;
return this;
}
/**
* Adds sub animation.
*
* @param x position x
* @param y position y
* @param animation animation
* @return this instance
*/
public Builder addSubAnimation(int x, int y, ImageAnimation animation) {
subAnimations.add(new SubAnimation(x, y, animation));
return this;
}
/**
* Builds the result object.
*
* @return created object
*/
public CompositeImageAnimation build() {
return new CompositeImageAnimation(this);
}
}
/**
* Frame width.
*/
private Integer frameWidth;
/**
* Frame height.
*/
private Integer frameHeight;
/**
* Sub animations.
*/
private List subAnimations;
/**
* Creates new instance.
*
* @param builder builder object
*/
public CompositeImageAnimation(Builder builder) {
frameWidth = builder.frameWidth;
frameHeight = builder.frameHeight;
subAnimations = Collections.unmodifiableList(DomainUtils.softCopyList(builder.subAnimations));
guardInvariants();
}
/**
* Guards this object to be consistent. Throws exception if this is not the case.
*/
private void guardInvariants() {
ValidationUtils.guardPositiveInt(frameWidth, "frameWidth must be positive");
ValidationUtils.guardPositiveInt(frameHeight, "frameHeight must be positive");
ValidationUtils.guardPositiveInt(subAnimations.size(), "at least 1 sub animation must be defined");
int frameDuration = subAnimations.get(0).getAnimation().getFrameDuration();
int numFrames = subAnimations.get(0).getAnimation().getNumFrames();
for (SubAnimation sa : subAnimations) {
ValidationUtils.guardEquals(frameDuration, sa.getAnimation().getFrameDuration(),
"frameDuration must be same for all animations in composite");
ValidationUtils.guardEquals(numFrames, sa.getAnimation().getNumFrames(),
"numFrames must be same for all animations in composite");
}
}
@Override
public int getFrameWidth() {
return frameWidth;
}
@Override
public int getFrameHeight() {
return frameHeight;
}
@Override
public int getNumFrames() {
return subAnimations.get(0).getAnimation().getNumFrames();
}
@Override
public int getFrameDuration() {
return subAnimations.get(0).getAnimation().getFrameDuration();
}
@Override
public RenderedImage getFrame(int index) {
BufferedImage img = new BufferedImage(frameWidth, frameHeight, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g = (Graphics2D)img.getGraphics();
for (SubAnimation sa : subAnimations) {
AffineTransform at = AffineTransform.getTranslateInstance(sa.getX(), sa.getY());
g.drawRenderedImage(sa.getAnimation().getFrame(index), at);
}
return img;
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
/**
* Defines sub animation. Sub animation is animation in the part of the frame.
*
*/
private static class SubAnimation {
/**
* Position x.
*/
private int x;
/**
* Position y.
*/
private int y;
/**
* Animation.
*/
private ImageAnimation animation;
/**
* Creates new instance.
* @param x position x
* @param y position y
* @param animation animation
*/
private SubAnimation(int x, int y, ImageAnimation animation) {
this.x = x;
this.y = y;
this.animation = animation;
guardInvariatns();
}
/**
* Guards this object to be consistent. Throws exception if this is not the case.
*/
private void guardInvariatns() {
ValidationUtils.guardNotNull(animation, "animation cannot be null");
}
/**
* Returns position x.
*
* @return position x
*/
public int getX() {
return x;
}
/**
* Returns position y.
*
* @return position y
*/
public int getY() {
return y;
}
/**
* Returns animation.
*
* @return animation
*/
public ImageAnimation getAnimation() {
return animation;
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy