Hello again,

> Hi Nicky,
>
>
> > I want to have an object moved along a path using the animateMotion element.
> > This works pretty well, but if I extend the path during animation the
> > modification is not recognized and the object keeps on moving the original
> > path.
>
> As far as I know, animating paths in SVG requires that the number of
> segments is kept during the animation [1] (at least in SVG Tiny 1.2).
> So I imagine that Batik's animateMotion implementation can be somehow
> tied to this concept...? You may animate the path taking this into
> consideration, though. ;-)
>
> I have tried keeping the number of path segments constant, but with no
success - same result as before.

>
>
> > Here's the code:
>
> I'd suggest only pasting the relevant code snippets inline and
> attaching the full code (or posting a link to it and attach it online
> somewhere) in order to ease on reading/replying. ;-)
>
> Sorry, I'm new to this mailing list mechanism, but makes sense indeed.

>
> > I actually got it working by removing the animation element from the doc and
> > in turn append a copy of it:
>
> Yeah, that would workaround the behavior above, as the new path would
> be then used for the animateMotion.
>
> As I said, it's not the optimal solution but I keep it in mind for the case
I don't find a better one.

>
> > Another next problem would be to determine the prosition of the moving
> > object and to detect a collition with an other element.
>
> For detecting position you have several DOM methods (for computing
> distance along a path [2], getting an element's bounding box - getBBox
> [3], etc.). Also, as far as I know there's no native collision
> detection in SVG, although you may compute it by comparing bounding
> box limits (somehow fuzzy) and/or intersections points [4] (should be
> more precise but also computationally more expensive).
>
> Thanks for that.

>
>
> > Thanks for your help.
>
> For general questions on SVG (not specific to Batik), I'd also
> recommend keeping an eye/posting into SVG Developers [5] mailing list.
> Please avoid cross-posting, though, as many are watching both lists.
> ;-)
>
>
> Hope this helps,
>  Helder
>
>
> [1] http://www.w3.org/TR/SVGTiny12/paths.html#PathDataAnimation
> [2] http://www.w3.org/TR/SVG11/paths.html#DistanceAlongAPath
> [3] http://www.w3.org/TR/SVG11/ecmascript-binding.html
> [4] http://ajaxian.com/archives/intersections-and-svg-objects
> [5] http://groups.yahoo.com/group/svg-developers/
>
> Thank you, you've been a great help sofar.

I came to a new idea using multiple animateMotion elements which are
dynamically appended to the animation target element (the 'plane') and form
a animation sequence using begin="prev_animation.end".
Although I'm not sure if this is supported by batik, I thought this was a
great idea, but it does not work either.
Relevant code here:
    public void mouseClicked(MouseEvent me) {
        System.out.println("clicked");

        queue.invokeLater(new Runnable() {
            public void run() {
                SVGOMPathElement tmpPath = (SVGOMPathElement)
doc.createElementNS(svgNS, "path");

                int id = plane.getChildElementCount() + 1;
                float length = path.getTotalLength();
                SVGPoint point = path.getPointAtLength(length);
                SVGPathSegList segs = tmpPath.getPathSegList();

                segs.appendItem(path.createSVGPathSegMovetoAbs(point.getX(),
point.getY()));

                SVGPathSeg seg;
                if (id % 2 == 0) {
                    seg = path.createSVGPathSegLinetoHorizontalRel(20);
                } else {
                    seg = path.createSVGPathSegLinetoVerticalRel(20);
                }
                path.getPathSegList().appendItem(seg);
                segs.appendItem(seg);

                length = path.getTotalLength() - length;

                anim = (SVGOMAnimateMotionElement)
baseAnim.cloneNode(false);
                anim.setAttributeNS(null, "id", "anim" + id);
                anim.setAttributeNS(null, "begin", "anim" + (id - 1) +
".end");
                anim.setAttributeNS(null, "dur", (length / VELOCITY) + "s");
                anim.setAttributeNS(null, "path",
tmpPath.getAttributeNS(null, "d"));

                plane.appendChild(anim);

                //printDocument();
            }
        });
    }

Full code here: http://gist.github.com/173770

Looks good, doesn't it? But as I said, it doesn't work for some reason: If I
click the mouse button and the new animateMotion element is appended to the
target the animation stops.
I tried to replace the begin="prev_animation.end" with "10s" but the
animation freezes anyway and continues after 10 seconds on the new path
segment (actually the new path).
My function printDocument() gives me something like that:
<svg contentScriptType="text/ecmascript" width="400"
     xmlns:xlink="http://www.w3.org/1999/xlink"; zoomAndPan="magnify"
     contentStyleType="text/css" height="400"
     preserveAspectRatio="xMidYMid meet" viewbox="0 0 400 400"
     xmlns="http://www.w3.org/2000/svg"; version="1.0">
    <path fill="none" d="M50,50 h20 v20 h20 v20 h20 v20 h20 v20 h 20.0"
          stroke-width="3px" id="path" stroke="green"/>
    <circle fill="red" r="5" id="plane" cx="0" cy="0">
        <animateMotion dur="4.0s" rotate="auto" repeatCount="1" begin="1s"
                       path="M50,50 h20 v20 h20 v20 h20 v20 h20 v20"
                       calcMode="paced" id="anim1"/>
        <animateMotion dur="0.5s" rotate="auto" repeatCount="1"
                       begin="anim1.end" path="M 130.0 130.0 h 20.0"
                       calcMode="paced" id="anim2"/>
    </circle>
</svg>

I tried this code with opera and sqiggle and it worked perfectly. So what am
I doing wrong?

Thanks for your help

Kind regards
Nicky

Reply via email to