Thursday, 6 September, 2018 UTC


Summary

In this article we will be looking at how we implemented the new animated logo of Scotch.io, a visual detail to complement all the improvements that the site has experienced. Something like the icing on the cake :)
For those who have not yet played a bit with the animation of the new logo, they can do so by moving the cursor inside (to resume animation) or outside (to pause animation) of the logo in the top left corner.
If you want to know all the details about how it was implemented, just keep reading!
Keeping the Waves Inside the Cup
One of the first things we had to do was to keep the waves inside the cup.
First we thought about cutting the waves using just a circular HTML element, using border-radius and overflow: hidden in the CSS. However, this was not possible, since the waves had to be at a height similar to what they are in the original Scotch.io logo. Therefore it was necessary to use an SVG clip-path region, which is shown in red color in the following image:
With this region in place, we could start to build the waves and animate them.
Building the Waves with HTML and SVG
Let's look at the basic HTML and SVG code to start developing the logo:
<div class="scotch-logo">
    <img class="scotch-logoimage" src="img/blank-glass.png">
    <svg class="scotch-logoliquid" viewBox="0 0 30 48">
        <defs>
            <clipPath id="clip-path--glass">
                <path class="liquid__path-container" d="M 8.6 1.5 c 0 13.33 -4.17 20 -3.75 23.33 a 9.17 8.33 0 0 0 20.83 0 c 0.42 -3.33 -3.75 -10 -3.75 -23.33 Z"></path>
            </clipPath>
        </defs>
        <g clip-path="url(#clip-path--glass)">
            <!-- Here will go the liquid waves -->
        </g>
    </svg>
</div>
As you can see, the basic structure is quite simple. We have an image, which is the empty cup in the logo, and some SVG elements to build the animation.
We have already defined the clip-path region that will help us show the waves only inside the cup. So let's see how we have defined the first wave:
<path class="liquidpath liquidpath--top" d="M -80 22 C -75.08 16 -69.08 16 -64.17 22 S -53.25 28 -48.33 22 S -37.42 16 -32.5 22 S -21.58 28 -16.67 22 S -5.75 16 -0.83 22 S 10.08 28 15 22 S 25.92 16 30.83 22 S 41.75 28 46.67 22 S 57.58 16 62.5 22 S 73.42 28 78.33 22 S 89.25 16 94.17 22 S 105.08 28 110 22 l 0 30 l -190 0"></path>
It is a simple SVG path, which we have built supporting us in a tool to build SVG paths like waves, that we already used in a previous tutorial.
The other wave was created using the same tool, testing different parameters and positions, to make our new logo as close as possible to the original.
At the end, with the help of some CSS transformations (translate specifically), we achieved a static logo, very similar to the original Scotch.io logo, only without the color difference for the intersection between the waves:
Later in this tutorial we will see how we added that third color!
Animating the Waves with CSS
With the waves in place, the most anticipated moment arrived: Animate them!
Actually we thought of a fairly simple animation, so that it would run smoothly, but that it would fulfill the main objective of being attractive enough. That's why we decided to animate the waves (SVG paths) with CSS translateX transformations, in opposite directions, and with a slight offset to give a touch of randomness.
After many tests, this was the final CSS code (SCSS) for the animation:
// Code for liquid waves
.liquid__path {
  animation: 1.5s linear infinite;

  // First (top) wave
  &--top {
    transform: translateX(0);
    animation-name: liquid-top;
  }

  // Second (bottom) wave
  &--bottom {
    transform: translateX(-27px);
    animation-name: liquid-bottom;
    // Little phase shift respect the top wave
    animation-duration: 1.6s;
    animation-delay: -0.7s;
  }
}

// Animation for the top wave
@keyframes liquid-top {
  100% {
    transform: translateX(-31.66px);
  }
}

