summaryrefslogtreecommitdiffstats
path: root/src/main/java/com/kitfox/svg/animation/AnimateTransform.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/kitfox/svg/animation/AnimateTransform.java')
-rw-r--r--src/main/java/com/kitfox/svg/animation/AnimateTransform.java225
1 files changed, 225 insertions, 0 deletions
diff --git a/src/main/java/com/kitfox/svg/animation/AnimateTransform.java b/src/main/java/com/kitfox/svg/animation/AnimateTransform.java
new file mode 100644
index 0000000..efce6fc
--- /dev/null
+++ b/src/main/java/com/kitfox/svg/animation/AnimateTransform.java
@@ -0,0 +1,225 @@
+/*
+ * Animate.java
+ *
+ * The Salamander Project - 2D and 3D graphics libraries in Java
+ * Copyright (C) 2004 Mark McKay
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
+ * projects can be found at http://www.kitfox.com
+ *
+ * Created on August 15, 2004, 2:51 AM
+ */
+
+package com.kitfox.svg.animation;
+
+import com.kitfox.svg.xml.XMLParseUtil;
+import org.xml.sax.*;
+import java.awt.geom.*;
+
+import com.kitfox.svg.*;
+import com.kitfox.svg.xml.*;
+import java.util.regex.Pattern;
+
+/**
+ * @author Mark McKay
+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
+ */
+public class AnimateTransform extends AnimateXform
+{
+// protected AffineTransform fromValue;
+// protected AffineTransform toValue;
+// protected double[] fromValue; //Transform parameters
+// protected double[] toValue;
+ protected double[][] values;
+ protected double[] keyTimes;
+
+ public static final int AT_REPLACE = 0;
+ public static final int AT_SUM = 1;
+
+ protected int additive = AT_REPLACE;
+
+ public static final int TR_TRANSLATE = 0;
+ public static final int TR_ROTATE = 1;
+ public static final int TR_SCALE = 2;
+ public static final int TR_SKEWY = 3;
+ public static final int TR_SKEWX = 4;
+ public static final int TR_INVALID = 5;
+
+ protected int xformType = TR_INVALID;
+
+ /** Creates a new instance of Animate */
+ public AnimateTransform()
+ {
+ }
+
+ public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent) throws SAXException
+ {
+ //Load style string
+ super.loaderStartElement(helper, attrs, parent);
+
+ //Type of matrix of transform. Should be one of the known names used to
+ // define matrix transforms
+ // valid types: translate, scale, rotate, skewX, skewY
+ // 'matrix' not valid for animation
+ String type = attrs.getValue("type").toLowerCase();
+ if (type.equals("translate")) xformType = TR_TRANSLATE;
+ if (type.equals("rotate")) xformType = TR_ROTATE;
+ if (type.equals("scale")) xformType = TR_SCALE;
+ if (type.equals("skewx")) xformType = TR_SKEWX;
+ if (type.equals("skewy")) xformType = TR_SKEWY;
+
+ String fromStrn = attrs.getValue("from");
+ String toStrn = attrs.getValue("to");
+ if (fromStrn != null && toStrn != null)
+ {
+ //fromValue = parseSingleTransform(type + "(" + strn + ")");
+ double[] fromValue = XMLParseUtil.parseDoubleList(fromStrn);
+ fromValue = validate(fromValue);
+
+ // toValue = parseSingleTransform(type + "(" + strn + ")");
+ double[] toValue = XMLParseUtil.parseDoubleList(toStrn);
+ toValue = validate(toValue);
+
+ values = new double[][]{fromValue, toValue};
+ keyTimes = new double[]{0, 1};
+ }
+
+ String keyTimeStrn = attrs.getValue("keyTimes");
+ String valuesStrn = attrs.getValue("values");
+ if (keyTimeStrn != null && valuesStrn != null)
+ {
+ keyTimes = XMLParseUtil.parseDoubleList(keyTimeStrn);
+
+ String[] valueList = Pattern.compile(";").split(valuesStrn);
+ values = new double[valueList.length][];
+ for (int i = 0; i < valueList.length; i++)
+ {
+ double[] list = XMLParseUtil.parseDoubleList(valueList[i]);
+ values[i] = validate(list);
+ }
+ }
+
+ //Check our additive state
+ String additive = attrs.getValue("additive");
+ if (additive != null)
+ {
+ if (additive.equals("sum")) this.additive = AT_SUM;
+ }
+ }
+
+ /**
+ * Check list size against current xform type and ensure list
+ * is expanded to a standard list size
+ */
+ private double[] validate(double[] paramList)
+ {
+ switch (xformType)
+ {
+ case TR_SCALE:
+ {
+ if (paramList == null)
+ {
+ paramList = new double[]{1, 1};
+ }
+ else if (paramList.length == 1)
+ {
+ paramList = new double[]{paramList[0], paramList[0]};
+
+// double[] tmp = paramList;
+// paramList = new double[2];
+// paramList[0] = paramList[1] = tmp[0];
+ }
+ }
+ }
+
+ return paramList;
+ }
+
+ /**
+ * Evaluates this animation element for the passed interpolation time. Interp
+ * must be on [0..1].
+ */
+ public AffineTransform eval(AffineTransform xform, double interp)
+ {
+ int idx = 0;
+ for (; idx < keyTimes.length - 1; idx++)
+ {
+ if (interp >= keyTimes[idx])
+ {
+ idx--;
+ if (idx < 0) idx = 0;
+ break;
+ }
+ }
+
+ double spanStartTime = keyTimes[idx];
+ double spanEndTime = keyTimes[idx + 1];
+// double span = spanStartTime - spanEndTime;
+
+ interp = (interp - spanStartTime) / (spanEndTime - spanStartTime);
+ double[] fromValue = values[idx];
+ double[] toValue = values[idx + 1];
+
+ switch (xformType)
+ {
+ case TR_TRANSLATE:
+ {
+ double x = (1.0 - interp) * fromValue[0] + interp * toValue[0];
+ double y = (1.0 - interp) * fromValue[1] + interp * toValue[1];
+ xform.setToTranslation(x, y);
+ break;
+ }
+ case TR_ROTATE:
+ {
+ double x1 = fromValue.length == 3 ? fromValue[1] : 0;
+ double y1 = fromValue.length == 3 ? fromValue[2] : 0;
+ double x2 = toValue.length == 3 ? toValue[1] : 0;
+ double y2 = toValue.length == 3 ? toValue[2] : 0;
+
+ double theta = (1.0 - interp) * fromValue[0] + interp * toValue[0];
+ double x = (1.0 - interp) * x1 + interp * x2;
+ double y = (1.0 - interp) * y1 + interp * y2;
+ xform.setToRotation(Math.toRadians(theta), x, y);
+ break;
+ }
+ case TR_SCALE:
+ {
+ double x = (1.0 - interp) * fromValue[0] + interp * toValue[0];
+ double y = (1.0 - interp) * fromValue[1] + interp * toValue[1];
+ xform.setToScale(x, y);
+ break;
+ }
+ case TR_SKEWX:
+ {
+ double x = (1.0 - interp) * fromValue[0] + interp * toValue[0];
+ xform.setToShear(Math.toRadians(x), 0.0);
+ break;
+ }
+ case TR_SKEWY:
+ {
+ double y = (1.0 - interp) * fromValue[0] + interp * toValue[0];
+ xform.setToShear(0.0, Math.toRadians(y));
+ break;
+ }
+ default:
+ xform.setToIdentity();
+ break;
+ }
+
+ return xform;
+ }
+}