We’ll be using a clipPath and a mask to invert SVG text. What can you use this for in the real world? A couple of examples would be a loader counting a percentage or a hover effect on a button. It’s a pretty easy effect to create.
Setting up your SVG
You can use any SVG you like. For my example, I’m using a simple 500×100 SVG with text centered in middle of the stage.
<svg id="demo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 100" width="500" height="100"> <rect x="0" y="0" width="500" height="100" fill="#fff" /> <text text-anchor="middle" x="250" y="60" font-size="36">Change the text</text> </svg>
There are two important elements to make this happen.
- The rectangle, which will be our clipPath or mask.
- A duplicate text layer to be revealed by the rectangle.
Rectangle in our <defs>
The first thing we need is a rectangle in our clipPath elements. I’ve made this one the full size of the SVG, but you can choose any size you like. It just depends on the element you’re masking or clipping.
<defs> <clipPath id="theClipPath"> <rect class="masker" x="0" y="0" width="500" height="100" fill="#444" /> </clipPath> </defs>
Duplicate text layer
We’ll be placing a duplicate text layer on top of the original text. You can simply copy and paste the original into a new group like I did or you can use a bit of JavaScript to clone the original. That group will be revealed by the mask or clipPath.
<!-- Original --> <text text-anchor="middle" x="250" y="60" font-size="36">Change the text</text> <!-- Duplicate in a clipped or masked group --> <g clip-path="url(#theClipPath)"> <text text-anchor="middle" x="250" y="60" font-size="36" fill="white">Change the text</text> </g>
One more rectangle
You’ll also notice another rectangle with a class of masker
in the HTML.
<rect class="masker" x="0" y="0" width="500" height="100" fill="#42a6e0" />
The additional rectangle isn’t necessary for this to work. I’m just using it as a new background for the white text that we’ll be revealing. Since it’s lower in the stack, the text will appear on top of it. Giving it the same class as the rectangle in the clipPath allows GSAP to animate both with one tween.
The GSAP code
First, we set the scaleX property of the masking rectangle so the duplicate layer is not visible on page load.
gsap.set(".masker", { scaleX: 0, transformOrigin: "left center" });
After that, we just need to create a timeline and populate it with the two tweens. You’ll notice we originally set the transformOrigin to “left center” which is exactly what we want on the first tween. That way, the rectangle will expand from left to right. When we want it to shrink back down to the right, we set the transformOrigin to “right center”.
const tl = gsap .timeline({ paused: true, defaults: { duration: 1.2 } }) .to(".masker", { scaleX: 1, ease: "power2.in" }) .to(".masker", { scaleX: 0, ease: "power2", transformOrigin: "right center" });
The result
After setting up the SVG and creating the timeline, we now have a nice little SVG text effect.
See the Pen Invert SVG Text Color With A <clipPath> by Craig Roblewsky (@PointC) on CodePen.
A more complex demo
In the following demo, I’ve used a mask instead of a clipPath. The use of a mask is not really necessary in this case, but I wanted to show you both versions.
Using a mask is an excellent choice if you want the stroke to be part of the mask or perhaps, you want to use a gradient.
See the Pen Invert SVG Text Color With A Mask by Craig Roblewsky (@PointC) on CodePen.
Closing thoughts
I hope this gave you some inspiration for using a mask or clip-path in your next SVG project. Until next time, keep your pixels movin’.