P.S. Při psaní tohoto kódu nebyly použity žádné moduly 😆
Pokud hledáte zdrojový kód, pak je k dispozici ve videu 😉
Podpořte prosím sledováním tohoto videa 😢
Základní HTML — CSS rozložení kurzoru
Začneme psaním JSX(HTML) pro tečku kurzoru a obrys kurzoru.
Vytvořili jsme také ref
pro tyto prvky, abychom mohli později přistupovat k prvkům DOM.
Dále přidáme CSS styling těchto prvků.
cursor: none
je přidán do univerzálního voliče *
protože chceme skrýt výchozí kurzor.
pointer-events: none
aby se tento prvek nestal cílem událostí ukazatele. Ukazatele-události MDN
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
Tento fragment kódu se používá k přesunutí obou prvků ve středu.
opacity: 1;
se používá, abychom později mohli skrýt a zobrazit náš kurzor na základě mouseenter
a mouseleave
událost. Proto transition
se také používá na opacity
vlastnost.
Přechod na transform
se používá k tomu, abychom mohli zvětšit a zmenšit velikost tečky a obrysu na základě některých událostí myši (brzy se dozvíme, která 😉).
Bude to vypadat nějak takto.
Přidávání obrázků pro zobrazení efektu umístění kurzoru
Přidáme několik obrázků, abychom ukázali ten hladký přechod kurzoru.
Vytvořil tento <Link />
komponentu, kterou lze znovu použít pro zobrazení obrázků.
Nyní to musíme importovat do našeho <Cursor />
komponentu a předat obrázky.
Přidali jsme ref
do jeho kontejneru, protože do všech těchto obrázků přidáme události myši.
getImage
je util funkce, kterou jsem vytvořil, abych získal obrázky na základě hodnoty indexu poskytované mapovou funkcí. Funkci najdete ve zdrojovém kódu (nepřidávám žádný obrázek, protože to není tak důležité. Omlouváme se getImage
funkce! 😥).
Bonusové body 🤩
- Cesta příkazu importu
Abych to mohl použít, použil jsem jsconfig.json
. Tento soubor můžete přidat do kořenového adresáře svého projektu a přidat baseUrl
vlastnost uvnitř compilerOptions
.
[...Array(4).keys()]
úryvek kódu
Array(4)
vytvoří prázdné pole o velikosti 4.
keys()
metoda vrací nový Iterátor pole objekt, který obsahuje klíče pro každý index v poli.
A rozložením pole získáme pole — [0, 1, 2, 3]
Dobře, vraťme se k tomu, co jsme dělali 😅.
Poslední věcí je přidat trochu stylu do našeho kontejneru obrázků.
A teď bude konečný výsledek vypadat nějak takto —
Přidání animace do našeho kurzoru
Konečně nastal čas přidat animaci do našeho kurzoru (chudák kurzor sedí sám ve středu obrazovky 😥).
Přidání referenčních proměnných
Potřebujeme přidat další refs
na náš kurzor komponentu, abychom mohli aktualizovat změny.
zpoždění se použije jako faktor, kterým změníme, jak rychle nebo pomalu má obrys kurzoru následovat tečku kurzoru. Vyšší číslo znamená pomalé a naopak.
cursorVisible pomůže při přepínání viditelnosti kurzoru.
kurzorZvětšený pomůže při přepínání velikosti kurzoru.
endX je poloha X tečky kurzoru. Do této proměnné budeme ukládat pozici X tečky. Inicializuje se s window.innerWidth/2
protože to je uprostřed osy X.
konecY je poloha Y tečky kurzoru. Do této proměnné budeme ukládat polohu Y tečky. Koncept je stejný jako endX .
_x je poloha X obrysu kurzoru. Do této proměnné budeme ukládat pozici X obrysu. Inicializuje se s 0, protože chceme zobrazit animaci pohybu. (Obrys vycházející z levého horního rohu obrazovky do prostředního bodu, kde se na začátku aplikace nachází tečka).
_y je poloha Y obrysu kurzoru. Do této proměnné budeme ukládat polohu Y obrysu. Koncept je stejný jako _x .
requestRef uloží ID vrácené z jedné důležité funkce (uvidí ho, když přidáme animaci do obrysu kurzoru).
Přidání funkcí přepínání kurzoru
-
toggleCursorVisibility — Pokud je kurzor viditelný, změníme krytí na 1, jinak jej změníme na 0.
-
toggleCursorSize — Pokud je kurzorEnlarged pravdivý, pak zmenšíme velikost tečky a zvětšíme velikost obrysu. V případě nepravdy ji změníme zpět na původní velikost.
Přidávání událostí myši přepnout, odepnout, zadat, opustit
„přejetí myší“ — Přejetí myší událost se spustí, když se kurzor dostane nad prvek nebo jeho potomky.
‘mouseout’ — Out myši událost se spustí, když kurzor není nad prvkem nebo jeho potomky.
‘mouseleave‘ — Pokles myši událost se spustí, když opustíme zobrazovanou oblast stránky.
‘mouseenter’ — Mouseenter událost se spustí, když vstoupíme do výřezu stránky.
Nyní můžeme předat mouseOverEvent a mouseOutEvent k naší obrazové složce.
Tyto funkce budou volány vždy, když se kurzor myši objeví nad obrázkem.
Přidání události mousemove
Nejprve se musíme ujistit, že náš kurzor je viditelný, proto jsme aktualizovali currentVisible a nazývá se toggleCursorVisibility funkce.
Poté pomocí pageX zaujmeme aktuální pozici kurzoru a stránkaY . Dalším krokem je aktualizace horní a levé vlastnosti tečkového kurzoru, aby se zobrazoval, jak se pohybuje po stránce.
P.S — Tato odpověď StackOverflow má velmi dobré vysvětlení rozdílu mezi clientX a stránkaX .
Přidání animace obrysu kurzoru
Toto je speciální rekurzivní funkce, kterou voláme uvnitř requestAnimationFrame
funkce. V této funkci aktualizujeme polohu obrysu kurzoru vzhledem k pozici tečky kurzoru .
Matematické vysvětlení tohoto je uvedeno v části 2 tohoto článku.
Tento článek je skvělý k pochopení toho, jak requestAnimationFrame funguje a proč byl vytvořen.
Volání všech funkcí události
Můžeme volat všechny naše funkce událostí uvnitř useEffect
(componentDidMount). V době odpojení bychom měli odebrat všechny posluchače událostí a také zrušit requestAnimationFrame pomocí cancelAnimationFrame funkce.
A se všemi těmito funkcemi se náš ubohý kurzor může konečně pohnout 🥳
Část 2 článku má trochu matematického vysvětlení. Takže si to můžete zkontrolovat, pokud chcete.
Některé z důležitých odkazů —
MDN requestAnimationFrame — https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame
StackOverflow odpověď na vyžádáníAnimationFrame — https://stackoverflow.com/questions/52212703/using-requestanimationframe-in-react/52213728
Použití requestAnimationFrame v Reactu — https://css-tricks.com/using-requestanimationframe-with-react-hooks/
Používání posluchačů událostí v Reactu — https://www.pluralsight.com/guides/event-listeners-in-react-components
Codepen VanillaJS pro vlastní kurzor — https://codepen.io/kjbrum/pen/qooQJJ