Animere Kalligrafi med SVG

0
21

Fra tid til annen på Stackoverflow, spørsmålet dukker opp om det er en tilsvarende slag-dashoffset teknikk for å animere SVG slag som arbeider for fyll-attributtet. Men ved nærmere ettersyn, hva spørsmålene er virkelig prøver å be er noe sånt som dette:

Jeg har noe som er i form av en linje, men fordi den har varierende børste bredder, i SVG det er definert som fyll på en bane.

Hvordan kan denne “pensel” besjelet?

Kort sagt: Hvordan kan du animere kalligrafi?

En maske vei dekker de kalligrafiske pensel

Den grunnleggende teknikken for dette er relativt enkel: tegn en andre (glatt) bane på toppen av kalligrafi, slik at den følger børsten linje og velg deretter strekbredde på en slik måte at det dekker kalligrafi overalt.

Denne veien på toppen vil bli brukt som en maske for ett under det. Påfør slag-dashoffset animasjon teknikk for å masken banen. Resultatet vil se ut som om den nedre stien blir “skrevet” direkte på skjermen i sanntid.

Det er en sak for en maske, ikke et klipp-banen — som ikke ville fungere. Klipp-baner alltid referanse fylle området på en vei, men ignorere slag.

Den enkleste varianten er å sette strek: hvit for banen i masken. Så alt utenfor området malt hvit er skjult, og noe inni er vist uten endring.

Se Penn å Skrive kalligrafi: grunnleggende eksempel ved ccprog (@ccprog) på CodePen.

Så langt, så enkelt. Ting blir vanskelig, men når den kalligrafiske linjer overlapper hverandre. Dette er hva som skjer i en naiv implementasjon:

Se Penn å Skrive kalligrafi: feil skjæringspunktet av ccprog (@ccprog) på CodePen.

På skjæringspunktet, maske avslører en del av krysset pensel. Derfor, kalligrafi har kuttes i ikke-overlappende deler. Stable dem i tegning for og definere egne maske stier for hver og en.

Kutt på maske banen og kalligrafiske pensel må matche

De mest vanskelige delen er å opprettholde inntrykket av at tegning er én sammenhengende bevegelse. Hvis du kutter en glatt bane, ender passer sammen så lenge begge bane tangenter har samme retning på deres felles punkt. Slaget ender vinkelrett til det, og det er viktig at kutt i kalligrafiske linje justerer nøyaktig. Ta vare på alle baner har rad retninger. Animere dem én etter én.

Mens mange line animasjoner kan få av med grove matematikk på lengden for slag-dasharray, dette scenariet krever nøyaktige målinger (selv om små roundings bør ikke skade). Som en påminnelse, kan du få dem i DevTools konsollen med:

