Animating with Dynamic Elements

Something fun I have been playing with :slight_smile:

Octopus and Ink

See animated version: https://twitter.com/kirupa/status/1696729311028576321

Code:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Animating Dynamic Elements</title>

  <style>
    body {
      margin: 0;
      padding: 0;

      width: 100vw;
      height: 100vh;

      display: grid;
      place-items: center;
    }
    .container {
      margin: 100px;
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    .main {
      display: grid;
      place-items: center;
    }

    .octopus {
      border: none;
      background: none;
      cursor: pointer;
    }

    .octopus:hover {
      transform:scale(1.1, 1.1);
      filter: drop-shadow(0px 0px 5px #666);
    }

    .bubble {
      width: 100px;
      height: 100px;

      background-color: #111;
      border-radius: 50%;
      opacity: .8;

      animation-name: explode;
      animation-timing-function: cubic-bezier(.42, .52, .92, 1);
    }

    @keyframes explode {
      0% {
        translate: 0px 0px;
        scale: 1;
      }

      100% {
        translate: 100px 70px;
        scale: 0;
      }
    }

    .bubbleContainer {
      position: absolute;
      z-index: -10;
    }

    .bubbleWrapper {
      animation-name: slightlyRotate;
      animation-fill-mode: both;
      animation-timing-function: cubic-bezier(.42, .52, .92, 1);
    }

    @keyframes slightlyRotate {
      0% {
        rotate: 0deg;
      }

      100% {
        rotate: 60deg;
      }
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="main">
      <button class="octopus"><img src="https://www.kirupa.com/icon/1f419.svg" width="100"></button>
    </div>
  </div>

  <template id="bubbleTemplate">
    <div class="bubbleContainer">
      <div class="bubbleWrapper">
        <div class="bubble"></div>
      </div>
    </div>
  </template>

  <script>

    let button = document.querySelector(".octopus");
    button.addEventListener("click", play, false);
    window.addEventListener("animationend", removeContainer, false);

    let main = document.querySelector(".main");

    let numberOfBubbles = 20;

    function play(event) {
      let randomStarting = Math.round(Math.random() * 360);
      let template = document.querySelector("#bubbleTemplate").content;

      for (let i = 0; i < numberOfBubbles; i++) {

        let degree = i * Math.round(Math.random() * 360);

        template.querySelector(".bubble").style.animationDelay = (Math.random() * .2) + "s";
        template.querySelector(".bubble").style.animationDuration = (.2 + Math.random() * .5) + "s";

        template.querySelector(".bubbleWrapper").style.animationDuration = (.1 + Math.random() * 1) + "s";
        template.querySelector(".bubbleContainer").style.transform = "rotate(" + degree + "deg)";

        let newElement = main.appendChild(document.importNode(template, true));
      }
    }

    function removeContainer(event) {
      if (event.target.className === "bubble") {
        event.target.parentElement.parentElement.remove();
      }
    }
  </script>
</body>

</html>

Whale and Bubbles

See animated version: https://twitter.com/kirupa/status/1696729314891551045

Code:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Animating Dynamic Elements</title>

  <style>
    body {
      margin: 0;
      padding: 0;

      width: 100vw;
      height: 100vh;

      display: grid;
      place-items: center;
    }
    .container {
      margin: 100px;
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    .main {
      display: grid;
      place-items: center;
    }

    .whale {
      border: none;
      background: none;
    }

    .whale:hover {
      transform:scale(1.1, 1.1);
      filter: drop-shadow(0px 0px 5px #666);
    }

    .bubble {
      width: 100px;
      height: 100px;

      background-color: #badeff;
      border-radius: 50%;
      opacity: .8;

      animation-name: explode;
      animation-timing-function: cubic-bezier(.42, .52, .92, 1);
    }

    @keyframes explode {
      0% {
        translate: 0px 0px;
        scale: 1;
      }

      100% {
        translate: 100px 70px;
        scale: 0;
      }
    }

    .bubbleContainer {
      position: absolute;
      z-index: -10;
    }

    .bubbleWrapper {
      animation-name: slightlyRotate;
      animation-fill-mode: both;
      animation-timing-function: cubic-bezier(.42, .52, .92, 1);
    }

    @keyframes slightlyRotate {
      0% {
        rotate: 0deg;
      }

      100% {
        rotate: 60deg;
      }
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="main">
      <button class="whale"><img src="https://www.kirupa.com/icon/1f40b.svg" width="100"></button>
    </div>
  </div>

  <template id="bubbleTemplate">
    <div class="bubbleContainer">
      <div class="bubbleWrapper">
        <div class="bubble"></div>
      </div>
    </div>
  </template>

  <script>
    window.addEventListener("animationend", removeContainer, false);

    let main = document.querySelector(".main");

    let numberOfBubbles = 20;

    function play(timestamp) {
      let randomStarting = Math.round(Math.random() * 360);
      let template = document.querySelector("#bubbleTemplate").content;

      for (let i = 0; i < numberOfBubbles; i++) {

        let degree = i * Math.round(Math.random() * 360);

        template.querySelector(".bubble").style.animationDelay = (Math.random() * .2) + "s";
        template.querySelector(".bubble").style.animationDuration = (.5 + Math.random() * 2) + "s";

        template.querySelector(".bubbleWrapper").style.animationDuration = (.1 + Math.random() * 1) + "s";
        template.querySelector(".bubbleContainer").style.transform = "rotate(" + degree + "deg)";

        let newElement = main.appendChild(document.importNode(template, true));
      }
    }
    window.setInterval(play, 300);

    function removeContainer(event) {
      if (event.target.className === "bubble") {
        event.target.parentElement.parentElement.remove();
      }
    }
  </script>
</body>

</html>

Blueberries

See animated version: https://twitter.com/kirupa/status/1696729317907341571

Code:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Animating Dynamic Elements</title>

  <style>
    body {
      margin: 0;
      padding: 0;

      width: 100vw;
      height: 100vh;

      display: grid;
      place-items: center;
    }
    .container {
      margin: 100px;
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    .main {
      display: grid;
      place-items: center;
    }

    .blueberry {
      border: none;
      background: none;
    }

    .blueberry:hover {
      transform:scale(1.1, 1.1);
      filter: drop-shadow(0px 0px 5px #666);
    }

    .bubble {
      width: 150px;
      height: 150px;

      background-color: #fff389;
      border-radius: 50%;
      opacity: 1;

      animation-name: explode;
      animation-timing-function: cubic-bezier(.42, .52, .92, 1);
      animation-fill-mode: both;
    }

    @keyframes explode {
      0% {
        translate: 0px 0px;
        scale: 0;
      }

      100% {
        translate: 50px 50px;
        scale: 1;
        opacity: 0;
      }
    }

    .bubbleContainer {
      position: absolute;
      z-index: -10;
    }

    .bubbleWrapper {
      animation-name: slightlyRotate;
      animation-fill-mode: both;
      animation-timing-function: cubic-bezier(.42, .52, .92, 1);
    }

    @keyframes slightlyRotate {
      0% {
        rotate: 0deg;
      }

      100% {
        rotate: 60deg;
      }
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="main">
      <button class="blueberry"><img src="https://www.kirupa.com/icon/1fad0.svg" width="100"></button>
    </div>
  </div>

  <template id="bubbleTemplate">
    <div class="bubbleContainer">
      <div class="bubbleWrapper">
        <div class="bubble"></div>
      </div>
    </div>
  </template>

  <script>
    window.addEventListener("animationend", removeContainer, false);

    let main = document.querySelector(".main");

    let numberOfBubbles = 20;

    function play(timestamp) {
      let randomStarting = Math.round(Math.random() * 360);
      let template = document.querySelector("#bubbleTemplate").content;

      for (let i = 0; i < numberOfBubbles; i++) {

        let degree = i * Math.round(Math.random() * 360);

        template.querySelector(".bubble").style.animationDelay = (Math.random() * .2) + "s";
        template.querySelector(".bubble").style.animationDuration = (1 + Math.random() * 4) + "s";

        let l_color = 80 + Math.random() * 10;
        let c_color = 10 + Math.random() * 70;
        let h_color = 280 + Math.random() * 10;

        template.querySelector(".bubble").style.backgroundColor = `lch(${l_color}% ${c_color}% ${h_color})`;

        template.querySelector(".bubbleWrapper").style.animationDuration = (.1 + Math.random() * 1) + "s";
        template.querySelector(".bubbleContainer").style.transform = "rotate(" + degree + "deg)";

        let newElement = main.appendChild(document.importNode(template, true));
      }
    }
    window.setInterval(play, 300);

    function removeContainer(event) {
      if (event.target.className === "bubble") {
        event.target.parentElement.parentElement.remove();
      }
    }
  </script>
</body>

</html>