Creative Technology Knowledge
Learn · System → Code

State, clamp, mapRange és render

Hogyan tároljuk az aktuális állapotot, hogyan alakítunk át tartományokat, és hogyan lesz a state-ből megjelenés?

Becsült olvasási idő: 12–15 perc

Kulcsfogalmak: const · let · state · clamp · mapRange · render A Signal Lab lényege nem a kör mozgatása, hanem az adat útja.

pointer data
   ↓
clamp / mapRange
   ↓
state
   ↓
render
   ↓
DOM / CSS

const és let

const MIN_SIZE = 48;
let pointerX = 0;

const esetén a változóhoz tartozó kötést nem rendeljük újra. let esetén később új értéket adhatunk neki.

Kezdő szabályként:

nem akarom újraértékelni → const
változni fog az érték    → let

Ez azonban nem azt jelenti, hogy minden let automatikusan state.

State

let pointerX = 0;
let pointerY = 0;
let mappedSize = 120;
let mappedRoundness = 50;

Ezek az aktuális működési állapot részei. A render() később ezekből olvas.

clamp()

function clamp(value, minimum, maximum) {
  return Math.min(Math.max(value, minimum), maximum);
}

A clamp korlátoz, nem átskáláz.

clamp(50, 0, 100);   // 50
clamp(-20, 0, 100);  // 0
clamp(170, 0, 100);  // 100

mapRange()

function mapRange(value, inputMin, inputMax, outputMin, outputMax) {
  const normalized = (value - inputMin) / (inputMax - inputMin);
  return outputMin + normalized * (outputMax - outputMin);
}

A mapRange() egyik tartományból egy másikba képez át.

INPUT:   0 ------------------- stage width
OUTPUT: 48 ------------------- 220

Ha az input félúton van, az output is félúton lesz.

Normalizálás

A függvény első sora azt számolja ki, hol helyezkedik el az érték az inputtartományban.

const normalized = (value - inputMin) / (inputMax - inputMin);

Tipikusan 0 és 1 közötti arányt kapunk:

inputMin          middle           inputMax
   0%               50%              100%
   0                0.5                 1

mapRange nem tud semmit a pointerről

Ez fontos absztrakció. A függvény csak számokat kap és számot ad vissza. Ezért használható méretre, opacityre, hangerőre, rotációra, sebességre vagy bármilyen más számszerű paraméterre.

Fordított mapping

mappedRoundness = mapRange(
  pointerY,
  0,
  bounds.height,
  MAX_ROUNDNESS,
  MIN_ROUNDNESS,
);

Az outputtartomány itt fordított, ezért lefelé mozgatva a pointert az érték csökken. Egy viselkedést sokszor egyetlen mapping megfordításával is teljesen más érzetűvé tehetünk.

render()

function render() {
  signal.style.left = `${pointerX}px`;
  signal.style.top = `${pointerY}px`;
  signal.style.width = `${mappedSize}px`;
  signal.style.height = `${mappedSize}px`;
  signal.style.borderRadius = `${mappedRoundness}%`;
}

A render() nem inputot olvas és nem mappinget számol. Az aktuális state alapján frissíti a DOM/CSS állapotát.

.style és .textContent

signal.style.left = "200px";
xValue.textContent = "200";

A .style az elem inline CSS-stílusát módosítja. A .textContent az elem szöveges tartalmát.

Template literal

`${pointerX}px`

Ha pointerX értéke 200, az eredmény a "200px" string. A CSS-nek a szám mellett mértékegységre is szüksége van.

reset()

A reset() az aktuális stage-méret alapján újraszámolja az alapállapotot, majd renderel. Ezért hívjuk meg induláskor és resize után is.

Ellenőrző kérdések

  1. Mi a különbség clamp() és mapRange() között?
  2. Miért hasznos, hogy a mapRange() nem tud semmit a pointerről?
  3. Miért tekintjük a mappedSize értéket state-nek?
  4. Mit változtat közvetlenül a render()?

On this page