Tegning Realistiske Skyer med SVG og CSS

0
18

Gresk mytologi forteller historien om Zevs skaper skyen nymfe, Nephele. Som andre greske myter, denne fortellingen blir ganske bisarr og X-rated. Her er en veldig forkortet, høflig versjon.

Nephele, blir vi fortalt, var skapt av Zeus i bildet av sin egen kone. Et menneske møter Nephele, forelsket i henne, og, sammen, vil de ta en voksen lur™. Til slutt, i en merkelig vri, skyen føder halvt menneske halvt hest Centaur babyer.

Merkelig, ikke sant? Personlig, er at jeg ikke kan gjøre hoder eller haler av det. Heldigvis, prosessen for å lage skyer i nettleseren er mye enklere og langt mindre dristige.

Yuan Chuan er skyer detalj. (Demo)

Nylig oppdaget jeg at utvikleren Yuan Chuan har innsett koden er generert, fotorealistiske skyene. For meg er dette begrepet i nettleseren lenge hadde vært ting av myten.

Med ett blikk på koden i denne pennen kan vi tenke oss at overbevisende individuelle skyer er oppnåelig gjennom bruk av CSS-box-shadow med en <filter> – element som inneholder to SVG-filtre som dens komplement.

Fotorealisme vi vil oppnås med en delikat blanding av feTurbulence og feDisplacementMap. Disse SVG-filtre er mektig, kompleks og tilbyr meget spennende funksjoner (inkludert en Oscar-vinnende algoritme)! Imidlertid, under panseret, deres kompleksitet kan være litt skremmende.

Mens fysikk av SVG-filtre er utenfor omfanget av denne artikkelen, det er rikelig med dokumentasjon som er tilgjengelig på MDN og w3.org. En veldig informativ side på feTurbulence og feDisplacement er fritt tilgjengelig (og tilbys som et kapittel av denne fantastiske boken).

For denne artikkelen, vil vi fokusere på å lære å bruke disse SVG-filtre for å få spektakulære resultater. Vi trenger ikke å gå for dypt inn i hva som skjer bak kulissene algoritmer, mye på den måten en kunstner som ikke er nødvendig, vet den molekylære strukturen av maling til å gjengi et fantastisk landskap.

I stedet, la oss betale nær oppmerksomhet til liten håndfull av SVG-egenskaper som er viktige for tegning overbevisende skyer i nettleseren. Deres bruk vil gjøre oss i stand til å bøye disse kraftige filtre til vår vilje og lær hvordan du kan tilpasse dem med presisjon i våre egne prosjekter.

La oss starte med noen grunnleggende

CSS-box-shadow eiendom har fem verdier som fortjener nøye:

box-shadow: <offsetX> <offsetY> <blurRadius> <spreadRadius> <farge>;

La oss skru disse verdiene opp (sannsynligvis høyere enn hva en sunn utbygger ville, slik at denne skyggen blir en spiller på scenen i sin egen rett.

(Demo)

#cloud-plassen {
bakgrunn: turkis;
box-shadow: 200px 200px 50px 0px #000;
bredde: 180px;
høyde: 180px;
}

#cloud-sirkel {
bakgrunn: coral;
border-radius: 50%;
box-shadow: 200px 200px 50px 0px #000;
bredde: 180px;
høyde: 180px;
}

Du enten har gjort eller sett shadow puppets, ikke sant?

Kreditt: Double-M

På samme måte som en hånd endrer form for å endre skygge, en “kilde form” i vår HTML kan flytte og forvandle seg til å flytte og endre form av en skygge gjengitt i nettleseren. box-shadow dupliserer “morphing” har på den opprinnelige størrelsen og border-radius. SVG-filtre bli brukt til både element og dens skygge.

<svg bredde=”0″ height=”0″>
<filter id=”filter”>
<feTurbulence type=”fractalNoise” baseFrequency=”.01″ numOctaves=”10″ />
<feDisplacementMap i=”SourceGraphic” scale=”10″ />
</filter>
</svg>

Dette er markup for våre SVG-så langt. Det vil ikke gjengi fordi vi ikke har definert noe visuelle (for ikke å nevne null bredde og høyde). Det eneste formål er å holde et filter som vi fôrer våre SourceGraphic (aka vår <div>). Vår kilde <div> og dens skygge er både å være forvrengt uavhengig av filteret.

