package org.newdawn.slick.svg; import java.util.ArrayList; import org.newdawn.slick.geom.MorphShape; /** * A utility to allow morphing between a set of similar SVG diagrams * * @author kevin */ public class SVGMorph extends Diagram { /** The list of figures being morphed */ private ArrayList figures = new ArrayList(); /** * Create a new morph with a first diagram base * * @param diagram The base diagram which provides the first step of the morph */ public SVGMorph(Diagram diagram) { super(diagram.getWidth(), diagram.getHeight()); for (int i=0;i<diagram.getFigureCount();i++) { Figure figure = diagram.getFigure(i); Figure copy = new Figure(figure.getType(), new MorphShape(figure.getShape()), figure.getData(), figure.getTransform()); figures.add(copy); } } /** * Add a subsquent step to the morphing * * @param diagram The diagram to add as the next step in the morph */ public void addStep(Diagram diagram) { if (diagram.getFigureCount() != figures.size()) { throw new RuntimeException("Mismatched diagrams, missing ids"); } for (int i=0;i<diagram.getFigureCount();i++) { Figure figure = diagram.getFigure(i); String id = figure.getData().getMetaData(); for (int j=0;j<figures.size();j++) { Figure existing = (Figure) figures.get(j); if (existing.getData().getMetaData().equals(id)) { MorphShape morph = (MorphShape) existing.getShape(); morph.addShape(figure.getShape()); break; } } } } /** * Set the current diagram we should morph from. This only really works with * updateMorphTime() but can be used for smooth transitions between * morphs. * * @param diagram The diagram to use as the base of the morph */ public void setExternalDiagram(Diagram diagram) { for (int i=0;i<figures.size();i++) { Figure figure = (Figure) figures.get(i); for (int j=0;j<diagram.getFigureCount();j++) { Figure newBase = diagram.getFigure(j); if (newBase.getData().getMetaData().equals(figure.getData().getMetaData())) { MorphShape shape = (MorphShape) figure.getShape(); shape.setExternalFrame(newBase.getShape()); break; } } } } /** * Update the morph time index by the amount specified * * @param delta The amount to update the morph by */ public void updateMorphTime(float delta) { for (int i=0;i<figures.size();i++) { Figure figure = (Figure) figures.get(i); MorphShape shape = (MorphShape) figure.getShape(); shape.updateMorphTime(delta); } } /** * Set the "time" index for this morph. This is given in terms of diagrams, so * 0.5f would give you the position half way between the first and second diagrams. * * @param time The time index to represent on this diagrams */ public void setMorphTime(float time) { for (int i=0;i<figures.size();i++) { Figure figure = (Figure) figures.get(i); MorphShape shape = (MorphShape) figure.getShape(); shape.setMorphTime(time); } } /** * @see Diagram#getFigureCount() */ public int getFigureCount() { return figures.size(); } /** * @see Diagram#getFigure(int) */ public Figure getFigure(int index) { return (Figure) figures.get(index); } }