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 / CSSconst é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 → letEz 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); // 100mapRange()
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 ------------------- 220Ha 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 1mapRange 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
- Mi a különbség
clamp()ésmapRange()között? - Miért hasznos, hogy a
mapRange()nem tud semmit a pointerről? - Miért tekintjük a
mappedSizeértéket state-nek? - Mit változtat közvetlenül a
render()?