Eleventy in a Box
A premium Eleventy starter kit for designers and developers who want to spend less time setting up the same project structure and more time designing distinctive websites.
Lately, while I’ve been making my Toon Titles and writing about SVG animations, I’ve been pondering where the sweet spot is between CSS and GSAP for animations. This Toon Title, featuring Hanna Barbera’s Quick Draw McGraw in his alter ego El Kabong, illustrates it nicely.
El Kabong was Quick Draw’s spoof of Zorro. He’d swing down on a rope, shout “OLÉ!”, and smash his enemies with a guitar. “KABOOOOOONG!” Like many Hanna-Barbera title cards of the time, this one was illustrated by Lawrence (Art) Goble. To recreate it in SVG, I built a file containing layered background elements, title text, and El Kabong himself.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 1080">
<path id="base" fill="url(#grad)" d="[…]"/>
<g id="bg">[…]</g>
<g id="text">[…]</g>
<g id="swing-group">[…]</g>
</svg>El Kabong is split into several pieces, ready for animation: head, body, cape, legs, tail, and tie.
<g id="swing-group">
<g id="quick-draw-head">[…]</g>
<g id="quick-draw-leg-back">[…]</g>
<g id="quick-draw-tail">[…]</g>
<g id="quick-draw-tie">[…]</g>
<g id="quick-draw-body">[…]</g>
<g id="quick-draw-head">[…]</g>
<g id="quick-draw-leg-front">[…]</g>
<g id="quick-draw-cape">[…]</g>
</g>My goal was to animate as much as possible using just CSS. Here’s a simple sway animation for his head:
#quick-draw-head {
animation-direction: alternate;
animation-duration: 1s;
animation-iteration-count: infinite;
animation-name: sway;
transform-origin: 50% 100%;
animation-timing-function: ease-in-out; }
@keyframes sway {
from { rotate: -2deg; }
to { rotate: 2deg; }
}Using only CSS, I was able to get his legs kicking, tail wobbling, and cape flapping. That ambient movement brings the scene to life, and for many uses, it would be enough. But I wanted more.
El Kabong swings in from above, so I needed his whole body to pivot. With GSAP, that’s easy:
gsap.fromTo("#swing-group", {
rotate: 5,
transformOrigin: "1920px 0px"
}, {
rotate: -5,
duration: 5,
ease: "sine.inOut",
yoyo: true,
repeat: -1,
transformOrigin: "1920px 0px"
});But why introduce a dependency when the same effect is achievable using CSS?
#swing-group {
animation-duration: 5s;
animation-iteration-count: infinite;
animation-name: swing;
animation-timing-function: ease-in-out;
animation-direction: alternate;
transform-box: fill-box;
transform-origin: 1920px 0px;
}So, why use GSAP at all?
Because I wanted El Kabong’s cape to morph shape as he swings. And that’s where things change. CSS can’t morph between paths unless they have the exact same number of points, which mine didn’t. I could’ve rewritten them to match, or tried to morph them manually in JavaScript. But GSAP’s MorphSVGPlugin handles all that elegantly.
gsap.registerPlugin(MorphSVGPlugin);
const originalPath = "[…]";
const morphPath = "[…]";
gsap.to("#cape-path", {
duration: 2,
repeat: -1,
yoyo: true,
ease: "sine.inOut",
morphSVG: { shape: morphPath }
});This means loading the GSAP library core and their MorphSVGPlugin, which adds significantly to the weight, so I need to be sure that this animation is key to the overall feel of the animation.
This is the decision I face every time I animate a scene: When is a library like GSAP worth it? And once it’s loaded, should I use it for everything, or stick to CSS where I can?
There’s no perfect answer. But in the case of El Kabong, mixing CSS for ambient motion and GSAP for advanced morphing hit the sweet spot.
“KABOOOOOONG!”
A premium Eleventy starter kit for designers and developers who want to spend less time setting up the same project structure and more time designing distinctive websites.
Contract Killer is plain and simple and there’s no legal jargon. It’s customisable to suit your business and has been used on countless web projects since 2008.
Free compound grid and modular grid layout generators, plus a set of HTML/CSS layout templates you can call on to make more interesting layouts, available to buy.