Newsletter • Issue 23

Scrolling Sodas, Generative Share Cards, and GSAP Utility Functions

Howdy there, partner! Welcome to another delightful ride on the Web Dev Trail! We’ve got a packed issue this week, so make sure you stick with us to take in all the sights. We’ll be looking at an awesome CSS soda can illusion, some generative social images, the GSAP utility functions, and a few other helpful things.

I hope this eases you into the weekend with a bit of fun. Let’s ride!


United Sodas of America

Web agency House of 207 created a great scrolling effect for soda brand, United Sodas of America. As you scroll it feels like the cans spin past you because of a really clever technique.

A row of colorful soda cans

The cans spinning in a gif

I think it’s even more fun on mobile, so make sure you check it out on both screen sizes.

So how are they doing this? 3D Cans?

Nope, just a really great use of two images. The ‘can’ image is solid at the top and bottom, but partially transparent in the middle, only providing shadows and highlights.

Showing the label off of the can

Then as the user scrolls down, the label image is moved left. The key is an SVG mask that’s used as a clip-path on just the label.

I made a quick CodePen demo to isolate the effect. It’s not the exact method that House of 207 used, but close. Scroll to make the label move, and toggle the checkbox at the top right to remove the clip path.

The effect works because if the can is spinning, but our camera and the lights in the room are stationary, the reflections of the can won’t change. There would be more perspective distortion of the label as it neared the edges, but it’s still a very effective illusion.

On the individual pages they give you a grabby-hand cursor and you can ‘spin’ the bottle to read the nutrition information on the back of the can.

One can with a grabby hand on it to show you can drag the can to spin it

It’s a great effect, and when tied to the user’s scroll, makes for a memorable experience.

Check Out United Sodas

Generative SVG Social Images

Check out this delightful and useful design that George Francis has created. If you have your own blog you know the pain of needing to design a snappy share image that’s readable, eye-catching, and all your own. Well, why don’t you generate a random one?

Generate your text alignment, colors, and shapes, then edit the text to match your content. Then click ‘Save’ and you get a PNG to use on your website!

George is using a bit of clever color theory in this generator. It chooses a random base hue and a saturation from 60-90, and generates the rest based on those values.

const baseHue = random(0, 360);
const saturation = random(60, 90);

baseColor = `hsl(${baseHue}, ${saturation}%, 60%)`;
baseColorWhite = `hsl(${baseHue}, ${saturation}%, 97%)`;
baseColorBlack = `hsl(${baseHue}, 95%, 3%)`;

complimentaryColor1 = `hsl(${baseHue + 90}, ${saturation}%, 60%)`;
complimentaryColor2 = `hsl(${baseHue + 180}, ${saturation}%, 60%)`;

By adding 90 and 180 to the first value, George is using what’s called ‘split complementary colors.’ It makes a ‘Y’ from the base color like this.

the colors red, teal, and green, and a color wheel showing how they are across from each other.

This is a great trick for generating colors that are guaranteed to work well together.

The other great part of this pen is how George is avoiding text and shape collisions. Each element gets a box drawn around its outer boundaries. It then checks to make sure that its boundary isn’t overlapping another shape’s.

George details all of this in a thorough tutorial on Dev.to.

Check Out the Tutorial

GSAP Utility Functions

Did you know that the animation library GSAP comes with a bunch of helpful utility methods? Here’s a couple that you might want to use on your next project.

gsap.utils.random(0, 100); will give you a random number between 0 and 100. It’s a bit tidier than writing your own solution and has a few more tricks it can do, too.

wrap() takes an array and an index, and if that index is larger than the number of items in the array, it wraps back to the start.

If I’m making a string of Christmas Lights where the pattern is ["red", "blue", "green", "orange"], I can use wrap() to make sure the pattern continues beyond the first 4 lights.

gsap.utils.wrap(["red", "blue", "green", "orange"], 6);

The 6 is the index I want, which will wrap around and return “green.”

Read more on wrap().

If you don’t want to wrap, but instead impose a minimum and maximum, clamp() is your friend. It’s similar in concept to the handy CSS clamp, but has a different API.

clamp(minimum, maximum, valueToClamp)

Here’s clamp examples from the docs:

// set the clamping range to between 0 and 100, and clamp 105
gsap.utils.clamp(0, 100, 105); // returns 100

// in the same range, clamp -50
gsap.utils.clamp(0, 100, -50); // returns 0

// and clamp 20
gsap.utils.clamp(0, 100, 20); // returns 20

If your project isn’t using GSAP, don’t add GSAP just to pick a random number. But if you’re already using it, these are great to lean on for these sorts of small tasks.

Check Out the Full List

Pen.new

Here’s a quick tip if you’re like me and find yourself creating a new CodePen a few times a day. Typing the URL pen.new into your browser will create a new CodePen and save you a few clicks.

There are a couple of other handy .new URLs out there.


Oldie but a Goodie

Here’s a Frontend Horse article you might have missed on the amazing illustrations of Ricardo Oliva Alonso. These 3D pieces look like they’re made in Three.js, but are actually pure HTML and CSS.

Colorful 3d CSS illustrations

We go into detail on his process, and Ricardo was even kind enough to share his snippets with us so we can make our own! It’s one of my most popular articles for a reason - check it out!

Check Out 3D CSS

Horse Fact

The average horse lives to be 33 years old, but some live for more than 50 years. The oldest horse to ever live was “Old Billy,” who lived to be 62! Talk about having a self-fulfilling name. In related news, I will now go by the name “Old Alex.”


So Long, Partner

That’s it for this week. Thanks for hitting the trail with us! Special thanks to Brandon Iffert from House of 207 for answering my questions!

Follow @FrontendHorse on Twitter, and if you enjoyed this, I’d be over the moon if you share it with a friend or tweet about it.

It’s the end of the trail for now, but I’ll see you next week. Take care.

Your Neigh-bor,
Alex