Techniky CSS pre efekt zvlnenia materiálu

Sprievodca rôznymi technikami zvlnenia pomocou CSS a JavaScript

Nedávno som musel implementovať efekt zvlnenia z materiálového dizajnu do webovej aplikácie. A potom som si uvedomil, že netuším, ako sa to implementuje. To ma priviedlo na cestu k štúdiu existujúcich implementácií a dokonca prišiel s úplne novou technikou, ktorá by pre vás mohla byť užitočná.

Čo je to zvlnenie?

Počkajte, nepoznáte zvlnený efekt materiálového dizajnu Google? Boli ste už niekoľko rokov v jaskyni?

Efekt zvlnenia sa použije, keď stlačíte tlačidlo. Funguje to rovnako pre interakciu myši alebo dotyku.

Poloha, na ktorú kliknete alebo sa dotknete tlačidla, sa nazýva kontaktný bod. Odtiaľ sa vlnenie posúva smerom von a stráca nepriehľadnosť, keď sa zväčšuje, až kým nevyplní celé tlačidlo. Potom úplne zmizne.

Dynamika tohto zvlnenia je podobná vlnám, ktoré získate, keď sa dotknete tekutého povrchu alebo keď spadnete skalu do jazera.

Vlnky, ktoré nájdete na webe

Po nejakom výskume som našiel dve hlavné techniky, ktoré sa používajú na implementáciu zvlnenia efektu na webové aplikácie.

Použitie :: po pseudoprvku

Použitím tejto techniky je pseudoprvok tlačidla :: po štylizovaný ako polopriehľadný kruh a animovaný tak, aby rástol a mizol. Tlačidlo na nádobe musí mať pretečenie: skryté, aby kružnica nikdy nepretekala mimo povrchu tlačidla a poloha: vzhľadom na to, aby bolo ľahké umiestniť kruh do gombíka. Viac informácií o tejto technike si môžete prečítať v tomto článku od Ionuț Colceriu.

Jednou z vynikajúcich vecí na tejto technike je to, že ide o čisté riešenie zvlnenia CSS. Efekt zvlnenia sa však vždy začína od stredu tlačidla namiesto od bodu kontaktu. Toto nie je najprirodzenejšia spätná väzba.

Dalo by sa to vylepšiť pomocou JavaScriptu na uloženie bodu kontaktu a použiť ho na umiestnenie zvlnenia. To je presne to, čo material.io urobil pre svoj komponent zvlnenia webu. Na ukladanie kontaktného miesta používa premenné CSS a pseudoprvok :: :: po použití týchto premenných na určovanie polohy.

Používanie podriadených prvkov

Táto technika v podstate používa rovnakú stratégiu ako predtým. Namiesto pseudoprvku však do tlačidla pridá prvok na nastavenie meracieho rozsahu, ktorý sa potom dá umiestniť pomocou JavaScriptu. Táto technika je opísaná v tomto článku od Jhey Tompkins.

Najjednoduchšia implementácia vytvorí rozpätie pre každé kliknutie na tlačidlo a pomocou polohy myši na udalosti kliknutia zmeníte polohu rozsahu. Animácia CSS spôsobuje, že rozpätie rastie a mizne, až kým nie je úplne transparentný. Keď sa animácia skončí, môžeme si vybrať, aby sa rozpätie z DOM odstránilo, alebo ho tam len necháme pod kobercom - nikto si skutočne nevšimne priehľadné rozpätie visiace okolo.

Našiel som inú variáciu tohto, v ktorej je podriadený prvok svg namiesto rozpätia a svg je animovaný pomocou JavaScriptu. Túto variáciu vysvetľuje Dennis Gaebel, ale v podstate sa zdá byť rovnaká a pravdepodobne umožňuje použitie zložitých tvarov a efektov SVG.

Problém s odoslaním vstupov

Obe vyššie uvedené techniky sa zdajú byť vynikajúce. Ale to sa stane, keď som sa ich pokúsil aplikovať na vstupné prvky s typom = submit:

Prečo nepracujú?

Vstupným prvkom je nahradený prvok. Stručne povedané, to znamená, že s týmito prvkami môžete robiť veľmi málo, pokiaľ ide o DOM a CSS. Konkrétne nemôžu mať podriadené prvky ani pseudoprvky. Teraz je jasné, prečo tieto techniky zlyhávajú.

Ak teda používate Material Design, je lepšie sa držať ďalej od vstupu [type = submit] a držať sa tlačidiel. Alebo len čítajte ďalej.

Pridanie vlniek na odoslanie vstupov

