Dynamic Shape Overlays with SVG

Some ideas for multi-layered SVG shape overlays that get generated dynamically with adjustable properties for a variety of effects.
ShapeOverlays

Today we’d like to share another way of achieving morphing page transitions. This time, we’ll generate multiple SVG curves with JavaScript, making many different looking shapes possible. By controlling the individual coordinates of the several layers of SVG paths, the curved shapes animate to a rectangle (the overlay) with a gooey motion. We use some nice easing functions from glsl-easings and by tuning the curve, speed and the delay value, we can generate many interesting effects.

Attention: We use some new CSS properties in the demos; please view them with a modern browsers.

This demo is kindly sponsored by HelloSign API: The dev friendly eSign.

Building the SVG

Let’s have a look at the SVG which we will use to insert the path coordinates dynamically.
First, we’ll make sure that the whole SVG and the overlay paths are stretched to the size of the screen. For that, we’ll set the preserveAspectRatio attribute to none. Depending on how many layers we want, we’ll create that amount of paths:

<svg class="shape-overlays" viewBox="0 0 100 100" preserveAspectRatio="none">
  <path class="shape-overlays__path"></path>
  <path class="shape-overlays__path"></path>
  <path class="shape-overlays__path"></path>
</svg>

The styles that will allow the SVG to match the size of the browser window looks as follows:

.shape-overlays {
  width: 100vw;
  height: 100vh;
  position: fixed;
  top: 0; 
  left: 0;
}

Each path element corresponds to a layer of the overlay. We’ll specify the fill for each of these layers in our CSS. The last path element is the background that stays after the overlay expansion:

.shape-overlays path:nth-of-type(1) { fill: #c4dbea; }
.shape-overlays path:nth-of-type(2) { fill: #4c688b; }
.shape-overlays path:nth-of-type(3) { fill: #2e496a; }

Note that in our demos, we make use of CSS custom properties to set the path colors.

The JavaScript

For our demos, we define an overlay control class that allows us to set and control a couple of things. By changing each value, you can create unique looking shapes and effects:

class ShapeOverlays {
  constructor(elm) {
    this.elm = elm; // Parent SVG element.
    this.path = elm.querySelectorAll('path'); // Path elements in parent SVG. These are the layers of the overlay.
    this.numPoints = 18; // Number of control points for Bezier Curve.
    this.duration = 600; // Animation duration of one path element.
    this.delayPointsArray = []; // Array of control points for Bezier Curve.
    this.delayPointsMax = 300; // Max of delay value in all control points.
    this.delayPerPath = 60; // Delay value per path.
    this.timeStart = Date.now();
    this.isOpened = false;
  }
  ...
}
const elmOverlay = document.querySelector('.shape-overlays');
const overlay = new ShapeOverlays(elmOverlay);

Further methods that determine the appearance of the overlay are the ShapeOverlays.toggle() method and the ShapeOverlays.updatePath() method.

The ShapeOverlays.toggle() method has the function of opening and closing the overlay, and also of setting the delay value of each control point for every time it opens and closes. It is not necessary to set the delay value every time, but by altering it, it will create some nice randomness.

The ShapeOverlays.updatePath() controls the animation by specifying the easing function.

For example, in demo 1, the same easing function is used for all control points, and the delay value is set like a fine wave using trigonometric functions, so that we get a “melting” appearance.

toggle() {
  const range = 4 * Math.random() + 6;
  for (var i = 0; i < this.numPoints; i++) {
    const radian = i / (this.numPoints - 1) * Math.PI;
    this.delayPointsArray[i] = (Math.sin(-radian) + Math.sin(-radian * range) + 2) / 4 * this.delayPointsMax;
  }
  ...
}

updatePath(time) {
  const points = [];
  for (var i = 0; i < this.numPoints; i++) {
    points[i] = ease.cubicInOut(Math.min(Math.max(time - this.delayPointsArray[i], 0) / this.duration, 1)) * 100
  }
  ...
}

In our demos we use this effect to create an overlay in order to show a menu in the end of the animation. But it could also be used for other types of transitions, like page transitions or scroll effects. Your imagination is the limit.

Here are a couple of screenshots:

ShapeOverlays_01

ShapeOverlays_02

ShapeOverlays_03

ShapeOverlays_04

We hope you enjoyed this effect and find it useful!

Credits

  • glsl-easings by glslify. Easing functions that use to demos are based on the code of glsl-easings module.
Previous:
Next:

Tagged with:

Related Articles

CSS Reference

Learn about all important CSS properties from the basics with our extensive and easy-to-read CSS Reference.

It doesn't matter if you are a beginner or intermediate, start learning CSS now.

Feedback 11

  1. 1

    Great work on this one ! Love this animations, pretty fluid compared with other method ! Vizions agence de communication

  2. 3

    Awesome stuff. I want to use demo3 as a preloader. How do I make it show opened and when the page finishes loading I would like to close it?

  3. 4

    Awesome…another super stuff. I love the last demo. Thanks a lot for sharing with this world. Keep always rocking.

  4. 7

    First I got to say that I love this site. I’ve learned so much through the years with all the tutorials. But I miss the old days when you guys have more variety of content (The quality is still the same, pretty high!). Nowadays is all about css morphing. Not to criticize but may be this is the sentiment of many other users.

    That said, keep up the good work! Awesome post!

Follow this discussion

Leave a Comment