demo

Viewing the Online Version

  • Polygon’s PlayStation 4 Review

  • vivus.js – svg animation

The principle of

To implement the cool stroke animations above, we first need to understand the three properties in SVG that implement stroke animations: stroke, stroke-Dasharray, and stroke-dashoffset. These three properties are presented as appearance properties and can be used as CSS properties.

stroke

The stroke property in SVG is used to control how strokes are drawn, and we can also use CSS to control the stroke style of SVG.

Codepen. IO/xiaoluobodi…

stroke-dasharray

> > < span style = “font-size: 10.5pt; font-family: ‘font-size: 10.5pt; ; To achieve dashed lines in SVG, use the stroke-dasharray property.

Codepen. IO/xiaoluobodi…

stroke-dashoffset

The stroke-dashoffset attribute is used to specify the offset of the path from the starting position. The drawn line is offset by specifying an offset

The original position is blank

Codepen. IO/xiaoluobodi…

move

So combining the three properties above, let’s try dynamically changing the stroke-Dashoffset property and see what happens. Changing the offset property dynamically, combined with setting width and stroke-dasharray properties, gives the static line a paintbrush effect.

Codepen. IO/xiaoluobodi…

In actual combat

GreenSock provides DrawSVGPlugin to control the stroke effect of various graphics. The principle is to achieve the animation effect by controlling the stroke-Dasharray and stroke-Dashoffset CSS properties learned above.

Getting the SVG code

Here is the Hi There animation in Vivus as a Demo, open the Vivus official website, open the developer tools, here is using Chrome, select the Hi There DOM element, you can see the Hi There SVG code. Let’s right-click on the element and copy it.

You get the following code:

<div class="bloc bloc-head">
  <svg height="300" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0, 404.7 354" enable-background="new 0 0 404.7 354" id="hi-there" onclick="hi.reset().play();">

    <! -- HI -->
    <path data-duration="10" d=,29.5 "M324.6, 61.2 c16.6, 0-12.9, 29.5-29.5 c0-16.6-12.9-29.5-29.5-29.5 - c - 16.6, 0-29.5, 12.9, 29.5, 29.5 C295.1, 48.4, 308,61.2, 324.6 61.2 z ", style="stroke-dasharray: 186, 226; stroke-dashoffset: 0;"></path>
    <path data-duration="130" d="M366.2, 204.2 c to 9.8, 0-15-5.6-15-15.1 V77.2 h - 85 v28h19. 5 c9. 8,0,8.5, 2.1, 8.5, 11.6 v72.4 c0, 9.5, 0.5, 15.1, 9.3, 15.1 H277h - 20.7 - c - 8.5, 0-14.2-4.1-14.2-12.9 V52.4 c0-8.5, 5.7, 12.3, 14.2-12.3-28 h18.8 v h - 127 v28h18. 1 c8. 5,0,9.9, 2.1, 9.9, 8.9 v56.1 h - 75 v53. 4 c0-11.5, 8.6 13.3, 17-13.3 h11v - 28 h2. 2 v28h26c8. 5,0,12,2.1, 12,7.9 v142.2 c0, 8.5-3.6, 13.9-12,13.9 h - 21 v33h122v - 11 - c - 8.5-33 h, 0-17-4.1-17-12.2 v 57.8 h75v58. 4 c0, 9.1-1.4, 11.6, 9.9, 11.6 h - 18.1 v33h122. 9 h5. 9 h102. 2 v - 33 h366. 2 z" style="stroke-dasharray: 2216, 2256; stroke-dashoffset: 0;"></path>

    <path data-async="" data-delay="20" d="M358.8 c11.1 82.8-4.2, 18.8-14.7, 18.8-27.5 c0-8.5-3.4-16-8.9-21.3" style="stroke-dasharray: 60, 100; stroke-dashoffset: 0;"></path>
    <path data-async="" d="M124.2 V77c0 105.7-11.5, 9.1-13.8, 17.5-13.8 h10.5 V44.7" style="stroke-dasharray: 84, 124; stroke-dashoffset: 0;"></path>
    <path data-async="" d="M147.9, 40.2 L171.2, L175.7 63.2, 63.2," style="stroke-dasharray: 38, 78; stroke-dashoffset: 0;"></path>
    <path data-async="" d="M295.1, 32.1 L275.2, 12.2" style="stroke-dasharray: 29, 69; stroke-dashoffset: 0;"></path>
    <path data-async="" d="M266.2, 204.7 V75.9 c0-8.5, 5.2-12.8, 13.7-12.8 h18.3 V44.7" style="stroke-dasharray: 187, 227; stroke-dashoffset: 0;"></path>
    <path data-async="" d="M265.9, 105.2 L289.2, L293.7 129.2, 129.2," style="stroke-dasharray: 38, 78; stroke-dashoffset: 0;"></path>
    <path data-async="" d="M374.2, 204.7 L374.2, L358.8 94.2, 82.8 L351.2, 77.2" style="stroke-dasharray: 140, 180; stroke-dashoffset: 0;"></path>
    <path data-async="" d="M148.2, L171.2 237.2, 261.2 L294.6, 261.2 L300.5, 261.2 L402.2 L402.2 261.2, 228.2 L379.2, 204.2" style="stroke-dasharray: 331, 371; stroke-dashoffset: 0;"></path>
    <path data-async="" d="M124.2, 204.7 L124.2, L175.7 157.2, 157.2," style="stroke-dasharray: 99, 139; stroke-dashoffset: 0;"></path>
    <path data-async="" d="M147.7, 228.2 L129.2, 204.2" style="stroke-dasharray: 31, 71; stroke-dashoffset: 0;"></path>
    <path data-async="" d="M7.2, 237.3 L30.2, L152.2 261.2, 261.2 L152.2, 241.7" style="stroke-dasharray: 175, 215; stroke-dashoffset: 0;"></path>
    <path data-async="" d=L26 "M1.9, 40.2, 63.2 L39.7, 63.2" style="stroke-dasharray: 48, 88; stroke-dashoffset: 0;"></path>
    <path data-async="" d="M129.2, 12.2 L148.2, 33.2" style="stroke-dasharray: 29, 69; stroke-dashoffset: 0;"></path>
    <path data-async="" d="M303.9, 53 l328. 1,77.2" style="stroke-dasharray: 35, 75; stroke-dashoffset: 0;"></path>

    <path d="M345.1, 10.5 L368.7, 34" style="stroke-dasharray: 34, 74; stroke-dashoffset: 0;"></path>

    <! -- there -->
    <path data-delay="30" data-duration="60" stroke-linecap="round" stroke-linejoin="round" d=",1.9 M76.8, 337.3 c0, 0, 12.2, 13.1, 12.2, c22.1,23.8 0-1.8, 59-66.4 - c - 19.7, 35.7, 36.4, 66.2-19.3, 66.2 c15.2, 0,22.9-14.2, 28.3-23.7 c3. 24-3-0.5, 3.2, 25.5 c4-35-8.1, 4.1-17.8-8.1-15.2 - c - 5.6, 1.2, 13.1, 14.8, 15.7, 19.2-7.6 c, 12.7-22.4, 45.2-22.4, 45.2 s10.3-22.4, 21.5 2 2.4 c15.5, 0-9.4, 22.4, 4.7, 22.4 c4.9, 0,11.7-11.4, and 16.6 20.9 c7.5, 4.7, 19.7, 1.7, 24.5-8.1 c10.1-20.4-14.4-12.8-24.5, 8.1-5.5 c, 11.3 2.2, 21.1, 11.2 and 21.1 c16.4, 0,26.1-28.3, and 30.5 37.5 c9.9, 2.5, 14,2.5, 22.7-1.1 - c - 3.5, 5.1-24,38.1-8.3, 38.1 c6.7, 0,11.7-11.4, 16.6-20. 9 the c7. 5,4.7, 19.7, 1.7, 24.5-8.1 c10.1-20.4-14.4-12.8-24.5, 8.1-5.5 c, 11.3-2.2, 21.1, 11.2, 21.1 c16.4, 0,24.7,20.6-4-10.5" style="stroke-dasharray: 851, 891; stroke-dashoffset: 0;"></path>

    <path stroke-linecap="round" stroke-linejoin="round" d="M157.3, 29,0.8 c3.8-2.3-300.8-35.6, 3.2," style="stroke-dasharray: 37, 77; stroke-dashoffset: 0;"></path>
  </svg>