Na webovej aplikácii, na ktorej som pracoval, sme už mali veľa tlačidiel na odoslanie. Zmena všetkých z nich na iný prvok by si vyžadovala veľa práce a vysoké riziko porušenia štýlov a logiky JavaScriptu. Takže som musel prísť na to, ako pridať vlnky do existujúcich tlačidiel na odoslanie.

Použitie baliaceho kontajnera

Rýchlo som si uvedomil, že by som mohol zabaliť tlačidlo odoslania do prvku vloženého bloku a použiť prvok vloženého bloku ako povrch zvlnenia. Tu je stručná ukážka:

Aj keď sa mi toto riešenie páči z dôvodu jeho jednoduchosti, stále ma vyžadovalo, aby som zmenil označenie na príliš mnohých miestach. A vedel som, že to bude krehké riešenie - do projektu vstúpia noví vývojári a vytvoria tlačidlá na odovzdanie bez toho, aby ich správne zabalili do zvlnenia. Stále som hľadal iné riešenia, ktoré si nevyžadujú zmenu DOM.

Radiálne gradienty

Syntax radiálneho gradientu mi umožňuje riadiť stred aj veľkosť gradientu. Samozrejme mi to umožňuje kontrolovať aj farbu gradientu vrátane polopriehľadných farieb. A nikdy neprekypuje prvok, na ktorý sa vzťahuje. Zdá sa teda, že už robí všetko, čo potrebujem!

Nie tak rýchlo ... chýba jedna vec: vlastnosť pozadia na pozadí nie je animovateľná. Pomocou animácií CSS som nedokázal dosiahnuť rast a prechod na priehľadnosť. Podarilo sa mi, aby sa rozrástla animáciou vlastnosti veľkosti pozadia, ale to bolo všetko, čo som mohol urobiť.

Vyskúšal som niekoľko ďalších vecí, napríklad miznúci kruh ako animovaný obrázok (pomocou formátu apng) a použil som ho ako obrázok na pozadí. Ale potom som nemohol ovládať, kedy sa obrazová slučka začala a skončila.

Nakoniec riešenie s JavaScriptom

Čo v CSS nemôžete urobiť, môžete to urobiť v JavaScripte. Po tom, čo som strávil viac času, než som ochotný pripustiť, aby som sa snažil dosiahnuť, aby tento efekt fungoval pomocou animácií CSS, som sa vzdal a rozhodol sa animáciu napísať do JavaScriptu.

Začal som vyššie uvedeným riešením radiálneho gradientu a pomocou okna.requestAnimationFrame som vytvoril plynulú animáciu radiálneho gradientu, rast a blednutie. Tu je moje konečné riešenie:

záver

Je možné mať vlnkové účinky na tlačidlá odoslania, nie iba so samotným CSS.

Túto techniku ​​som nenašiel nikde na webe, takže ju nazývam vlastnou. Technika zvlnenia Leonarda nevyžaduje zmeny DOM a pracuje pre akýkoľvek prvok, pretože sa nespolieha na pseudo-prvky alebo podriadené prvky. Nie je to však dokonalé riešenie.

Najprv je tu výkon. Animáciou prechodu pomocou jazyka JavaScript stratíte veľa optimalizácií prehliadača. Keďže sa však zmenila jediná vlastnosť, je obrázok na pozadí, mal by som podozrenie, že prehliadače by sa nemuseli preformátovať, a vyžadoval by som len opätovné použitie štýlov a prekreslenie prvku. V praxi sa to presne deje a výkon je skutočne dobrý. Výnimkou z tohto tvrdenia je Firefox Mobile, ktorý z nejakého dôvodu nedrží krok s animáciou. (úprava: animácia je v moderných verziách prehliadača Firefox Mobile plynulá)

Po druhé, technika využíva vlastnosť tlačidla na pozadí. Ak váš návrh vyžaduje, aby tlačidlá mali na pozadí aplikovaný obrázok, efekt zvlnenia by to potlačil. Ak skutočne potrebujete tento obrázok vo svojom návrhu, potom by sa JavaScript mohol upraviť tak, aby nakreslil radiálny gradient na vrch existujúceho obrázka na pozadí.

Po tretie, zdá sa, že to nefunguje v programe Internet Explorer. Nevidím však žiadny dôvod, prečo by nemal fungovať s programom IE10 a novším. Možno je to preto, že IE používa inú radiálnu syntax pre radiálny gradient. Ale komu dnes záleží na IE? (upraviť: táto metóda funguje bez problémov v programe Internet Explorer 11)