Jump to content
Search Community

General purpose SVG plug-in?

akbr test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

First of all, I'm long time fan. Greensock is great! 8-)

 

I've been using GSAP in one of my projects as a unified platform for animating both SVG and HTML. Up until recently, I'd been using Raphael as my SVG library. GSAP's RaphaelPlugin was a nice abstraction from the messy matrix math underlying transitions between transform states. I got spoiled using scaleX, scaleY, tx, ty, localPivot, etc.

 

Recently, I switched fron Raphael to D3, both for the data-driven functionality but also for more direct access/control over my SVG elements. (D3 focuses on transformation of SVG, whereas Raphael introduces it's own, special representations.) The change has been refreshing, but I miss the added functionality of RaphaelPlugin--especially for times when I simply want to spin and scale SVG elements using transform without thinking about interpolation, etc. [i'm not exclusively making graphs, but also flying spaceships around, etc.]

 

So I went back and looked at RaphaelPlugin, and it strikes me that you're very close to having a general purpose, library-agnostic SVG plug-in for GSAP. The very few Raphael-specific methods (e.g., matrix, bbox) in RaphaelPlugin are mirrored in the SVG spec (e.g., getCTM, getBBox). With a little hacking, I got a prototype (mostly) working fairly quickly.

 

Is there any interest in the community for such a thing? Have GSAP staff thought about this?

  • Like 2
Link to comment
Share on other sites

Thanks for suggesting this, akbr. Like you, I'm curious about whether or not the community really wants a general SVG plugin like you described. We've got a whole lot of other things in the hopper right now, but if there's enough demand for this type of thing, we'll very likely tackle it at some point. If you've got a working version of a plugin that might serve as a reference, please do send it along to us (if you don't mind). 

  • Like 1
Link to comment
Share on other sites

Thanks for the response. It's probably true that complex SVG animation is a small niche served primarily by Raphael at present.

 

That said, in case it's helpful to someone down the road, here's a link to my hackjob of your RaphaelPlugin:

 

https://github.com/akbr/GSAPSvgPlugin/blob/master/SvgPlugin.js

 

My changes were trivial; mostly swapping out Raphael-specific matrix fetches and BBox calls with the native SVG versions. I used D3 as a selector here, but it could just as easily be jQuery or the DOM API.

 

LocalPivot is broken because I have been too lazy to create or identify a replacement for Raphael's getBBox(true) functionality.

 

So at the end of the day, here's the syntax I'm using in my project:

 

TweenMax.to(/*SVG Node*/, 2, { svg: { scale:2, fill:"pink", rotation: 180} });

 

This has the following benefits for me:

 

(1) I get to use GSAP for all my animation. Yay!

 

(2) I get easy, intuitive access to matrix transformations. This is hard to come by for SVG outside of Raphael.

 

(3) Less "magic" than Raphael and other SVG solutions. I'm simply simply tweening the "transform" attribute of my SVG elements, and I can understand where those values are coming from.

 

Anyways, thanks again for your work on GSAP. Great stuff.

  • Like 2
Link to comment
Share on other sites

  • 4 months later...

I'd be very interested in this type of plug-in. I agree that GSAP and D3 are both awesome, and a plug-in would be a nice and extremely useful simplification. I'll check out the prototype when I'm back on a waiting task that would benefit from it.

Link to comment
Share on other sites

  • 8 months later...
  • 2 weeks later...

@akbr nice plugin. I'm wondering how can I use your plugin and rorate around the center of a group? I've got some SVG-buttons which I want to animate from a open-button/plus-sign to a cross-sign or close-button.

                        <svg version="1.1" role="img" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="55px" height="55px" viewBox="0 0 70 70" xml:space="preserve">
                            <circle class="icon-bg" cx="35" cy="35" r="30"/>
                            <g>
                                <line x1="25" y1="25" x2="45" y2="45"/>
                                <line x1="25" y1="45" x2="45" y2="25"/>
                            </g>
                        </svg>
		var animIconsDetail = function() {
			var $workDetails 		= $( 'section#work-details' ),
				$anchors			= $workDetails.find( 'a.btn-close' ),
				backgroundColors 	= [],
				children 			= $workDetails.children( 'article' ),
				circleProps			= {
					size : {
						start 	: $($anchors[0]).find( '.icon-bg' ).attr( 'r' ),
						end 	: 35
					},
					opacity : {
						start	: $($anchors[0]).find( '.icon-bg' ).css( 'fill-opacity' ),
						end 	: .9	
					}
				},
				lineProps			= {
					width : {
						start 	: $($anchors[0]).find( 'line' ).css( 'stroke-width' ),
						end		: 5
					}
				},
				groupBBox = $($anchors[0]).find( 'g' )[0].getBBox(),
				pivotGroup = {
					x	: groupBBox.x + (groupBBox.width / 2),
					y 	: groupBBox.y + (groupBBox.height / 2) 
				};

				console.info(pivotGroup);

			children.each( function(index, elem){
				var bg = $(elem).css('background-color');
				backgroundColors.push(bg);
			});

			console.info($anchors, backgroundColors, circleProps.size.start);

			$anchors.each( function(index, elem){
				elem.circle	 = $(elem).find( 'circle' );
				elem.group	 = $(elem).find( 'g' );
				elem.line	 = $(elem).find( 'line' );
				elem.bgColor = backgroundColors[index];
			});

			$anchors.on({
				mouseenter	: function(event) {
					TweenMax.to(this.circle, duration, { attr: { r: circleProps.size.end }, css: {fillOpacity:  circleProps.opacity.end}, ease:easing});
					TweenMax.to(this.group, duration, {svg: {rotation: -45, scale: 1, localPivot: pivotGroup}, ease:easing});
					TweenMax.to(this.line, duration, {css: { stroke: this.bgColor, strokeWidth: lineProps.width.end}, ease:easing});
				},
				mouseleave	: function(event) {
					TweenMax.to(this.circle, duration, { attr: { r: circleProps.size.start }, css: {fillOpacity: circleProps.opacity.start }, ease:easing});
					TweenMax.to(this.group, duration, {svg: {rotation: 45, scale: 1, localPivot: pivotGroup}, ease:easing});
					TweenMax.to(this.line, duration, {css: {stroke: colorPallet[0], strokeWidth: lineProps.width.start}, ease:easing});
				}
			});
		};

the object pivotGroup holds the propper x and y coordinate for the center-position of the group. But I can't figure out how I could use these points in the Tween. You can find these tweens in the jquery on-method as second TweenMax.to(). 

 

When I outcomment line 354 and 355 of SvgPlugin.js group starts to rotate but localPivot doesn't do anything.

        //dx += t.attr("x");
        //dy += t.attr("y");
Edited by myradon
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...