From 091a1e0179cb264cc2cab6e3b11ea31045c8536d Mon Sep 17 00:00:00 2001 From: kitfox Date: Tue, 29 May 2007 23:33:23 +0000 Subject: Restoring SVG Salamander to it's original code base, and updating build scripts. git-svn-id: https://svn.java.net/svn/svgsalamander~svn/trunk/svg-core@36 7dc7fa77-23fb-e6ad-8e2e-c86bd48ed22b --- .../com/kitfox/svg/animation/AnimateMotion.java | 234 +++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 src/main/java/com/kitfox/svg/animation/AnimateMotion.java (limited to 'src/main/java/com/kitfox/svg/animation/AnimateMotion.java') diff --git a/src/main/java/com/kitfox/svg/animation/AnimateMotion.java b/src/main/java/com/kitfox/svg/animation/AnimateMotion.java new file mode 100644 index 0000000..c96f45e --- /dev/null +++ b/src/main/java/com/kitfox/svg/animation/AnimateMotion.java @@ -0,0 +1,234 @@ +/* + * 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 org.xml.sax.*; +import java.util.regex.*; +import java.awt.geom.*; +import java.awt.*; +import java.util.*; + +import com.kitfox.svg.*; + +/** + * @author Mark McKay + * @author Mark McKay + */ +public class AnimateMotion extends AnimateXform +{ + static final Matcher matchPoint = Pattern.compile("\\s*(\\d+)[^\\d]+(\\d+)\\s*").matcher(""); + +// protected double fromValue; +// protected double toValue; + GeneralPath path; + int rotateType = RT_ANGLE; + double rotate; //Static angle to rotate by + + public static final int RT_ANGLE = 0; //Rotate by constant 'rotate' degrees + public static final int RT_AUTO = 1; //Rotate to reflect tangent of position on path + + final Vector bezierSegs = new Vector(); + double curveLength; + + /** Creates a new instance of Animate */ + public AnimateMotion() + { + } + + public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent) throws SAXException + { + //Load style string + super.loaderStartElement(helper, attrs, parent); + + //Motion element implies animating the transform element + if (attribName == null) + { + attribName = "transform"; + attribType = AT_AUTO; + additiveType = AD_SUM; + } + + + //Determine path + String from = attrs.getValue("from"); + String to = attrs.getValue("to"); + if (from != null && to != null) + { + Point2D.Float ptFrom = new Point2D.Float(), ptTo = new Point2D.Float(); + + matchPoint.reset(from); + if (matchPoint.matches()) + { + setPoint(ptFrom, matchPoint.group(1), matchPoint.group(2)); + } + + matchPoint.reset(to); + if (matchPoint.matches()) + { + setPoint(ptFrom, matchPoint.group(1), matchPoint.group(2)); + } + + if (ptFrom != null && ptTo != null) + { + path = new GeneralPath(); + path.moveTo(ptFrom.x, ptFrom.y); + path.lineTo(ptTo.x, ptTo.y); + } + } + + String path = attrs.getValue("path"); + if (path != null) + { + this.path = buildPath(path, GeneralPath.WIND_NON_ZERO); + } + + //Now parse rotation style + String rotate = attrs.getValue("rotate"); + if (rotate != null) + { + if (rotate.equals("auto")) + { + this.rotateType = RT_AUTO; + } + else + { + try { this.rotate = Math.toRadians(Float.parseFloat(rotate)); } catch (Exception e) {} + } + } + + paramaterizePath(); + } + + protected static void setPoint(Point2D.Float pt, String x, String y) + { + try { pt.x = Float.parseFloat(x); } catch (Exception e) {}; + + try { pt.y = Float.parseFloat(y); } catch (Exception e) {}; + } + + + private void paramaterizePath() + { + bezierSegs.clear(); + curveLength = 0; + + double[] coords = new double[6]; + double sx = 0, sy = 0; + + for (PathIterator pathIt = path.getPathIterator(new AffineTransform()); !pathIt.isDone(); pathIt.next()) + { + Bezier bezier = null; + + int segType = pathIt.currentSegment(coords); + + switch (segType) + { + case PathIterator.SEG_LINETO: + { + bezier = new Bezier(sx, sy, coords, 1); + sx = coords[0]; + sy = coords[1]; + break; + } + case PathIterator.SEG_QUADTO: + { + bezier = new Bezier(sx, sy, coords, 2); + sx = coords[2]; + sy = coords[3]; + break; + } + case PathIterator.SEG_CUBICTO: + { + bezier = new Bezier(sx, sy, coords, 3); + sx = coords[4]; + sy = coords[5]; + break; + } + case PathIterator.SEG_MOVETO: + { + sx = coords[0]; + sy = coords[1]; + break; + } + case PathIterator.SEG_CLOSE: + //Do nothing + break; + + } + + if (bezier != null) + { + bezierSegs.add(bezier); + curveLength += bezier.getLength(); + } + } + } + + /** + * Evaluates this animation element for the passed interpolation time. Interp + * must be on [0..1]. + */ + public AffineTransform eval(AffineTransform xform, double interp) + { + Point2D.Double point = new Point2D.Double(); + + if (interp >= 1) + { + Bezier last = (Bezier)bezierSegs.get(bezierSegs.size() - 1); + last.getFinalPoint(point); + xform.setToTranslation(point.x, point.y); + return xform; + } + + double curLength = curveLength * interp; + for (Iterator it = bezierSegs.iterator(); it.hasNext();) + { + Bezier bez = (Bezier)it.next(); + + double bezLength = bez.getLength(); + if (curLength < bezLength) + { + double param = curLength / bezLength; + bez.eval(param, point); + break; + } + + curLength -= bezLength; + } + + xform.setToTranslation(point.x, point.y); + + return xform; + } + + public static void main(String[] argv) + { + AnimateMotion a = new AnimateMotion(); + a.path = buildPath("M0 0 L-400, 0", GeneralPath.WIND_NON_ZERO); + a.paramaterizePath(); + } +} -- cgit v1.2.3-55-g7522