<!-- part of article: https://utilitybend.com/blog/revisiting-svg-filters-my-forgotten-powerhouse-for-duotones-noise-and-other-effects -->

<svg width="0" height="0" viewBox="0 0 500 350" aria-hidden="true">

  <filter id="blurYHard">
    <feGaussianBlur stdDeviation="0 0"></feGaussianBlur>
  </filter>

  <filter id='noiseFilter'>
    <feTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch' />
  </filter>
</svg>
<div class="wrapper">
  <section></section>

  <div class="speed">
    <label for="slider">Speed</label>
    <input type="range" id="slider" min="0" max="10" step="0.1" value="5">
  </div>

  <div class="checkbox"><input type="checkbox" id="flip-it" /><label for="flip-it">Flip it</label></div>
  <div class="hamster-and-parachute">

    <svg class="parachute" xmlns="http://www.w3.org/2000/svg" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" viewBox="0 0 402 512.29">
      <path fill="seagreen" d="M133.59 360.6 3.33 208.96c-.76-.88-1.35-1.84-1.79-2.85-.43-.26-.8-.63-1.07-1.08a3.24 3.24 0 0 1-.47-1.68c-.02-98.1 51.53-160.36 117.71-187.54C143.55 5.2 171.62-.06 199.7 0c28.09.06 56.23 5.43 82.18 16.06 65.86 26.96 117.75 87.7 119.87 181.34.31 1.44.33 2.93.07 4.39l.01 1.57c0 1.32-.8 2.46-1.93 2.97a11 11 0 0 1-.59.76L269.04 360.81c6.89 1.88 13.07 5.56 17.98 10.47l1.37 1.53c6.53 7.22 10.52 16.74 10.52 27.07v71.91c0 11.05-4.57 21.16-11.9 28.52l-.12.12c-7.36 7.31-17.45 11.86-28.48 11.86H143.4c-11.05 0-21.16-4.56-28.53-11.89l-.12-.12c-7.3-7.35-11.85-17.44-11.85-28.49v-71.91c0-11.08 4.57-21.21 11.88-28.61 5.11-5.1 11.58-8.87 18.81-10.67zm106.84-1.21 134.94-159.22c-17.13-11.34-34.22-16.37-51.24-15.97-15.71.36-31.49 5.34-47.31 14.21l-48.14 160.98h11.75zm-35.51 0 47.58-159.1c-18.87-11.97-36.94-17.26-54.3-16.83-16.54.4-32.57 6-48.15 15.95l48.4 159.98h6.47zm-30.27 0-48.5-160.31c-18.62-10.86-37.1-15.43-55.46-14.88-16.03.48-32.05 4.86-48.04 12.36l139.88 162.83h12.12zm-31.25 19.54h115.01c11.53 0 20.96 9.47 20.96 20.95v71.91c0 11.48-9.48 20.96-20.96 20.96H143.4c-11.48 0-20.96-9.43-20.96-20.96v-71.91c0-11.52 9.43-20.95 20.96-20.95z" />
    </svg>
    <!-- hamster copy -->
    <div class="hamster">
      <div class="head">
        <div class="ears">
        </div>
        <div class="eyes">
          <div></div>
        </div>
        <div class="mouth">
          <div></div>
          <div></div>
        </div>
      </div>
      <div class="body">
        <div class="hands">
          <div></div>
        </div>
        <div class="feet"></div>
      </div>
    </div>
  </div>
</div>
:root {
  --slider-value: 0;
  --base-landscape-duration: 15s;
}

.checkbox {
  display: flex;
  align-items: center;
  position: fixed;
  top: 40px;
  left: 50%;
  z-index: 100;
}

section {
  height: 100dvh;
  background: skyblue;
  background-image: url("https://assets.codepen.io/159218/clouds.svg");
  background-size: auto 200vh;
  animation: landscape
    calc(var(--base-landscape-duration) / (var(--slider-value) * 0.5 + 1))
    linear infinite;

  filter: url(#blurYHard);
}

.wrapper {
  height: 100dvh;
  &::after {
    position: absolute;
    inset: 0;
    z-index: 1;
    border: 20px solid black;
    content: "";
  }
}

:root:has(input[type="checkbox"]:checked) section {
  animation-name: landscape-reverse;
}

body {
  margin: 0;
  font-family: Arial, Helvetica, sans-serif;
  font-weight: 700;
  font-size: 1.5rem;
}

.speed {
  position: fixed;
  top: 50%;
  right: 0;
  z-index: 3;
}

#slider {
  rotate: -90deg;
  accent-color: rebeccapurple;
  scale: 2;
}

svg[aria-hidden="true"] {
  position: absolute;
  height: 0;
  width: 0;
  visibility: hidden;
}

