The component that also covers SVG morphing, with similar functionality as for the SVG Morph component, but with a different implementation for value processing and animation setup.
Animate SVG paths with cubic-bezier path commands and improved performance.
The KUTE.js SVG Cubic Morph component enables animation for the d (description) presentation attribute and is the latest in all the SVG components.
The main difference with the other SVG Morph component is the fact that this time we're using some path processing scripts borrowed from Raphael.js and other libraries to convert all path commands into cubic-bezier path commands.
This component will process paths and out of the box will provide the closest possible interpolation by default. It comes with two tween options to help you manage the morphing animation in certain conditions:
A series of familiar options to optimize the animation for every situation.
To enhance processing and improve the morphing animation, in certain cases you will need to control the outcome via two options to reverse paths.
The first morphing animation example is a transition from a rectangle into a star, just like for the other component.
<svg id="morph-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
<path id="rectangle" class="bg-lime" d="M38.01,5.653h526.531c17.905,0,32.422,14.516,32.422,32.422v526.531 c0,17.905-14.517,32.422-32.422,32.422H38.01c-17.906,0-32.422-14.517-32.422-32.422V38.075C5.588,20.169,20.104,5.653,38.01,5.653z"/>
<path id="star" style="visibility:hidden" d="M301.113,12.011l99.25,179.996l201.864,38.778L461.706,380.808 l25.508,203.958l-186.101-87.287L115.01,584.766l25.507-203.958L0,230.785l201.86-38.778L301.113,12.011"/>
</svg>
Now we can apply both .to()
and fromTo()
methods:
// the fromTo() method
var tween = KUTE.fromTo('#rectangle', {path: '#rectangle' }, { path: '#star' }).start();
// OR
// the to() method will take the path's d attribute value and use it as start value
var tween = KUTE.to('#rectangle', { path: '#star' }).start();
// OR
// simply pass in a valid path string without the need to have two paths in your SVG
var tween = KUTE.to('#rectangle', { path: 'M301.113,12.011l99.25,179.996l201.864,38.778L461.706,380.808l25.508,203.958l-186.101-87.287L115.01,584.766l25.507-203.958L0,230.785l201.86-38.778L301.113,12.011' }).start();
By default, the component will process the paths as authored and deliver its best without any option required, like for the first red rectangle below which applies to any of the above invocations:
The second blue shape and its corresponding end shape have been edited by adding additional curve points using a vector graphics editor to match the amount of points in both shapes as well as to optimize their travel distance during the animation. You can use the same technique on your shapes to control the animation to your style.
Chris Coyier wrote an excelent article to explain how SVG morphing animation works, it should give you a pretty good idea on the concept, terminology.
In other cases, you may want to morph paths that have subpaths. Let's have a look at the following SVG:
<svg id="multi-morph-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
<path id="w1" d="M412.23 511.914c-47.708-24.518-94.086-36.958-137.88-36.958-5.956 0-11.952 0.18-17.948 0.708-55.88 4.624-106.922 19.368-139.75 30.828-8.708 3.198-17.634 6.576-26.83 10.306l-89.822 311.394c61.702-22.832 116.292-33.938 166.27-33.938 80.846 0 139.528 30.208 187.992 61.304 22.962-77.918 78.044-266.09 94.482-322.324-11.95-7.284-24.076-14.57-36.514-21.32z
m116.118 79.156l-90.446 314.148c26.832 15.372 117.098 64.05 186.212 64.05 55.792 0 118.252-14.296 190.834-43.792l86.356-301.976c-58.632 18.922-114.876 28.52-167.464 28.52-95.95 0-163.114-31.098-205.492-60.95z
m-235.526-222.28c77.118 0.798 134.152 30.208 181.416 60.502l92.752-317.344c-19.546-11.196-70.806-39.094-107.858-48.6-24.386-5.684-50.02-8.616-77.204-8.616-51.796 0.976-108.388 13.946-172.888 39.8l-88.44 310.596c64.808-24.436 120.644-36.34 172.086-36.34 0.046 0.002 0.136 0.002 0.136 0.002z
m731.178-170.666c-58.814 22.832-116.208 34.466-171.028 34.466-91.686 0-159.292-31.802-203.094-62.366l-91.95 318.236c61.746 39.708 128.29 59.878 198.122 59.878 56.948 0 115.94-13.68 175.462-40.688l-0.182-2.222 3.734-0.886 88.936-306.418z"/>
<path id="w2" d="M0 187.396l367.2-50.6v354.798h-367.2v-304.2z
m0 649.2v-299.798h367.2v350.398z
m407.6 56v-355.798h488.4v423.2z
m0-761.2l488.4-67.4v427.6h-488.4v-360.2z"/>
</svg>
Similar to the svgMorph component, this component doesn't provide multipath processing so we should split the sub-paths into multiple <path> shapes, analyze and associate them in a way that corresponding shapes are close and their points travel the least possible distance.
Now since we've worked with these paths before, the first example below showcases how the svgCubicMorph component handles it by default, using the reverseSecondPath:true
option for all tweens because
each shape have a slightly different position from its corresponding shape. The following example was made possible by editing the shapes with a vector graphics editor. The last example showcases a creative use of
association between starting and end shapes. Let's have a look:
Make sure to check the markup here as well as the svgCubicMorph.js for a full code review.
The same preparation apply here, however the outcome is a bit different with cubic-bezier path commands, as shown in the first example. For the next two examples, the shapes have been edited for a better outcome. Let's have a look:
So the technique involves creating <mask>
elements, splitting multipath shapes into multiple <path>
shapes, matching the amount of starting and ending shapes by duplicating
an existing shape or by sampling another shape for the same purpose, editing shapes for more accurate point-to-point animation, as well as various options to optimize the visual presentation.
That's it, you now mastered the SVG Cubic Morph component.
path
SVGElements, you might need a convertToPath utility.fill-rule="evenodd"
specific SVG attribute, you must make sure you check your shapes in that regard as well.