Priročen učinek lebdenja za vaš avatar

Priročen učinek lebdenja za vaš avatar

Ali poznate tak učinek, ko glava nekoga štrli skozi krog ali luknjo? Slavna animacija Porky Pig, kjer pomaha v slovo, medtem ko izskoči iz niza rdečih obročev, je odličen primer, in Kilian Valkhof je to pred časom dejansko ponovno ustvaril tukaj na CSS-Tricks.

Imam podobno idejo, vendar sem se je lotil na drugačen način in z malo animacije. Mislim, da je precej praktičen in omogoča lep učinek lebdenja, ki ga lahko uporabite na nečem, kot je vaš lastni avatar.

Poglej to? Naredili bomo animacijo povečanja, pri kateri se bo zdelo, da bo avatar izskočil iz kroga, v katerem je. Kul, kajne? Ne glejte kode in skupaj sestavimo to animacijo korak za korakom.

HTML: Samo en element

Če še niste preverili demo kode in se sprašujete, koliko divČe bo to trajalo, potem se takoj ustavite, ker naša oznaka ni nič drugega kot en sam slikovni element:

<img src="" alt="">

Da, en sam element! Zahteven del te vaje je uporaba najmanjše možne količine kode. Če ste bili sledi mi nekaj časa bi se morali tega navaditi. Zelo se trudim najti rešitve CSS, ki jih je mogoče doseči z najmanjšo možno kodo, ki jo je najbolj vzdržljivo.

Napisal sem serija člankov tukaj na CSS-Tricks, kjer raziskujem različne učinke lebdenja z uporabo iste oznake HTML, ki vsebuje en element. Podrobno se poglobim v prelive, maskiranje, izrezovanje, obrise in celo tehnike postavitve. Zelo priporočam, da jih preverite, ker bom ponovno uporabil številne trike v tej objavi.

Kvadratna slikovna datoteka s prozornim ozadjem bo najbolje delovala za to, kar počnemo. Tukaj je tisti, ki ga uporabljam, če želite začeti s tem.

Modni učinek lebdenja za vaš avatar PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.
Oblikovano od cang

Upam, da bom videl čim več primerov tega z uporabo resničnih slik — zato vas prosimo, da delite svoj končni rezultat v komentarjih, ko končate, da bomo lahko zgradili zbirko!

Preden skočimo na CSS, najprej razčlenimo učinek. Slika se poveča, ko lebdimo, zato jo bomo zagotovo uporabili transform: scale() tam. Za avatarjem je krog in radialni preliv bi moral pomagati. Končno potrebujemo način za ustvarjanje obrobe na dnu kroga, ki ustvari videz avatarja za krogom.

Pa se lotimo dela!

Učinek lestvice

Začnimo z dodajanjem transformacije:

img { width: 280px; aspect-ratio: 1; cursor: pointer; transition: .5s;
}
img:hover { transform: scale(1.35);
}

Še nič zapletenega, kajne? Gremo naprej.

Krog

Rekli smo, da bo ozadje radialni gradient. To je popolno, ker lahko med barvami radialnega preliva ustvarimo trde meje, zaradi česar je videti, kot da rišemo krog s polnimi črtami.