</div>
Copy the code

Analyze the animation timeline

If you look closely at the Hi There stroke animation in Vivus, There are four stages:

  1. I’m going to stroke oneHiDots of letters
  2. Then strokeHiThe letter
  3. Another strokeHi3D border of letters
  4. The last strokethereThe word

We define a class for the graph we want to stroke, in this case path, polyline, line, etc., for selection. Remove the useless vivus attribute and the optimized code is as follows:

<div class="bloc bloc-head">
  <svg height="300" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0, 404.7 354" id="hi-there">

    <! -- HI -->
    <path class="hi-o" fill="none" stroke="#FFFFFF" stroke-width="4" d=,29.5 "M324.6, 61.2 c16.6, 0-12.9, 29.5-29.5 c0-16.6-12.9-29.5-29.5-29.5 - c - 16.6, 0-29.5, 12.9, 29.5, 29.5 C295.1, 48.4, 308,61.2, 324.6 61.2 z ", />
    <path class="hi" fill="none" stroke="#FFFFFF" stroke-width="4" d="M366.2, 204.2 c to 9.8, 0-15-5.6-15-15.1 V77.2 h - 85 v28h19. 5 c9. 8,0,8.5, 2.1, 8.5, 11.6 v72.4 c0, 9.5, 0.5, 15.1, 9.3, 15.1 H277h - 20.7 - c - 8.5, 0-14.2-4.1-14.2-12.9 V52.4 c0-8.5, 5.7, 12.3, 14.2-12.3-28 h18.8 v h - 127 v28h18. 1 c8. 5,0,9.9, 2.1, 9.9, 8.9 v56.1 h - 75 v53. 4 c0-11.5, 8.6 13.3, 17-13.3 h11v - 28 h2. 2 v28h26c8. 5,0,12,2.1, 12,7.9 v142.2 c0, 8.5-3.6, 13.9-12,13.9 h - 21 v33h122v - 11 - c - 8.5-33 h, 0-17-4.1-17-12.2 v 57.8 h75v58. 4 c0, 9.1-1.4, 11.6, 9.9, 11.6 h - 18.1 v33h122. 9 h5. 9 h102. 2 v - 33 h366. 2 z" />

    <path fill="none" class="threedline" stroke="#FFFFFF" stroke-width="4" d="M358.8 c11.1 82.8-4.2, 18.8-14.7, 18.8-27.5 c0-8.5-3.4-16-8.9-21.3" />
    <path fill="none" class="threedline" stroke="#FFFFFF" stroke-width="4" d="M124.2 V77c0 105.7-11.5, 9.1-13.8, 17.5-13.8 h10.5 V44.7" />
    <polyline fill="none" class="threedline" stroke="#FFFFFF" stroke-width="4" points="147.9, 40.2, 171.2, 63.2, 175.7, 63.2," />
    <line fill="none" class="threedline" stroke="#FFFFFF" stroke-width="4" x1="295.1" y1="32.1" x2="275.2" y2="12.2" />
    <path fill="none" class="threedline" stroke="#FFFFFF" stroke-width="4" d="M266.2, 204.7 V75.9 c0-8.5, 5.2-12.8, 13.7-12.8 h18.3 V44.7" />
    <polyline fill="none" class="threedline" class="threedline" stroke="#FFFFFF" stroke-width="4" points="265.9, 105.2, 289.2, 129.2, 293.7, 129.2," />
    <polyline fill="none" class="threedline" stroke="#FFFFFF" stroke-width="4" points="374.2, 204.7, 374.2, 94.2, 358.8, 82.8, 351.2, 77.2," />
    <polyline fill="none" class="threedline" stroke="#FFFFFF" stroke-width="4" points="148.2,237.2 171.2,261.2 294.6,261.2 300.5,261.2 402.2,261.2 402.2,228.2 379.2,204.2" />
    <polyline fill="none" class="threedline" stroke="#FFFFFF" stroke-width="4" points="124.2, 204.7, 124.2, 157.2, 175.7, 157.2," />
    <line fill="none" class="threedline" stroke="#FFFFFF" stroke-width="4" x1="147.7" y1="228.2" x2="129.2" y2="204.2" />
    <polyline fill="none" class="threedline" stroke="#FFFFFF" stroke-width="4" points="7.2, 237.3, 30.2, 261.2, 152.2, 261.2, 152.2, 241.7," />
    <polyline fill="none" class="threedline" stroke="#FFFFFF" stroke-width="4" points=26,63.2 "1.9, 40.2, 39.7 63.2" />
    <line fill="none" class="threedline" stroke="#FFFFFF" stroke-width="4" x1="129.2" y1="12.2" x2="148.2" y2="33.2" />
    <line fill="none" class="threedline" stroke="#FFFFFF" stroke-width="4" x1="303.9" y1="53" x2="328.1" y2="77.2" />
    <line fill="none" class="threedline" stroke="#FFFFFF" stroke-width="4" x1="345.1" y1="10.5" x2="368.7" y2="34" />

    <! -- there -->
    <path class="there" fill="none" stroke="#FFFFFF" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d=",1.9 M76.8, 337.3 c0, 0, 12.2, 13.1, 12.2, c22.1,23.8 0-1.8, 59-66.4 - c - 19.7, 35.7, 36.4, 66.2-19.3, 66.2 c15.2, 0,22.9-14.2, 28.3-23.7 c3. 24-3-0.5, 3.2, 25.5 c4-35-8.1, 4.1-17.8-8.1-15.2 - c - 5.6, 1.2, 13.1, 14.8, 15.7, 19.2-7.6 c, 12.7-22.4, 45.2-22.4, 45.2 s10.3-22.4, 21.5 2 2.4 c15.5, 0-9.4, 22.4, 4.7, 22.4 c4.9, 0,11.7-11.4, and 16.6 20.9 c7.5, 4.7, 19.7, 1.7, 24.5-8.1 c10.1-20.4-14.4-12.8-24.5, 8.1-5.5 c, 11.3 2.2, 21.1, 11.2 and 21.1 c16.4, 0,26.1-28.3, and 30.5 37.5 c9.9, 2.5, 14,2.5, 22.7-1.1 - c - 3.5, 5.1-24,38.1-8.3, 38.1 c6.7, 0,11.7-11.4, 16.6-20. 9 the c7. 5,4.7, 19.7, 1.7, 24.5-8.1 c10.1-20.4-14.4-12.8-24.5, 8.1-5.5 c, 11.3-2.2, 21.1, 11.2, 21.1 c16.4, 0,24.7,20.6-4-10.5" />
    <path class="there" fill="none" stroke="#FFFFFF" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M157.3, 29,0.8 c3.8-2.3-300.8-35.6, 3.2," />
  </svg>
