Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to animate handwriting text on the web page using SVG?

Tags:

css

animation

svg

I am trying to animate a text that I created and saved as SVG. So far, I've only been able to animate the stroke, but that's not what I am trying to achieve. How can I implement animation like the two examples, below?

http://codepen.io/se7ensky/pen/waoMyx
https://codepen.io/munkholm/pen/EaZJQE

Here is what I have so far:

.test {
  width: 300px
  /*   margin:0 auto; */
}

.l1 {
  animation: dash 15s 1;
  stroke-linecap: round;
  stroke-miterlimit: 10;
  stroke-dasharray: 300;
  stroke-dashoffset: 300;
  animation-fill-mode: forwards;
  /*fill: none;*/
}

.l2 {
  stroke-dasharray: 300;
  stroke-dashoffset: 300;
  animation: dash 20s linear forwards;
  -webkit-animation-delay: 1s;
  /* Chrome, Safari, Opera */
  animation-delay: 1s;
}

.l3 {
  stroke-dasharray: 300;
  stroke-dashoffset: 300;
  animation: dash 25s linear forwards;
  -webkit-animation-delay: 2.5s;
  /* Chrome, Safari, Opera */
  animation-delay: 2.5s;
}

.l4 {
  stroke-dasharray: 300;
  stroke-dashoffset: 300;
  animation: dash 25s linear forwards;
  -webkit-animation-delay: 4.5s;
  /* Chrome, Safari, Opera */
  animation-delay: 4.5s;
}

