SVG animated lines
by hlmurray91
HTML
<section class="verticals">
<div class="vertical-circle">
<h2>Retail</h2>
<div class="vc-line">
<svg width="100%" height="100%" viewBox="0 0 100 100" x="0px" y="0px" preserveAspectRatio="none">
<g>
<path id="progress-path-1" vector-effect="non-scaling-stroke" class="path" fill="none" d="M0,50 L150,50"/>
<polygon id="process-arrow-1" points="0,0 0,5 5,2.5" style="transform: translate(0,-50%) scale(1.5);">
<animateMotion dur="5s" repeatCount="indefinite" rotate="auto" to="50">
<mpath xlink:href="#progress-path-1"/>
</animateMotion>
</polygon>
</g>
</svg>
</div>
</div>
<div class="vertical-circle left">
<h2>Transportation</h2>
<div class="vc-line">
<svg width="100%" height="100%" viewBox="0 0 100 100" x="0px" y="0px" preserveAspectRatio="none">
<g>
<path id="progress-path-2" vector-effect="non-scaling-stroke" fill="none" class="path" d="M4,0 L4,50,100,50"/>
<polygon id="process-arrow-2" points="0,0 0,5 5,2.5" style="transform: scale(0.5) translateY(-50%);">
<animateMotion dur="5s" repeatCount="indefinite" rotate="auto" to="50">
<mpath xlink:href="#progress-path-2"/>
</animateMotion>
</polygon>
</g>
</svg>
</div>
</div>
<div class="vertical-circle bottom">
<h2>Manufacturing</h2>
<div class="vc-line">
<svg width="100%" height="100%" viewBox="0 0 100 100" x="0px" y="0px" preserveAspectRatio="none">
<g>
<path id="progress-path-3" vector-effect="non-scaling-stroke" class="path" d="M50,0 L50,100"/>
<polygon id="process-arrow-3" points="0,0 0,6 1.5,3" style="transform: translate(0,-50%);">
<animateMotion dur="5s" repeatCount="indefinite" rotate="auto" to="50">
<mpath xlink:href="#progress-path-3"/>
</animateMotion>
</polygon>
</g>
</svg>
</div>
...
SCSS
body {
background: #003568;
}
.verticals {
width: 75%;
height: 100%;
margin: 0 auto;
clear: both;
.vertical-circle {
float: left;
position: relative;
margin: 40px 0 0;
width: 20%;
padding-bottom: 20%;
background-color: #0071C5;
border-radius: 50%;
&:nth-of-type(1) .vc-line {
transform: scale(-1, 1);
top: 0;
right: 100%;
}
&:nth-of-type(2) .vc-line {
height: auto;
transform: scale(-1, 1) translateX(-16px);;
top: 100%;
right: 50%;
}
&:nth-of-type(3) .vc-line {
top: 100%;
left: 0;
}
&:nth-of-type(4) .vc-line {
height: auto;
transform: translateX(-16px);
top: 100%;
left: 50%;
svg {
position: absolute;
top: 0;
}
&:before {
content: '';
display: block;
width: 100%;
height: 0;
padding-bottom: 100%;
}
}
&:nth-of-type(5) .vc-line {
top: 0;
left: 100%;
}
}
h2 {
margin: 0;
font-size: 10px;
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
color: #fff;
line-height: 1.5em;
font-family: Arial, sans-serif;
letter-spacing: 0.2em;
text-align: center;
text-transform: uppercase;
}
.vc-line {
position: absolute;
width: 100%;
height: 100%;
}
svg path {
stroke: #fff;
stroke-width: 1;
stroke-dasharray: 2,8;
}
svg polygon {
fill: #fff;
}
}
.line-animation {
background: #003568;
}
.line-animation svg path {
stroke: #fff;
stroke-width: 1;
stroke-dasharray: 2,8;
}
.line-animation svg polygon {
fill: #fff;
}
JavaScript
function lineWidth() {
$('.vertical-circle').each(function() {
var width = $(this).width()
, height = $(this).height()
, docWidth = $(document).width()
, docHeight = $(document).height()
, posL = $(this).offset().left
, posT = $(this).offset().top
;
if($(this).hasClass('left')) {
posL += width;
$(this).find('.vc-line').css('width', posL);
} else if($(this).hasClass('right')) {
var posR = docWidth - posL;
$(this).find('.vc-line').css('width', posR);
} else if ($(this).hasClass('bottom')) {
var posB = docHeight - height - posT;
$(this).find('.vc-line').css('height', posB);
}
});
}
lineWidth();
$(window).resize(lineWidth);