dokumentet.querySelector(‘#mask1 vei’).getTotalLength()

Se Penn å Skrive kalligrafi: dele opp kryss av ccprog (@ccprog) på CodePen.

“Den ene etter den andre” delen er litt vanskelig å skrive i CSS. Det beste mønsteret er trolig å gi alle delvis animasjoner samme starttidspunkt og total varighet, og deretter sette middels keyframes mellom den slag-dashoffset endringer.

Noe sånt som dette:

@keyframes brush1 {
0% { slag-dashoffset: 160; } /* la statisk */
12% { slag-dashoffset: 160; } /* start av første børste */
44% { slag-dashoffset: 0; } /* slutt på første strøket er lik starten av andre */
100% { slag-dashoffset: 0; } /* la statisk */
}

@keyframes brush2 {
0% { slag-dashoffset: 210; } /* la statisk */
44% { slag-dashoffset: 210; } /* start av andre børsten er lik slutten av første */
86% { slag-dashoffset: 0; } /* slutten av andre børste */
100% { slag-dashoffset: 0; } /* la statisk */
}

Ytterligere ned, vil du se hvordan et SMIL animering gjør at en mer flytende og uttrykksfull måte å definere timing. Tråd med CSS, beregninger gjort med Sass kan være ganske nyttig, siden den kan håndtere noe matte.

Masken banen (til venstre) og dens anvendelse (høyre)

Et tilsvarende problem vises hvis kurve radius av maske banen blir mindre enn strekbredde. Mens animasjonen går gjennom kurven, kan det skje at en mellomliggende tilstand ser alvorlig skjevt.

Løsningen er å flytte maske vei ut av den kalligrafiske kurve. Du trenger bare å ta vare på sin indre kanten fortsatt dekker penselen.

Du kan også klippe maske banen og misalign endene, så lenge kutte kantene passer sammen.

Radius opphold stor nok

Se Penn å Skrive kalligrafi: dele opp kryss av ccprog (@ccprog) på CodePen.

Og, dermed, du kan selv tegne noe komplisert, som arabisk kalligrafi i dette eksemplet:

Se Penn Tughra Mahmud II – tekst animasjon av ccprog (@ccprog) på CodePen.

Den opprinnelige design, Tughra av Osmanic Sultan Mahmud II., er av en ukjent 19. århundre maler bruker mange. De vectorized versjon ble gjort av Wikipedia illustrator Baba66. Animasjonen er mitt forsøk på å visualisere posisjon i den arabiske bokstaver i tegningen. Det bygger på en tidligere versjon av Baba66. Creative Commons Attribution-Share Alike 2.5.

Følgende kodebit viser den avanserte metoden som brukes til å kjøre animasjoner i orden og i en repeterbar måte.

maske banen {
fyll: ingen;
hjerneslag: white;
hjerneslag-bredde: 16;
}

.børste {
fill: #0d33f2;
}
<maske id=”mask1″ maskUnits=”userSpaceOnUse”>
<bane slag-dasharray=”160 160″ strek-dashoffset=”160″ d=”…”>
<!– animasjon begynner etter dokument begynner, og gjentas med et klikk
på “repeat” – knappen –>
<animere id=”animate1″ attributeName=”strek-dashoffset”
fra=”160″=”0″ begin=”1;gjenta.klikk” dur=”1.6 s” />
</bane>
</mask>
<maske id=”mask2″ maskUnits=”userSpaceOnUse”>
<bane slag-dasharray=”350 350″ strek-dashoffset=”350″ d=”…”>
<!– animasjon begynner i slutten av forrige –>
<animere id=”animate2″ attributeName=”strek-dashoffset”
fra=”350″=”0″ begin=”animate1.end” – dur=”3.5 s” />
</bane>
</mask>
<!– flere masker… –>
<maske id=”mask15″ maskUnits=”userSpaceOnUse”>
<bane slag-dasharray=”230 230″ strek-dashoffset=”230″ d=”…”>
<!– sett inn en kunstig pause mellom animasjoner, som om
børste hadde blitt løftet –>
<animere id=”animate15″ attributeName=”strek-dashoffset”
fra=”230″=”0″ begin=”animate14.end+0.5 s” dur=”2.3 s” />
</bane>
</mask>

<g class=”pensel”>
<bane id=”brush1″ d=”…”>
<!– Masken påføres kun etter at dokumentet starter/gjentar og til
animasjonen har kjørt. Dette gjør at børstene er synlig i
renderers som ikke støtter SMIL –>
<angi attributeName=”maske”=”url(#mask1)”
begynner=”0s;gjenta.klikk på” end=”animate1.end;ubestemt” />
</bane>
<bane id=”brush2″ d=”…”>
<angi attributeName=”maske”=”url(#mask2)”
begynner=”0s;gjenta.klikk på” end=”animate2.end;ubestemt” />
</bane>
<!– flere stier… –>
<bane id=”brush15″ d=”…”>
<angi attributeName=”maske”=”url(#mask2)”
begynner=”0s;gjenta.klikk på” end=”animate15.end;ubestemt” />
</bane>
</g>

I motsetning til de andre eksemplene vi har se på, denne animasjonen bruker SMIL, noe som betyr at det ikke vil fungere i Internet Explorer og Edge.

Denne artikkelen er publisert i tysk over på Leseren…koblet fra.

Jetpack WordPress plugin går på dette nettstedet, slår ikke bare relaterte innlegg nedenfor, men sikkerhet og sikkerhetskopiering, Markdown-støtte, søk nettstedet, kommentar form, sosiale nettverk-tilkoblinger, og mer!