Vi vil legge de grunnleggende CSS-regel som knytter HTML-element (`#cloud-krets”) til SVG-filter ved hjelp av sin ID:

#cloud-sirkel {
filter: url(#filter);
box-shadow: 200px 200px 50px 0px #fff;
}

Et Nå!

OK, så riktignok legge til SVG-filter er ganske underwhelming.

(Demo)

Ingen bekymringer! Vi har bare skrapet overflaten og har en mye mer god ting å se på.

Eksperimentere med feDisplacementMap skala attributt

Noen fn-vitenskapelige eksperimenter med dette attributtet kan gi dramatiske resultater. For øyeblikket, la oss holde alle verdier i feTurbulence konstant og bare justere skalaen egenskap av DisplacementMap.

Som omfanget øker (i steg på 30) vår kilde <div> blir fordreid, og kaster en skygge til å speile den stokastiske form som skyer dukker opp i himmelen.

<feDisplacementMap i=”SourceGraphic” scale=”180″/>

Skalaen attributt, og øker med verdier for 30. (Demo)

OK, vi får et sted! La oss endre fargene litt for å lage en mer overbevisende skyen og for å “selge” effekten.

body {
bakgrunn: linear-gradient(165deg, #527785 0%, #7FB4C7 100%);
}

#cloud-sirkel {
bredde: 180px;
høyde: 180px;
bakgrunn: #000;
border-radius: 50%;
filter: url(#filter);
box-shadow: 200px 200px 50px 0px #fff;
}

Nå er vi komme nærmere en realistisk cloud effekt!

Endre box-shadow uskarphet verdi

Følgende suite av bildene viser den innflytelse som uskarphet som har verdien på box-shadow. Her, blur er økt med 10 punkter trinnvis.

Skyen blir “mykere” som blur-verdien øker.

For å gi våre cloud litt av en cumulus-lignende effekt, kan vi utvide vår kilde <div> litt.

#cloud-sirkel {
width: 500px;
høyde: 275px;
bakgrunn: #000;
border-radius: 50%;
filter: url(#filter);
box-shadow: 200px 200px 60px 0px #fff;
}

Flott, nå kilden element er å komme i veien. 😫

Vente! Vi har utvidet kilde element, og nå er det i veien for vår av den hvite skyggen vi kaller en sky. La oss “re-kastet” skyggen på en større avstand slik at våre cloud er ikke lenger skjult av biletet. (Tenk på dette som å flytte hånden lenger vekk fra veggen slik at det ikke hindrer utsikten på shadow puppets.)

Dette er pent oppnådd med litt CSS-posisjonering. <Body> er overordnet element for våre cloud, som er statisk plassert som standard. La oss “brette” vår kilde <div> opp og ut av veien med noen absolutt posisjonering. I utgangspunktet, som vil omplassere vår skygge så godt, så vi trenger også å øke avstanden til skyggen fra elementet og dytte element litt mer.

#cloud-sirkel {
width: 500px;
høyde: 275px;
bakgrunn: #000;
border-radius: 50%;
filter: url(#filter);
box-shadow: 400px 400px 60px 0px #fff; /* Øke skygge offset */
position: absolute; /* Ta den overordnede ut av dokumentet flow-og varmtvannsberedning */
øverst: -320px; /* Flytte litt ned */
venstre: -320px; /* Flytte litt høyre */
}

Ja! Vi har kommet til en ganske overbevisende skyen.

Se Penn
av Beau Haus (@beauhaus)
på CodePen.

Hva er malt til web-leseren er en ganske anstendig skildring av en cloud–Men, jeg er ikke sikker på…gjør dette cloud virkelig gjøre rettferdighet skyen nymfe, Nephele? Jeg er sikker på at vi kan gjøre det bedre!

Å formidle dybden med lag

Her er hva vi ønsker:

Kreditt: pcdazero

Fra utseendet av dybde, struktur og rikdom av skyene i dette bildet, en ting er klart: Zeus gikk på kunstskole. I det minste, han må ha lest Den Universelle Prinsipper for Utforming som illustrerer en kraftig, men likevel, utrolig vanlig–konsept:

[…] belysning bias spiller en betydelig rolle i tolkningen av dybde og naturlighet, og kan manipuleres i en rekke måter av designere…Bruk nivået av kontrasten mellom lys og mørke områder for å variere utseendet av dybde.

Dette verset gir oss et hint om hvordan vi kan vesentlig forbedre vår egen kode generert av skyen. Vi kan gi våre cloud-med en god del av troskap til skyene i vår referanse bilde ved å stable lag av ulik form, størrelse og farge på toppen av hverandre. Alt som trengs er å ringe vårt filter så mange ganger som vi ønsker lagene.

<svg bredde=”0″ height=”0″>
<!– Tilbake Lag –>
<filter id=”filter-back”>
<feTurbulence type=”fractalNoise” baseFrequency=”0.012″ numOctaves=”4″ />
<feDisplacementMap i=”SourceGraphic” scale=”170″ />
</filter>
<!– Midterste Laget –>
<filter id=”filter-mid”>
<feTurbulence type=”fractalNoise” baseFrequency=”0.012″ numOctaves=”2″ />
<feDisplacementMap i=”SourceGraphic” scale=”150″ />
</filter>
<!– Foran Lag –>
<filter id=”filter-front”>
<feTurbulence type=”fractalNoise” baseFrequency=”0.012″ numOctaves=”2″ />
<feDisplacementMap i=”SourceGraphic” scale=”100″ />
</filter>
</svg>

Vi bruker våre lag skal ha råd til oss en mulighet til å utforske feTurbulence og realisere sin allsidighet. Vi vil velge den mykere type som er tilgjengelig for oss: fractalNoise med numOctaves cranked opp til 6.

<feTurbulence type=”fractalNoise” baseFrequency=”n” numOctaves=”6″/>

Hva betyr alt dette? For nå, la oss fokusere spesifikt på baseFrequency attributtet. Her er hva vi får når vi øke verdien av n:

Jo lavere verdi, jo rundere og uklart vi får. Jo høyere verdi, jo rundere og mer rigid vi får.

Ord som uro, støy, frekvens, og oktav kan virke merkelig og til og med forvirrende. Men frykt ikke! Det er faktisk helt riktig å analogize dette filteret er effekter til lydbølger. Vi kan likestille en lav frekvens (baseFrequency=0.001) med en lav, dempet støy og en økende frekvens (baseFrequency=0.1) med en høyere, skarpere banen.

Vi kan se at vår sweet spot for en cumulus-lignende effekt kan ligge komfortabelt rundt ~0.005 og ~0.01 utvalg for baseFrequency.

Legge til detaljer med numOctaves

Økes numOctaves gir oss muligheten til å yte vårt bilde i ekstremt detaljer. Dette krever en god del av beregningen, så vær advart: høye verdier er en betydelig ytelse hit. Prøv å motstå fristelsen til å pumpe opp denne verdien med mindre nettleseren din har på seg en hjelm og kne-pads.

Jo høyere verdien er vi sette inn numOctaves mer detaljer gir våre cloud.

Den gode nyheten er at vi ikke trenger å skru denne verdien er for høy for å produsere detalj og delikatesse. Som tabellen over bildene ovenfor viser, kan vi tilfredsstille oss selv med en numOctavesvalue av 4 eller 5.

Her er resultatet

Se Penn
av Beau Haus (@beauhaus)
på CodePen.

Uendelig rekke med frø attributt

Det er mye å si om frø attributt som tilbyr et hint inn i den magiske skjer bak kulissene. Men for vårt formål, nytten av frø kan bli redusert til fire ord: “en annen verdi, annen form.”

Den Perlin Noise funksjon (nevnt tidligere) bruker denne verdien som utgangspunkt for tilfeldig tall generator. Å velge å ikke inkludere dette attributtet standard frø til null. Når inkludert, imidlertid, uansett verdi, kan vi gi frø, vi trenger ikke å bekymre deg om en ytelse hit.

Forskjellige frø verdier produsere forskjellige former.

GIF ovenfor representerer noe av det frø har å tilby. Husk at hver av disse skyene er en lagdelt, kompositt skyen. (Mens jeg har forskjøvet attributter for hvert lag, jeg har holdt sine respektive frø verdier uniform.)

Kreditt: Brockenhexe

Her, med en nærmere titt på referanse bilde, jeg har lag 3 cloud-<div>s (av ulik tetthet) på en enkelt base div. Gjennom prøving og feiling og punching i tilfeldig frø verdier, vil jeg til slutt kom til en form som ligner på formen av skyen i bildet.

Se Penn
Nephele Referanse Bilde studie av BEAU.HAUS (@beauhaus)
på CodePen.

Himmelen er grensen

Selvfølgelig, det ville være arroganse å tro at <div>s at vi maling til nettleseren kan være overlegen til Zevs, Nephele.

Imidlertid mer mysteriet vi er i stand til å lokke ut av CSS og SVG-filtre, jo mer vi er bemyndiget skape noe visuelt imponerende med en høy grad av trofasthet mot Torden Guds opprinnelige skapelsen. Vi kan, så kan du gå på eksperimentere videre!

Som Reflekterer Tåke

Animerte Reflekterer tåke

Alto-Cirrus Skyer

Alto-Cirrus skyer

I denne artikkelen har vi bare dyppet vår tå i et hav av kraft og kompleksitet. SVG-filtre kan ofte virke overveldende og utilnærmelig.

Imidlertid er det mye som eksempler finnes i En Enkelt Div prosjektet eller Diana Smiths maleteknikker, en leken og eksperimentell tilnærming vil alltid belønnet med spektakulære resultater!

Jeg håper dette får du spent på å skape en bit av fotorealisme på nettet. Utviklet jeg et lite verktøy for å bidra til å sette dem alle til å bruke og eksperimentere litt. Eventuelle spørsmål, forslag eller råd? Ping meg i vers slippe en kommentar her.

Mange takk til Amelia Bellamy-Royds for hennes gode råd på denne artikkelen.