• October 19, 2017Dynamic Shape Overlays with SVG

    • /
    • /
    • in Best News, Freebies
    • /
    • by Juancho

    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.

    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>

    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:





    We hope you enjoyed this effect and find it useful!


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

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

    Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 54 other subscribers