@keyframes dash {
  to {
    stroke-dashoffset: 0;
  }
}
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg class="test" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 30.1 21.8" style="enable-background:new 0 0 30.1 21.8;" xml:space="preserve">
    <g>
    	<path class="text l1" d="M16.5,9.2c-0.2-0.2-0.2-1,0.1-1.5c0.1-0.1,0.2-0.3,0.3-0.4c-1.6,0-3.2-0.3-4.7-0.1C10.8,7.3,9.5,8,9.3,8.9
    		c-0.1,0.6,0.5,0.8,0.7,1c0.1,0.1,0,0.2-0.1,0.1C9.5,10,8.7,9.4,9,8.7c0,0,0-0.1,0-0.2c0.3-1.2,1.7-1.8,3.3-1.9
    		c1.8-0.1,3.9,0.4,4.8,0.4c0.2-0.2,0.4-0.4,0.5-0.4c0.3-0.1,0.6,0.1,0.3,0.4c-0.1,0.1-0.4,0.3-0.6,0.5c-0.4,0.4-0.8,1-0.5,1.5
    		C16.8,9.2,16.7,9.3,16.5,9.2z M12.1,12.8c0.1,0.1-0.1,0.3-0.1,0.3c-0.2,0.3-0.5,0.8-0.8,0.8c-0.1,0-0.5-0.1-0.5-0.1
    		c-0.1-0.8,1.5-3.5,1.9-4.2c0.2-0.3,0.1-0.4,0.1-0.5c0.1-0.4,0.9-1.4,1.5-1.4c0.2,0,0.8,0.2,0.7,0.5c0,0-0.1-0.1-0.2-0.1
    		c-1.1,0-2.9,3.6-3.4,4.7c-0.3,0.7,0.1,0.6,0.4,0.3C11.8,13,12,12.8,12.1,12.8z" fill="red" stroke="#000" stroke-miterlimit="10" stroke-width="0.5" />
    	<path class="text l2" d="M14.4,12.3c-0.2,0-0.3-0.2-0.1-0.2c0.4,0,1.1-0.4,1.5-0.8c0.2-0.2,0.6-0.5,0.5-0.8c0-0.3-0.4-0.2-0.6-0.1
    		c-0.7,0.3-1.7,1.3-2,2.2c-0.3,1,0.6,1,1.4,0.7c0.9-0.4,1.7-1,2.1-1.7c0-0.1,0.1-0.1,0.1,0c0.1,0,0.1,0.1,0,0.1
    		c-0.5,0.8-1.2,1.5-2.1,1.8c-1.2,0.5-2.8,0-2.1-1.5c0.4-0.8,2.2-2.4,3.1-2.1c0.5,0.2,0.4,0.8,0.2,1.1C16.1,11.8,15,12.2,14.4,12.3z" fill="none" stroke="#000" stroke-miterlimit="5" stroke-width="0.5"
    		/>
    	<path class="text l3" d="M17.3,13.6c-0.2,0.2-0.1,0.5,0.4,0.4c0.6-0.2,1.5-0.9,1.5-1.6c0-0.3-0.7-0.6-0.9-0.7c-0.2-0.1-0.3-0.3-0.4-0.4
    		c-0.1,0.2-0.3,0.5-0.5,0.8c-0.1,0.1-0.3,0-0.2-0.1c0.3-0.5,0.6-0.9,0.6-1.1c0.1-0.9,1.7-1.7,2.6-1.7c0.5,0,1,0.3,0.7,0.8
    		c-0.1,0.2-0.2,0.3-0.4,0.4c-0.1,0-0.2,0-0.1-0.2c0.2-0.2,0.3-0.6,0-0.6c-0.4,0-1,0.2-1.3,0.4c-0.4,0.2-0.7,0.4-1,0.9
    		c-0.3,0.3-0.2,0.6,0.1,0.8c0.8,0.5,1.8,0.8,0.9,1.8c-0.4,0.5-1.1,0.7-1.7,0.9c-0.2,0-0.7,0.1-0.9-0.1c-0.1-0.1,0-0.3,0.2-0.5
    		c0.1-0.1,0.3-0.3,0.6-0.3c0.1,0,0.1,0.1,0,0.1C17.5,13.4,17.3,13.5,17.3,13.6z" fill="none" stroke="#000" stroke-miterlimit="5" stroke-width="0.5"/>
    	<path class="text l4" d="M23.6,10.2c-0.2,0.1-0.8,0.1-1.4,0.2c-0.2,0.3-0.3,0.5-0.3,0.6c-0.4,0.7-0.7,1.4-0.7,1.7c-0.1,0.5,0.2,0.8,0.6,0.6
    		c0.4-0.2,1.3-1,1.8-1.7c0.1-0.1,0.2,0,0.1,0.1c-0.2,0.4-1,1.2-1.6,1.6c-0.4,0.3-1.3,0.6-1.5-0.1c-0.1-0.3,0.1-0.9,0.4-1.5
    		c-0.1,0.1-0.2,0.3-0.5,0.6c-0.1,0.1-0.2,0-0.1-0.2c0.4-0.5,0.7-1,0.9-1.2c0,0,0.1-0.2,0.3-0.5c-0.1,0-0.2,0-0.3,0
    		c-0.1,0-0.2-0.1-0.2-0.3c0.1-0.2,0.4-0.2,0.6-0.2c0,0,0,0,0,0l0.6-1.1c0.3-0.5,0.3-0.6,0.5-0.7c0.2,0,0.4,0,0.5,0.1
    		c0.1,0.1,0,0.4-0.1,0.5C23.2,9,23.1,9,23,9.1l-0.6,1l0.2,0c0.4,0,0.7-0.1,1.1-0.1C23.9,10,24.1,10.1,23.6,10.2z" fill="none" stroke="#000" stroke-miterlimit="5" stroke-width="0.5"/>
    </g>
    <g></g>
    <g></g>
    <g></g>
    <g></g>
    <g></g>
    <g></g>
</svg>

View on CodePen

like image 500
nb_ck Avatar asked Jun 12 '16 22:06

nb_ck


People also ask

Can SVG files animate?

SVG supports the ability to change vector graphics over time, to create animated effects. SVG content can be animated in the following ways: Using SVG's animation elements [svg-animation]. SVG document fragments can describe time-based modifications to the document's elements.


2 Answers

How the Se7ensky animation works is that it uses the standard dash animation technique, but clips the animated stroke with an outline representing the hand-drawn look of the logo.

So the standard dash animation technique works as follows. You take a standard line:

<svg>
  <path d="M 10,75 L 290,75" stroke="red" stroke-width="50"/>
</svg>

Then you add a dash pattern to it and animate it's position (stroke-dashoffset).

.pen {
  stroke-dasharray: 280 280;
  stroke-dashoffset: 280;
  animation-duration: 2s;
  animation-name: draw;
  animation-iteration-count: infinite;
  animation-direction: alternate;
  animation-timing-function: linear;
}

@keyframes draw {
  from {
    stroke-dashoffset: 280;
  }

  to {
    stroke-dashoffset: 0;
  }
}
<svg>
  <path class="pen" d="M 10,75 L 290,75" stroke="red" stroke-width="50"/>
</svg>