img { --b: 5px; /* border width */ width: 280px; aspect-ratio: 1; background: radial-gradient( circle closest-side, #ECD078 calc(99% - var(--b)), #C02942 calc(100% - var(--b)) 99%, #0000 ); cursor: pointer; transition: .5s;
}
img:hover { transform: scale(1.35);
}

Upoštevajte spremenljivko CSS, --b, tam uporabljam. Predstavlja debelino "obrobe", ki se v resnici samo uporablja za definiranje trdih barvnih omejitev za rdeči del radialnega gradienta.

Naslednji korak je igranje z velikostjo gradienta pri lebdenju. Krog mora ohraniti svojo velikost, ko slika raste. Ker prijavljamo a scale() transformacijo, dejansko potrebujemo zmanjša velikost kroga, ker se sicer poveča z avatarjem. Torej, medtem ko se slika poveča, potrebujemo gradient za zmanjšanje.

Začnimo z definiranjem spremenljivke CSS, --f, ki definira "faktor lestvice", in ga uporabite za nastavitev velikosti kroga. uporabljam 1 kot privzeto vrednost, saj je to začetno merilo za sliko in krog, iz katerega se transformiramo.

Tukaj je predstavitev za ponazoritev trika. Premaknite miškin kazalec, da vidite, kaj se dogaja v zakulisju:

Dodal sem tretjo barvo radial-gradient za boljšo identifikacijo območja gradienta pri lebdenju:

radial-gradient( circle closest-side, #ECD078 calc(99% - var(--b)), #C02942 calc(100% - var(--b)) 99%, lightblue
);

Zdaj moramo naše ozadje postaviti na sredino kroga in se prepričati, da zavzame celotno višino. Vse rad izjavim neposredno na background stenografska lastnost, tako da lahko dodamo naše pozicioniranje v ozadju in zagotovimo, da se ne ponavlja, tako da se obrnemo na te vrednosti takoj za radial-gradient():

background: radial-gradient() 50% / calc(100% / var(--f)) 100% no-repeat;

Ozadje je postavljeno na sredino (50%), ima širino enako calc(100%/var(--f)), in ima višino enako 100%.

Nič ne skali, ko --f je enako 1 — spet naša začetna lestvica. Medtem gradient zavzame celotno širino vsebnika. Ko povečamo --f, velikost elementa raste — zahvaljujoč scale() transformiraj — in velikost gradienta se zmanjša.

Evo, kaj dobimo, ko vse to uporabimo v naši predstavitvi:

Bližamo se! Na vrhu imamo učinek prelivanja, vendar moramo še vedno skriti spodnji del slike, tako da je videti, kot da izstopa iz kroga, namesto da bi sedel pred njim. To je zapleten del vse te stvari in to bomo naredili naslednje.

Spodnja meja

Tega sem se najprej poskušal lotiti z border-bottom lastnosti, vendar nisem mogel najti načina, da bi velikost obrobe uskladil z velikostjo kroga. Tukaj je najboljše, kar sem lahko dobil, in takoj lahko vidite, da je narobe:

Dejanska rešitev je uporaba outline premoženje. ja outline, Ne border. v prejšnji članek, pokažem kako outline je močan in nam omogoča ustvarjanje kul efektov lebdenja. V kombinaciji z outline-offset, imamo točno tisto, kar potrebujemo za naš učinek.

Ideja je postaviti outline na sliki in prilagodite njen odmik, da ustvarite spodnjo mejo. Odmik bo odvisen od faktorja skaliranja na enak način kot velikost gradienta.

Zdaj imamo svojo spodnjo "mejo" (pravzaprav an outline) v kombinaciji z »obrobo«, ki jo ustvari gradient, da ustvari polni krog. Še vedno moramo skriti dele outline (z vrha in s strani), do katerega bomo prišli v trenutku.

Tukaj je naša dosedanja koda, vključno z nekaj dodatnimi spremenljivkami CSS, ki jih lahko uporabite za nastavitev velikosti slike (--s) in barvo »obrobe« (--c):

img { --s: 280px; /* image size */ --b: 5px; /* border thickness */ --c: #C02942; /* border color */ --f: 1; /* initial scale */ width: var(--s); aspect-ratio: 1; cursor: pointer; border-radius: 0 0 999px 999px; outline: var(--b) solid var(--c); outline-offset: calc((1 / var(--f) - 1) * var(--s) / 2 - var(--b)); background: radial-gradient( circle closest-side, #ECD078 calc(99% - var(--b)), var(--c) calc(100% - var(--b)) 99%, #0000 ) 50% / calc(100% / var(--f)) 100% no-repeat; transform: scale(var(--f)); transition: .5s;
}
img:hover { --f: 1.35; /* hover scale */
}

Ker potrebujemo okroglo spodnjo obrobo, smo dodali a border-radius na spodnji strani, kar omogoča outline da se ujema z ukrivljenostjo gradienta.

Izračun, uporabljen na outline-offset je veliko bolj preprosto, kot je videti. Privzeto, outline je narisan zunaj škatle elementa. In v našem primeru to potrebujemo prekrivajo element. Natančneje, potrebujemo, da sledi krogu, ki ga ustvari gradient.

Diagram prehoda ozadja.
Priročen učinek lebdenja za vaš avatar

Ko povečamo element, vidimo prostor med krogom in robom. Ne pozabimo, da je ideja ohraniti krog enake velikosti po zagonu transformacije merila, kar nam pušča prostor, ki ga bomo uporabili za določitev odmika obrisa, kot je prikazano na zgornji sliki.

Ne pozabimo, da je drugi element skaliran, zato je tudi naš rezultat skaliran ... kar pomeni, da moramo rezultat deliti z f da dobimo pravo vrednost odmika:

Offset = ((f - 1) * S/2) / f = (1 - 1/f) * S/2

Dodamo negativni predznak, ker potrebujemo, da gre obris od zunaj navznoter:

Offset = (1/f - 1) * S/2

Tukaj je hitra predstavitev, ki prikazuje, kako oris sledi prelivu:

Morda ga že vidite, vendar še vedno potrebujemo spodnji obris, da prekriva krog, namesto da pustimo, da se preliva skozi njega. To lahko storimo tako, da odstranimo velikost obrobe iz odmika:

outline-offset: calc((1 / var(--f) - 1) * var(--s) / 2) - var(--b));

