Transition

TRANSITION

Details

Playing around with the Decovar variable font. Every few seconds I randomize 14 of the different axis values between 0 and 1000. CSS shifts the shape over a few seconds and then back again. Colors get the same treatment.

Here's the bitty based code that does the work:

The HTML

<bitty-2-0 
  data-connect="TransitionMaker" 
  data-send="shift"
>
  <div class="shifter">TRANSITION</div>
</bitty-2-0>

The CSS

@font-face {
  font-family: 'Decovar';
  src: url('/fonts/DecovarAlpha-VF.ttf');
}

:root {
  --SKLA: 0; 
  --SKLB: 0; 
  --SKLD: 0; 
  --TRMA: 0; 
  --TRMB: 0; 
  --TRMC: 0; 
  --TRMD: 0; 
  --TRME: 0; 
  --TRMF: 0; 
  --TRMG: 0; 
  --TRMK: 0; 
  --TRML: 0; 
  --BLDA: 0; 
  --BLDB: 0;
  --l-light: 0;
  --c-light: 0;
  --h-light: ;
  --l-dark: 0.9;
  --c-dark: 0.0;
  --h-dark: 150;
  --color: oklch(var(--l-light) var(--c-light) var(--h-light));
}

@media (prefers-color-scheme: dark) {
  :root {
    --color: oklch(var(--l-dark) var(--c-dark) var(--h-dark));
  }
}

.shifter {
  display: flex;
  color: var(--color);
  font-size: min(15vw, 6rem);
  font-family: Decovar;
  font-variation-settings: 
    'SKLA' var(--SKLA), 
    'SKLB' var(--SKLB), 
    'SKLD' var(--SKLD), 
    'TRMA' var(--TRMA), 
    'TRMB' var(--TRMB), 
    'TRMC' var(--TRMC), 
    'TRMD' var(--TRMD), 
    'TRME' var(--TRME), 
    'TRMF' var(--TRMF), 
    'TRMG' var(--TRMG), 
    'TRMK' var(--TRMK), 
    'TRML' var(--TRML), 
    'BLDA' var(--BLDA), 
    'BLDB' var(--BLDB);
  justify-content: center;
  transition: font-variation-settings 2.6s, color 2.6s;
}

The JavaScript

const vars = {
  SKLA: {
    "min": 0,
    "max": 1000,
  },
  SKLB: {
    "min": 0,
    "max": 1000,
  },
  SKLD: {
    "min": 0,
    "max": 1000,
  },
  TRMA: {
    "min": 0,
    "max": 1000,
  },
  TRMB: {
    "min": 0,
    "max": 1000,
  },
  TRMC: {
    "min": 0,
    "max": 1000,
  },
  TRMD: {
    "min": 0,
    "max": 1000,
  },
  TRME: {
    "min": 0,
    "max": 1000,
  },
  TRMF: {
    "min": 0,
    "max": 1000,
  },
  TRMG: {
    "min": 0,
    "max": 1000,
  },
  TRMK: {
    "min": 0,
    "max": 1000,
  },
  TRML: {
    "min": 0,
    "max": 1000,
  },
  BLDA: {
    "min": 0,
    "max": 1000,
  },
  BLDB: {
    "min": 0,
    "max": 1000,
  },
  "l-light": {
    min: 0.7,
    max: 1,
  },
  "c-light": {
    min: 0.0,
    max: 0.2,
  },
  "h-light": {
    min: 0,
    max: 360,
  },
  "l-dark": {
    min: 0.7,
    max: 1,
  },
  "c-dark": {
    min: 0.0,
    max: 0.2,
  },
  "h-dark": {
    min: 0,
    max: 360,
  },
};

function randFloat(min, max) {
  return (Math.random() * (max - min + 1)) + min;
}

function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

window.TransitionMaker = class {
  #toggle = "max";
  async shift(_event, _el) {
    this.#toggle = this.#toggle === "min" ? "max" : "min";
    for (let axis of Object.keys(vars)) {
      document.documentElement.style.setProperty(
        `--${axis}`,
        randFloat(vars[axis].min, vars[axis][this.#toggle]),
      );
    }
    await sleep(3000);
    this.api.forward(null, "shift");
  }
};