Animera Kalligrafi med SVG

0
40

Från tid till tid på Stackoverflow, dyker frågan upp om det finns en motsvarighet till den stroke-dashoffset teknik för att animera SVG-stroke är till för att fylla attribut. Men vid närmare inspektion, vilka frågor det är verkligen att försöka be om något liknande detta:

Jag har något som är en slags linje, men eftersom det har varierande borste bredder, i SVG det definieras som att fylla på en väg.

Hur kan denna “pensel” var animerad?

Kort sagt: Hur gör du för att animera kalligrafi?

En mask väg täcker den kalligrafiska borste

Den grundläggande tekniken för detta är relativt enkel: dra en sekund (slät) sökväg på toppen av kalligrafi så att den följer borste för linje och välj linjebredd på ett sådant sätt att den täcker kalligrafi överallt.

Denna väg på toppen kommer att användas som en mask för en under den. Applicera stroke-dashoffset animation teknik för att masken väg. Resultatet kommer att se ut som om den nedre vägen är att vara “skriven” direkt på skärmen i realtid.

Det är ett fall för en mask, inte en klipp-väg — att det inte skulle fungera. Clip-vägar alltid referera till fyllningen område av en väg, men strunta i stroke.

Den enklaste varianten är att ställa stroke: vit för vägen i masken. Då allt utanför det område målade vita är dolda, och någonting inuti visas utan förändring.

Se Pennan Skriver kalligrafi: grundläggande exempel genom att ccprog (@ccprog) på CodePen.

Så långt, så enkelt. Det blir knepigt, men när den kalligrafiska linjer överlappar varandra. Detta är vad som händer i en naiv implementation:

Se Pennan Skriver kalligrafi: felaktig korsningen av ccprog (@ccprog) på CodePen.

Vid skärningspunkten, den mask avslöjar en del av crossing borste. Därför, kalligrafi måste kapas i icke-överlappande bitar. Stapla dem i ordning och definiera separata mask vägar för var och en.

Snittet på mask väg och kalligrafisk borsta måste match

De mest svåra delen är att upprätthålla intrycket av att teckning är en enda kontinuerlig rörelse. Om du skär en smidig väg, slutar kommer att passa ihop så länge som både väg tangenterna har samma riktning på deras gemensamma punkt. Slaget slutar är vinkelrät mot den, och det är viktigt att skära i kalligrafisk linje anpassas exakt. Ta hand alla vägar har på varandra följande anvisningar. Animera dem, den ena efter den andra.

Medan många online-animationer kan bli av med grov matematik på längden för stroke-dasharray detta scenario kräver noggranna mätningar (även om små avrundningar borde inte ont). Som en påminnelse, du kan få dem i DevTools konsolen med:

dokumentet.querySelector(‘#mask1 vägen”).getTotalLength()

Se Pennan Skriver kalligrafi: dela upp korsningar av ccprog (@ccprog) på CodePen.

“Den ena efter den andra” delen är lite krångligt att skriva i CSS. Bästa mönstret är antagligen att ge alla partiella animationer samma starttid och total varaktighet, ställ sedan in mellanliggande keyframes mellan stroke-dashoffset förändringar.

Något liknande detta:

@keyframes brush1 {
0% { stroke-dashoffset: 160; } /* lämna statisk */
12% { stroke-dashoffset: 160; } /* start av första borste */
44% { stroke-dashoffset: 0; } /* slut på första borste lika början av andra */
100% { stroke-dashoffset: 0; } /* lämna statisk */
}

@keyframes brush2 {
0% { stroke-dashoffset: 210; } /* lämna statisk */
44% { stroke-dashoffset: 210; } /* start av andra borsten är lika med slutet av första */
86% { stroke-dashoffset: 0; } /* slut på andra borste */
100% { stroke-dashoffset: 0; } /* lämna statisk */
}

Längre ner kan du se hur en SMIL-animation och möjliggör en mer flytande och uttrycksfulla sätt att definiera timing. Håller med CSS, gjort beräkningar med Sass kan vara ganska bra eftersom det kan hantera lite matte.

Masken väg (till vänster) och dess tillämpning (höger)

En jämförbar problem visas om kurvans radie av masken vägen blir mindre än linjebredd. Medan animeringen körs genom att kurva, kan det hända att en mellanliggande staten ser allvarligt snett.

Lösningen är att flytta mask vägen ut ur den kalligrafiska kurva. Du behöver bara ta hand dess inre kanten fortfarande täcker borste.

Du kan även klippa mask väg och snedställ den slutar, så länge som den skär ihop.

Radien stannar tillräckligt stor

Se Pennan Skriver kalligrafi: dela upp korsningar av ccprog (@ccprog) på CodePen.

Och, alltså, du kan även rita något komplex, som den arabiska kalligrafi i detta exempel:

Se Pennan Tughra Mahmud II – text animation av ccprog (@ccprog) på CodePen.

Den ursprungliga utformningen, den Tughra av Osmanska Sultanen Mahmud II., är av en okänd 19-talet och kalligraf. Den vektoriserade versionen gjordes av Wikipedia illustratör Baba66. Animeringen är mitt försök att visualisera placeringen av den arabiska bokstäver inne i ritningen. Det bygger på en tidigare version av Baba66. Creative Commons Erkännande-Dela Lika 2.5.

Följande kodavsnitt visar den avancerade metod som används för att köra animationer i ordning och på ett repeterbart sätt.

mask väg {
fyllning: none;
stroke: vit.
stroke-width: 16;
}

.borsta {
fyllning: #0d33f2;
}
<mask id=”mask1″ maskUnits=”userSpaceOnUse”>
<sökväg stroke-dasharray=”160 160″ stroke-dashoffset=”160″ d=”…”>
<!– animation börjar efter dokument börjar och upprepar med ett klick
på “repeat” – knappen –>
<animera id=”animate1″ attributeName=”stroke-dashoffset”
från=”160″ till=”0″ begin=”1s;upprepa.klicka på” dur=”1.6 s” />
</sökväg>
</mask>
<mask id=”mask2″ maskUnits=”userSpaceOnUse”>
<sökväg stroke-dasharray=”350 350″ stroke-dashoffset=”350″ d=”…”>
<!– animation börjar vid slutet av den föregående –>
<animera id=”animate2″ attributeName=”stroke-dashoffset”
från=”350″ till=”0″ begin=”animate1.slutet” dur=”3,5 s” />
</sökväg>
</mask>
<!– mer masker… –>
<mask id=”mask15″ maskUnits=”userSpaceOnUse”>
<sökväg stroke-dasharray=”230 230″ stroke-dashoffset=”230″ d=”…”>
<!– infoga en konstgjord paus mellan animationer, som om
borsta hade lyfts –>
<animera id=”animate15″ attributeName=”stroke-dashoffset”
från=”230″ till=”0″ begin=”animate14.slut+0,5 s” dur=”2.3 s” />
</sökväg>
</mask>

<g class=”pensel”>
<sökväg id=”brush1″ d=”…”>
<!– Masken är endast tillämpas efter det att ett dokument börjar/och upprepar tills
animeringen har kört. Detta gör att borstarna är synliga i
renderare som inte har stöd för SMIL –>
<uppsättning attributeName=”mask” till=”url(#mask1)”
börja=”0: or;upprepa.klicka på” end=”animate1.slutet;obestämd” />
</sökväg>
<sökväg id=”brush2″ d=”…”>
<uppsättning attributeName=”mask” till=”url(#mask2)”
börja=”0: or;upprepa.klicka på” end=”animate2.slutet;obestämd” />
</sökväg>
<!– flera stigar… –>
<sökväg id=”brush15″ d=”…”>
<uppsättning attributeName=”mask” till=”url(#mask2)”
börja=”0: or;upprepa.klicka på” end=”animate15.slutet;obestämd” />
</sökväg>
<g>

I motsats till de andra exemplen vi har titta på denna animation använder SMIL, vilket innebär att det inte kommer att fungera i Internet Explorer och Edge.

Denna artikel är publicerad på tyska över på Webbläsaren…unplugged.

Jetpack WordPress plugin som körs på denna webbplats, driver inte bara relaterade inlägg nedan, men säkerhet och backup, Wiki-stöd, sök på sajten, kommentera form, sociala nätverk, och mycket mer!