</div>
Copy the code

Realization of animation

GreenSock provides timeline for creating continuous staggered tween animations, which, understandably, are in order on a timeline.

Drawing an SVG path from 0% to 100% is animated with the DrawSVGPlugin.

// Create a timeline
let tl = gsap.timeline({ repeat: -1 })

/** * 1, First stroke a Hi letter dot * 2, then stroke the Hi letter * 3, then stroke the Hi letter 3D border * 4, finally stroke the there word */
tl
  .fromTo(
    '.hi-o',
    { drawSVG: "0%" },
    { duration: 3..drawSVG: "100%".stagger: 0.1 },
  )
  .fromTo(
    '.hi',
    { drawSVG: "0%" },
    { duration: 3.drawSVG: "100%".stagger: 0.2 },
  )
  .fromTo(
    '.threedline',
    { drawSVG: "0%" },
    { duration: 0.8.drawSVG: "100%" },
    "+ = 0.2"
  )
  .fromTo(
    '.there',
    { drawSVG: "0%" },
    { duration: 2.drawSVG: "100%".stagger: 0.5})Copy the code

End result:

Codepen. IO/xiaoluobodi…

reference

  • www.polygon.com/a/ps4-revie…
  • maxwellito.github.io/vivus/
  • Developer.mozilla.org/zh-CN/docs/…
  • Css-tricks.com/svg-line-an…

about

This is the fifth chapter of the SVG animation development series.

Version of the Notion

The litany was written on Notion, so I’ve kept a shared version of Notion, which you can also view here.

Making version

The brochure offers a GitHub version of the online reading experience, Portal

Wechat official account version

Follow my technical official number, also can find this booklet series, currently in the update…