SVG Morph
Morphing SVG shape using SMIL. Multiple keyframes.
by the_voder
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<!--
REFERENCES:
(Very) comprehensive guide to SVG animation
https://css-tricks.com/guide-svg-animations-smil/
-->
<!-- Button container element (link for accessibility) -->
<a id="moonBTN" href="https://www.google.co.uk/">
<!-- SVG element definition -->
<svg id="moon" viewbox="0 0 1000 1000">
<!-- SVG internal stylesheet. Works like ordinary CSS styles, but some properties are unique to SVG (ie "fill") -->
<style type="text/css">
.svgMoon { fill: #fff; }
.svgMoonBG { fill: #222; }
</style>
<!-- Moon background (delete this and associated CSS anove if not needed) -->
<path class="svgMoonBG" d="M 1000,500c0,276.14-224.55,500-501.54,500C219.68,1000,0,776.14,0,500S226.86,0,498.46,0 C775.45,0,1000,223.86,1000,500 Z" />
<!-- Moon path (begins with points for full moon) -->
<path class="svgMoon" d="M 1000,500c0,276.14-224.55,500-501.54,500C219.68,1000,0,776.14,0,500S226.86,0,498.46,0 C775.45,0,1000,223.86,1000,500 Z">
<!-- Define SVG animation. "Values" is list of points for 3 animation keyframes-->
<animate
id="moonAnim"
attributeName="d"
dur="500ms"
repeatCount="0"
begin="indefinite"
fill="freeze"
calcMode="linear"
keyTimes="0; 0.7; 1"
values="M 1000,500c0,276.14-224.55,500-501.54,500C219.68,1000,0,776.14,0,500S226.86,0,498.46,0 C775.45,0,1000,223.86,1000,500 Z;
M 1000,500c0,276.14-224.55,500-501.54,500c0-86,1.54-223.86,1.54-500s-1.54-380-1.54-500 C775.45,0,1000,223.86,1000,500 Z;
M 1000,500c0,276.14-224.55,500-501.54,500c57.4-53.48,236.4-223.86,236.4-500 S565.08,53.48,498.46,0C775.45,0,1000,223.86,1000,500 Z;"
/>
</path>
</svg>
</a>
CSS
body {
overflow: hidden;
background-color: #111;
}
/* Moon button container */
#moonBTN {
display: block;
width: 20%;
margin:100px auto 0 auto;
cursor: pointer;
}
/* SVG element */
#moon {
transform: rotate(30deg);
}
JavaScript
// Create handle to SVG animation element and button container
let anim = document.getElementById("moonAnim");
let btn = document.getElementById("moonBTN");
// Listen for click on button element
btn.addEventListener('click', function(e) {
// Prevent default action (ie loading another page if element is link)
e.preventDefault();
// Start animation
anim.beginElement();
}, false);
// Listen for animation end
anim.addEventListener('endEvent', function(e) {
// Load page when animation ends. URL extracted from btn link
//window.location.href = btn.getAttribute('href');
}, false);