Finally to get the fancy variable stroke width of the Se7ensky example, you clip that line with the outline of your logo.

So let's pretend this simple path below represents your logo:

<svg>
  <path stroke="black" stroke-width="1" fill="lightgrey"
        d="M 40,50
           C 110,55 195,60, 265,55
           C 290,55 290,85 265,85
           C 195,85 110,85 40,100
           C 0,100 0,50 40,50 Z"/>
</svg>

We turn that into a clipPath element and use it to trim our animated stroke to the shape of our logo:

.pen {
  stroke-dasharray: 280 280;
  stroke-dashoffset: 280;
  animation-duration: 2s;
  animation-name: draw;
  animation-iteration-count: infinite;
  animation-direction: alternate;
  animation-timing-function: linear;
}

@keyframes draw {
  from {
    stroke-dashoffset: 280;
  }

  to {
    stroke-dashoffset: 0;
  }
}
<svg>
  <clipPath id="logo">
    <path d="M 40,50
             C 110,55 195,60, 265,55
             C 290,55 290,85 265,85
             C 195,85 110,85 40,100
             C 0,100 0,50 40,50 Z"/>
  </clipPath>
  
  <path class="pen" d="M 10,75 L 290,75" stroke="red" stroke-width="50" clip-path="url(#logo)"/>
</svg>

So to replicate their example, you'll need to add a continuous path (or paths if you want) to your SVG that represents the path that a pen would take if it were writing the letters in your logo.

Then animate that path using the dashoffset technique while clipping it with your original logo.


Update

Here's a final demo with a more realistic letter shape:

// Simple code to enable and disable the clipping path
var chk = document.getElementById("chk");
var penpath = document.getElementById("penpath");

chk.addEventListener("input", function(evt) {
  if (evt.target.checked) {
    penpath.classList.add("clipped");
  } else {
    penpath.classList.remove("clipped");
  }
});
.pen {
  fill: none;
  stroke: red;
  stroke-width: 18;
  stroke-linecap: round;

  stroke-dasharray: 206 206;
  stroke-dashoffset: 206;
  animation-duration: 2s;
  animation-name: draw;
  animation-iteration-count: infinite;
  animation-direction: alternate;
  animation-timing-function: linear;
}

.clipped {
  clip-path: url(#logo);
}

@keyframes draw {
  from {
    stroke-dashoffset: 206;
  }

  to {
    stroke-dashoffset: 0;
  }
}
<svg>
  <defs>
    <clipPath id="logo">
      <path d="m85.77 49.77c-10.59 8.017-27.38 21.95-41.58 21.95-6.396 0-12.99-2.481-12.39-9.735l0.3998-4.199c38.38-12.03 48.17-26.15 48.17-35.5 0-7.635-7.995-9.162-14.39-9.162-25.98-0.1909-54.97 25.39-54.17 50.39 0.3998 12.6 7.196 25.01 21.79 25.01 19.79 0 41.78-17.94 53.97-31.5zm-52.37-1.336c5.397-12.6 16.99-21.76 26.98-24.24 1.399-0.3818 2.399 0.7635 2.399 2.1 0.1999 3.245-11.79 16.42-29.38 22.14z"/>
    </clipPath>
  </defs>
  
  <path id="penpath" d="m39.02 51.1c5.361-1.771 10.04-4.182 15.98-7.857 6.019-3.933 9.841-7.728 12.77-10.71 1.403-1.369 12.03-15.97-7.857-13.93-9.824 1.01-19.62 8.3-26.16 14.91-6.538 6.61-10.42 14.51-11.96 22.23-2.559 12.76 1.807 26.19 21.07 23.48 13.96-1.965 32.59-14.55 43.66-25.54" class="pen clipped"/>
</svg>


<p>
<input id="chk" type="checkbox" checked="true"/> <label for="chk">Enable clipping path</label>
</p>
like image 107
Paul LeBeau Avatar answered Oct 18 '22 09:10

Paul LeBeau


The example looks like a combination of svg paths and delayed animations.

This blog post by CSS-Tricks explains it pretty well (Note that the svg must have strokes for this to work): https://css-tricks.com/svg-line-animation-works/

Here's a guide on stroke-dashoffset (used on the example) that might be useful: https://css-tricks.com/almanac/properties/s/stroke-dashoffset/

like image 21
Diego Avatar answered Oct 18 '22 10:10

Diego