03. SVG Stroke Animations

Any SVG element can have a dashed stroke applied to it. By making that dash the same length of the path contour you can create a single line you can animate.

First we need to set the attribute pathLength to 1 on the path we want to animate. This makes the animation easier as now the length of the path is equal to 1 for our code.

Now you can set the stroke-dasharray and stroke-dashoffset properties to 1px in our CSS and animate the dashoffset to 0.

Self drawing heart

<svg viewBox="0 0 100 100">
	<style>
		.animated-heart {
			fill: none;
			stroke: red;
			stroke-width: 2px;
			stroke-linecap: round;
			stroke-dasharray: 1px;
			stroke-dashoffset: 1px;
			animation: drawHeart 3s ease-out infinite;
		}
		@keyframes drawHeart {
			90%, 100% {
				stroke-dashoffset: 0px;
			}	
		}
	</style>
	<path class="animated-heart" pathLength="1" d="M49.998,90.544c0,0,0,0,0.002,0c5.304-14.531,32.88-27.047,41.474-44.23C108.081,13.092,61.244-5.023,50,23.933  C38.753-5.023-8.083,13.092,8.525,46.313C17.116,63.497,44.691,76.013,49.998,90.544z" />
</svg>

Self drawing heart with brush effect

In this demo the heart to animate is no more a single path with a stroke but a more complex SVG group of paths.
To do the trick here, we are going to apply the texture on the animated stroke as a clip-path.

This technique is useful when you want to make a text appear but the text is more complex than single paths with strokes.

<svg viewBox="0 0 300 300">
	<style>
		.animated-heart-clip {
			fill: none;
			stroke: red;
			stroke-width: 17;
			stroke-linecap: round;
			stroke-dasharray: 1px;
			stroke-dashoffset: 1px;
			animation: drawHeart 3s ease-out infinite;
		}

		@keyframes drawHeart {
			90%, 100% {
				stroke-dashoffset: 0px;
			}
		}
	</style>
	<clipPath id="clipHeart">
		<path d="M141.8 252.3c.4.8.5-.1 1.4 2.6 2.5 3.1 2.2 3.4 3.1 3.4 1.6 2 2.6 4.6.9 2.3.9 1.4 1.9 2.8 3.9 6.4l-1.9-4.1c.9.8 1.6 3.1 4.1 7.6-1.5-3.3-1.2-3.2-3.4-7.4l.4.3-3.4-5.8c.2.1.3-.1 1 1.1-1.8-3.4-2.5-3-7.1-8 .1.4.5.8 1 1.6z"></path>
		<path d="M137.8 245c-3.3-2.2-2.7-1.9-6.5-6.2-2-1.3-2.1-1 .3 1.2-9.5-7.8 1.5 2 8.9 10.5l-.7-.8.6-.7c-1-.9-1.7-1.9-2.6-2.9 1.6 1.5 3.4 2.9 4.9 4.5-.6-2.3-5.2-6.9-6.7-9 1.6 2.9-1.9-1.6 1.8 3.4z"></path>
		<!-- [...] All the brush paths are here but hidden to make this readable -->
	</clipPath>
	<path class="animated-heart-clip" clip-path="url(#clipHeart)" pathLength="1" d="M150 271.6c15.9-43.6 98.6-81.1 124.4-132.7 49.8-99.7-90.7-154-124.4-67.1-33.7-86.9-174.2-32.5-124.4 67.1C51.3 190.5 134.1 228 150 271.6z"></path>
</svg>

Hover to remove the clip-path from the stroke