adobe-webplatform / Snap.svg

The JavaScript library for modern SVG graphics.
http://snapsvg.io
Apache License 2.0
13.96k stars 1.15k forks source link

Add the option to use svg files as frames in animations #279

Open Emasoft opened 10 years ago

Emasoft commented 10 years ago

PROBLEM: Currently the "animate" property of an svg element accept as parameters only key-value pairs of start-destination attributes, not entire svg objects. This has made much more difficult to create animated svg animated icons, because the author must:

1 - Draw the 2 svg frames in Inkscape, Illustrator or any other svg editor 2 - Open the svg files and manually copy all the elements values changed from the start frame to the destination frame (i.e. paths, colors, transform matrix, etc) 3 - Manually paste all parameters as arguments of the el.animate(...) function, or inside a method like this used to assign the properties programmatically:

myIconName : { 
    url : 'svgs/myIconName.svg',
    animation : [
        { 
            el : 'path:nth-child(5)', 
            animProperties : { 
                from : { val : '{"path" : "m 61.693118,24.434001 -59.386236,0 29.692524,19.897984 z"}', animAfter : '{"stroke" : "#000"}' }, 
                to : { val : '{"path" : "m 61.693118,24.434001 -59.386236,0 29.692524,-19.7269617 z"}', animAfter : '{"stroke" : "#444"}' }
                } 
        },
        { 
            el : 'rect:nth-child(3)', 
            animProperties : { 
                from : { val : '{"transform" : "t0 0"}', after : '{ "opacity" : 0 }' }, 
                to : { val : '{"transform" : "t-10 -10"}', before : '{ "opacity" : 1 }' }
            } 
        }
]
}

svgIcon.prototype.toggle = function( motion ) {
        if( !this.config.animation ) return;
        var self = this;
        for( var i = 0, len = this.config.animation.length; i < len; ++i ) {
            var a = this.config.animation[ i ],
                el = this.svg.select( a.el ),
                animProp = this.toggled ? a.animProperties.from : a.animProperties.to,
                val = animProp.val, 
                timeout = motion && animProp.delayFactor ? animProp.delayFactor : 0;

            if( animProp.before ) {
                el.attr( JSON.parse( animProp.before ) );
            }

            if( motion ) {
                setTimeout(function( el, val, animProp ) { 
                    return function() { el.animate( JSON.parse( val ), self.options.speed, self.options.easing, function() {
                        if( animProp.after ) {
                            this.attr( JSON.parse( animProp.after ) );
                        }
                        if( animProp.animAfter ) {
                            this.animate( JSON.parse( animProp.animAfter ), self.options.speed, self.options.easing );
                        }
                    } ); }; 
                }( el, val, animProp ), timeout * self.options.speed );
            }
            else {
                el.attr( JSON.parse( val ) );
            }

        }
        this.toggled = !this.toggled;
    };

as described in this excellent article: http://tympanus.net/codrops/2013/11/05/animated-svg-icons-with-snap-svg/ All this is very difficult and long to do, and this is one of the main reasons because Icon animations in SVG are very rare.

SOLUTION: Add to Snap.svg the option to pass svg files as parameters to the animation function. The different files would be compared and automatically parsed to get the start and destination properties of all objects. More specifically:

This function can be called "frameAnimation()" and implemented not as a method of the element but as a global method.

Also, a multi frame system can be implemented using a technique like the one in the following example: http://svg.dabbles.info/snaptut-animateframe.html The only difference would be that instead of defining an array of properties, the user would define an array of svg files, like button_frame1.svg, button_frame2.svg, button_frame3.svg, button_frame4.svg, and so on. This would allow for an easy animation system, accessible to designer and artists that love svg but didn't know how to use it.

Emasoft commented 10 years ago

Currently there is a design proposal for Inkscape to support multiple pages/frames for onion skin animations (see https://bugs.launchpad.net/inkscape/+bug/1343411 ): inkscape onion skin multipage feature proposal

ibrierley commented 10 years ago

Do you have example svgs out of interest, sounds like maybe a bit much for core Snap, but maybe for a plugin or something it could work ? It would be useful to see a couple of typical example svgs though.