// Animation for the bottom wave
@keyframes liquid-bottom {
  100% {
    transform: translateX(1.66px);
  }
}
Adding the Intersection Color for Waves
To add the third color, corresponding to the intersection between the waves, we thought of several options.
The first option that came to mind, was to use SVG filters to blend the two waves and get the third color. We quickly discarded that option because it did not have adequate browser support, and we would not have absolute control of the resulting color.
So then we thought about using a new clip-path, where the clipping region would be a copy of one of the waves, and the clipped region would be a copy of the other wave. Then we could arbitrarily assign any color we wanted to the intersection between the two waves.
So, the code that we had to add to our initial SVG code was the following:
<!-- New SVG code to add the intersection color -->
<defs>
    <clipPath id="clip-path--liquid">
        <path class="liquidpath liquidpath--top-clip" d="M -80 22 C -75.08 16 -69.08 16 -64.17 22 S -53.25 28 -48.33 22 S -37.42 16 -32.5 22 S -21.58 28 -16.67 22 S -5.75 16 -0.83 22 S 10.08 28 15 22 S 25.92 16 30.83 22 S 41.75 28 46.67 22 S 57.58 16 62.5 22 S 73.42 28 78.33 22 S 89.25 16 94.17 22 S 105.08 28 110 22 l 0 30 l -190 0"></path>
    </clipPath>
</defs>
<g clip-path="url(#clip-path--glass)">
    <g class="liquidpath--clip-container" clip-path="url(#clip-path--liquid)">
        <path class="liquidpath liquid__path--bottom-clip" d="M -70 24.5 C -65.92 18.5 -59.92 18.5 -55.83 24.5 S -45.75 30.5 -41.67 24.5 S -31.58 18.5 -27.5 24.5 S -17.42 30.5 -13.33 24.5 S -3.25 18.5 0.83 24.5 S 10.92 30.5 15 24.5 S 25.08 18.5 29.17 24.5 S 39.25 30.5 43.33 24.5 S 53.42 18.5 57.5 24.5 S 67.58 30.5 71.67 24.5 S 81.75 18.5 85.83 24.5 S 95.92 30.5 100 24.5 l 0 30 l -170 0"></path>
    </g>
</g>
To also animate these copies of our original waves, we only had to add the new selectors to the CSS code that we already had, nothing more.
Fixing Firefox Issue with the Interseccion Color
Just after adding the color of the intersection between the waves, during the tests, we could verify that all the browsers ran the animation without problems, except Firefox.
Firefox does not allow to animate with CSS the elements that have been defined within the defs tags, in our case the clip-path element. This is not a bug, since Firefox is honoring the SVG specification in this regard, being the other browsers those that allow a little more liberties.
But for practical purposes, this was definitely an issue that we had to solve, or at least find a workaround for, since the animation did not looks good.
The workaround that we used was to simply hide that third color for Firefox, avoiding the problem of not being able to animate it. Another solution could have been to use Javascript to perform the animations, but we wanted to keep the CSS animations, and also avoid adding extra dependencies only for this visual detail.
So, what we did was:
  1. Hide the third color initially through a CSS class.
  2. Detect if the browser that was being used was Firefox.
  3. In case of NOT being Firefox, we remove the CSS class, to show the third color properly.
Adding Drops
So far, the animation looked great, but we just wanted to add another small detail: drops.
It was fairly simple to add them into the SVG code. Just two small SVG circles did the job:
<circle class="liquiddrop liquiddrop--top liquiddrop--1" cx="18.3" cy="3.3" r="1.5"></circle>
<circle class="liquiddrop liquiddrop--bottom liquiddrop--2" cx="12" cy="5" r="1.5"></circle>
Next we just needed to animate them with CSS as well:
// Code for drops
.liquid__drop {
  animation: 4.5s ease-in-out infinite;

  // First drop
  &--1 {
    transform: translate(0, 25px);
    animation-name: drop-1;
    animation-delay: 2s;
  }

  // Second drop
  &--2 {
    transform: translate(0, 25px);
    animation-name: drop-2;
  }
}

// Animation for the first drop
@keyframes drop-1 {
  20% { transform: translate(0, 25px); }
  40% { transform: translate(-2px, 10px); }
  60% { transform: translate(-4px, 25px); }
}

// Animation for the second drop
@keyframes drop-2 {
  20% { transform: translate(0, 25px); }
  40% { transform: translate(2px, 5px); }
  60% { transform: translate(4px, 25px); }
}
Finally, to integrate the animation to the new Scotch.io site, we implemented a simple logic to pause and resume the animation from Javascript, in order to start or stop the animation in different situations.
Conclusion
And that's how we managed to develop a nice and simple animation for the logo of the new Scotch.io site.
If you want to see the complete code, or even play with it, you can do it in the Codepen demo.
We hope you have enjoyed this tutorial and that it has been useful!