@keyframes landscape {
  from {
    background-position-y: 0%;
  }
  to {
    background-position-y: 200%;
  }
}

@keyframes landscape-reverse {
  from {
    background-position-y: 0%;
  }
  to {
    background-position-y: -200%;
  }
}

label {
  padding-left: 30px;
  cursor: pointer;
}

input[type="checkbox"] {
  scale: 3;
  accent-color: rebeccapurple;
}

/* hamster */

.head,
.eyes,
.feet,
.hands,
.mouth {
  &::before,
  &::after {
    content: "";
  }
}

.mouth {
  position: absolute;
  top: 30%;
  inset-inline: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 2;
  &::before {
    position: absolute;
    top: 50%;
    border-radius: 50%;
    aspect-ratio: 1;
    background: black;
    width: calc(var(--base-width) / 40);
  }
}

.mouth div {
  width: calc(var(--base-width) / 8);
  aspect-ratio: 1;
  border-radius: 50%;
  border-bottom: 5px solid black;
}

.hamster-and-parachute {
  position: fixed;
  top: 20%;
  left: 50%;
  animation: updown calc(20s / (var(--slider-value) * 0.5 + 1)) linear infinite;
  transform: translateX(-50%);
}

.parachute {
  width: 40vmin;
  display: block;
  z-index: 1;
}

@keyframes updown {
  0%,
  100% {
    translate: 0 0;
    rotate: 0;
  }
  33% {
    translate: -2% -2%;
    rotate: -5deg;
  }
  66% {
    translate: 2% 2%;
    rotate: 5deg;
  }
}

.hamster {
  --base-width: 20vmin;
  --body: calc(var(--base-width) * 1.3);
  --color: BurlyWood;
  --secondary-color: sienna;
  position: absolute;
  bottom: -10%;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin-inline: auto;
  z-index: 2;
}

.head {
  position: relative;
  width: var(--base-width);
  aspect-ratio: 1;
  background: var(--color);
  border-radius: 48%;
  background: radial-gradient(
    farthest-corner circle at 100% 0%,
    var(--secondary-color) 32% 0%,
    31%,
    var(--color) 100%
  );
  &::before,
  &::after {
    position: absolute;
    width: calc(var(--base-width) / 5);
    aspect-ratio: 5/ 4;
    border-radius: 50%;
    background: var(--color);
    top: -5%;
    left: calc(var(--base-width) / 7);
    rotate: -30deg;
    z-index: -1;
  }
  &::after {
    inset-inline: auto calc(var(--base-width) / 7);
    rotate: 30deg;
    background: var(--secondary-color);
  }
}

.eyes {
  position: absolute;
  top: 20%;
  width: 60%;
  left: 20%;
  display: grid;
  grid-template-columns: calc(var(--base-width) / 8) auto calc(
      var(--base-width) / 8
    );
  z-index: 1;
  &::before,
  &::after {
    width: calc(var(--base-width) / 10);
    aspect-ratio: 1;
    border-radius: 50%;
    background: black;
  }
}

.body {
  position: relative;
  width: var(--body);
  aspect-ratio: 8/6.5;
  background: var(--color);
  border-radius: 48%;
  margin-top: calc(var(--base-width) / -1.6);
}

.hands {
  position: absolute;
  top: 38%;
  width: 60%;
  left: 15%;
  display: grid;
  grid-template-columns: calc(var(--base-width) / 8) auto calc(
      var(--base-width) / 8
    );
  z-index: 1;
  &::before,
  &::after {
    border-right: calc(var(--base-width) / 30) solid black;
    border-bottom: calc(var(--base-width) / 30) solid black;
    width: calc(var(--body) / 6);
    aspect-ratio: 1;
    rotate: -45deg;
    transform: skew(20deg, 20deg);
  }
  &::after {
    rotate: 135deg;
  }
}

.feet {
  &::before,
  &::after {
    position: absolute;
    width: calc(var(--base-width) / 7);
    aspect-ratio: 3/4;
    border-radius: 50%;
    background: var(--color);
    bottom: -4%;
    left: calc(var(--base-width) / 3);
    rotate: 20deg;
    z-index: -1;
  }
  &::after {
    inset-inline: auto calc(var(--base-width) / 3);
    rotate: -20deg;
  }
}
const slider = document.getElementById("slider");
const root = document.documentElement;
const blurYHardFilter = document.querySelector("#blurYHard feGaussianBlur");

function updateEffects(value) {
  // Update CSS custom property
  root.style.setProperty("--slider-value", value);

  const blurYHardValue = (value / 10) * 15; // Max value is 10

  blurYHardFilter.setAttribute("stdDeviation", `0 ${blurYHardValue}`);
}

// Set initial values
updateEffects(slider.value);

slider.addEventListener("input", function () {
  const value = parseFloat(this.value);
  updateEffects(value);
});
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.