Zdaj moramo najti, kako odstraniti zgornji del iz obrisa. Z drugimi besedami, želimo samo spodnji del slike outline.

Najprej dodamo prostor na vrhu z oblazinjenjem, da se izognemo prekrivanju na vrhu:

img { --s: 280px; /* image size */ --b: 5px; /* border thickness */ --c: #C02942; /* border color */ --f: 1; /* initial scale */ width: var(--s); aspect-ratio: 1; padding-block-start: calc(var(--s)/5); /* etc. */
}
img:hover { --f: 1.35; /* hover scale */
}

Ni posebne logike v tem zgornjem oblazinjenju. Ideja je zagotoviti, da se oris ne dotika glave avatarja. Uporabil sem velikost elementa, da sem določil ta prostor, da ima vedno enak delež.

Upoštevajte, da sem dodal content-box vrednost za background:

background: radial-gradient( circle closest-side, #ECD078 calc(99% - var(--b)), var(--c) calc(100% - var(--b)) 99%, #0000 ) 50%/calc(100%/var(--f)) 100% no-repeat content-box;

To potrebujemo, ker smo dodali oblazinjenje in želimo, da je ozadje nastavljeno samo na polje z vsebino, zato moramo ozadju izrecno povedati, naj se tam ustavi.

Dodajanje maske CSS mešanici

Prišli smo do zadnjega dela! Vse kar moramo storiti je, da skrijemo nekaj kosov, in končali smo. Za to se bomo zanašali na mask lastnosti in seveda gradientov.

Tukaj je slika, ki ponazarja, kaj moramo skriti ali kaj moramo prikazati, da bo bolj natančno

Prikazuje, kako se maska ​​nanaša na spodnji del kroga.
Priročen učinek lebdenja za vaš avatar

Leva slika je tisto, kar trenutno imamo, desna pa tisto, kar želimo. Zeleni del ponazarja masko, ki jo moramo uporabiti na izvirni sliki, da dobimo končni rezultat.

Prepoznamo lahko dva dela naše maske:

  • Krožni del na dnu, ki ima enako dimenzijo in ukrivljenost kot radialni gradient, s katerim smo ustvarili krog za avatarjem
  • Pravokotnik na vrhu, ki pokriva območje znotraj obrisa. Opazite, kako je obris zunaj zelenega območja na vrhu - to je najpomembnejši del, saj omogoča, da se obris izreže tako, da je viden le spodnji del.

Tukaj je naš končni CSS:

img { --s: 280px; /* image size */ --b: 5px; /* border thickness */ --c: #C02942; /* border color */ --f: 1; /* initial scale */ --_g: 50% / calc(100% / var(--f)) 100% no-repeat content-box; --_o: calc((1 / var(--f) - 1) * var(--s) / 2 - var(--b)); width: var(--s); aspect-ratio: 1; padding-top: calc(var(--s)/5); cursor: pointer; border-radius: 0 0 999px 999px; outline: var(--b) solid var(--c); outline-offset: var(--_o); background: radial-gradient( circle closest-side, #ECD078 calc(99% - var(--b)), var(--c) calc(100% - var(--b)) 99%, #0000) var(--_g); mask: linear-gradient(#000 0 0) no-repeat 50% calc(-1 * var(--_o)) / calc(100% / var(--f) - 2 * var(--b)) 50%, radial-gradient( circle closest-side, #000 99%, #0000) var(--_g); transform: scale(var(--f)); transition: .5s;
}
img:hover { --f: 1.35; /* hover scale */
}

Razčlenimo to mask premoženje. Za začetek opazite, da podobno radial-gradient() Iz background lastnina je notri. Ustvaril sem novo spremenljivko, --_g, za skupne dele, da bo stvari manj razmetane.

--_g: 50% / calc(100% / var(--f)) 100% no-repeat content-box; mask: radial-gradient( circle closest-side, #000 99%, #0000) var(--_g);

Sledi a linear-gradient() tudi tam:

--_g: 50% / calc(100% / var(--f)) 100% no-repeat content-box; mask: linear-gradient(#000 0 0) no-repeat 50% calc(-1 * var(--_o)) / calc(100% / var(--f) - 2 * var(--b)) 50%, radial-gradient( circle closest-side, #000 99%, #0000) var(--_g);

To ustvari pravokotni del maske. Njegova širina je enaka širini radialnega gradienta minus dvakratna debelina roba:

calc(100% / var(--f) - 2 * var(--b))

Višina pravokotnika je enaka polovici, 50%, velikosti elementa.

Potrebujemo tudi linearni gradient, postavljen v vodoravno sredino (50%) in zamik od vrha za enako vrednost kot zamik obrisa. Ustvaril sem še eno spremenljivko CSS, --_o, za odmik, ki smo ga predhodno definirali:

--_o: calc((1 / var(--f) - 1) * var(--s) / 2 - var(--b));

Ena od stvari, ki povzročajo zmedo, je, da potrebujemo negativna odmik za obris (da ga premaknete od zunaj navznoter), vendar a pozitiven odmik za gradient (za premikanje od zgoraj navzdol). Torej, če se sprašujete, zakaj pomnožimo odmik, --_os -1, no, zdaj veš!

Tukaj je predstavitev za ponazoritev konfiguracije gradienta maske:

Premaknite miško na zgoraj in si oglejte, kako se vse premika skupaj. Srednje polje ponazarja plast maske, sestavljeno iz dveh gradientov. Predstavljajte si ga kot vidni del leve slike in končni rezultat dobite na desni!

Zavijanje

Uf, končali smo! In ne samo, da smo zaključili s prefinjeno animacijo lebdenja, ampak smo vse naredili z enim samim HTML-jem <img> element. Samo to in manj kot 20 vrstic CSS zvijač!

Seveda smo se zanašali na nekaj majhnih trikov in matematičnih formul, da smo dosegli tako zapleten učinek. Vendar smo točno vedeli, kaj storiti, saj smo že vnaprej določili kose, ki jih potrebujemo.

Ali bi lahko poenostavili CSS, če bi si dovolili več HTML-ja? Vsekakor. Ampak tukaj smo, da se naučimo novih trikov CSS! To je bila dobra vaja za raziskovanje gradientov CSS, maskiranja, outline vedenje lastnine, transformacije in še veliko več. Če ste se na kateri koli točki počutili izgubljene, potem vsekakor preverite moja serija ki uporablja iste splošne koncepte. Včasih pomaga videti več primerov in primerov uporabe, da dosežemo cilj.

Pustil vam bom še zadnjo predstavitev, ki uporablja fotografije priljubljenih razvijalcev CSS. Ne pozabite mi pokazati predstavitve s svojo sliko, da jo lahko dodam v zbirko!

Časovni žig:

Več od Triki CSS