Utilizing SVG
An example of using animateTransform
is demonstrated in the following code snippet. The circles' center points (cx and cy) are initially translated along the Y axis (by 100px), then animated back to their original position.
polyline {
stroke: black;
stroke-width: 1;
fill: transparent;
}
.container {
overflow: hidden;
height: 200px;
width: 200px;
border: 1px solid;
}
svg {
height: 100%;
width: 100%;
}
<div class="container">
<svg viewBox='0 0 100 100'>
<polyline points='25,35 33,75 50,33 89,22 15,65' />
<circle cx='25' cy='35' r='2'>
<animateTransform attributeName="transform" attributeType="XML" type="translate" from="0 -100" to="0 0" dur="2s" />
</circle>
<circle cx='33' cy='75' r='2'>
<animateTransform attributeName="transform" attributeType="XML" type="translate" from="-100 100" to="0 0" dur="2s" />
</circle>
<circle cx='50' cy='33' r='2'>
<animateTransform attributeName="transform" attributeType="XML" type="translate" from="0 100" to="0 0" dur="2s" />
</circle>
<circle cx='89' cy='22' r='2'>
<animateTransform attributeName="transform" attributeType="XML" type="translate" from="100 100" to="0 0" dur="2s" />
</circle>
</svg>
</div>
To optimize re-usability with patterns or behaviors for multiple elements, the use
element can be employed as shown below.
polyline {
stroke: black;
stroke-width: 1;
fill: transparent;
}
.container {
overflow: hidden;
height: 100%;
width: 100%;
border: 1px solid;
}
svg {
height: 100%;
width: 100%;
}
<div class="container">
<svg viewBox='0 0 100 100'>
<defs>
<g id='circle'>
<circle r='2'>
<animateTransform attributeName="transform" attributeType="XML" type="translate" from="0 -100" to="0 0" dur="2s" />
</circle>
</g>
<g id='circle2'>
<circle r='2'>
<animateTransform attributeName="transform" attributeType="XML" type="translate" from="100 0" to="0 0" dur="2s" />
</circle>
</g>
<g id='circle3'>
<circle r='2'>
<animateTransform attributeName="transform" attributeType="XML" type="translate" from="0 100" to="0 0" dur="2s" />
</circle>
</g>
</defs>
<polyline points='25,35 33,75 50,33 89,22 15,65 0,10 90,90' />
<use x='25' y='35' xlink:href='#circle' />
<use x='33' y='75' xlink:href='#circle2' />
<use x='50' y='33' xlink:href='#circle' />
<use x='89' y='22' xlink:href='#circle2' />
<use x='0' y='10' xlink:href='#circle3' />
<use x='0' y='10' xlink:href='#circle3' />
</svg>
</div>
CSS Approach
If CSS is a requirement, you can group polylines within one container div
, circular points within another, and animate the latter's transition using keyframes
and transform
.
polyline {
stroke: black;
stroke-width: 1;
fill: transparent;
}
.container {
position: relative;
overflow: hidden;
height: 200px;
width: 200px;
border: 1px solid;
}
svg {
height: 100%;
width: 100%;
}
.points,
.lines {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
}
.points {
transform: translateY(100%);
animation: movepoints 1s ease forwards;
}
@keyframes movepoints {
0% {
transform: translateY(100%);
}
100% {
transform: translateY(0%);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="container">
<div class="lines">
<svg viewBox='0 0 100 100'>
<polyline points='25,35 33,75 50,33 89,22 15,65' />
</svg>
</div>
<div class="points">
<svg viewBox='0 0 100 100'>
<circle cx='25' cy='35' r='2' />
<circle cx='33' cy='75' r='2' />
<circle cx='50' cy='33' r='2' />
<circle cx='89' cy='22' r='2' />
</svg>
</div>
</div>
Please note that positioning child elements absolutely within a percentage-based parent may cause issues if parent heights are not explicitly defined due to the absolute positioning. To ensure proper functionality with 100% dimensions set on the container, only absolutely position the div
containing the circular points.
polyline {
stroke: black;
stroke-width: 1;
fill: transparent;
}
.container {
position: relative;
overflow: hidden;
height: 100%;
width: 100%;
border: 1px solid;
}
svg {
height: 100%;
width: 100%;
}
.points,
.lines {
height: 100%;
width: 100%;
}
.points {
position: absolute;
top: 0px;
left: 0px;
transform: translateY(100%);
animation: movepoints 1s ease forwards;
}
@keyframes movepoints {
0% {
transform: translateY(100%);
}
100% {
transform: translateY(0%);
}
}
*{
margin: 0;
padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="container">
<div class="lines">
<svg viewBox='0 0 100 100'>
<polyline points='25,35 33,75 50,33 89,22 15,65' />
</svg>
</div>
<div class="points">
<svg viewBox='0 0 100 100'>
<circle cx='25' cy='35' r='2' />
<circle cx='33' cy='75' r='2' />
<circle cx='50' cy='33' r='2' />
<circle cx='89' cy='22' r='2' />
</svg>
</div>
</div>