Reputation: 826
It is possible with divs, shapes or svgs to curve an item to follow the curve of the path.
It's just an example, but imagine the rectangles curving on the edges, right now it's just had turn 90deg from one frame to another
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>frame</title><style>
main {
width: 100vw;height: 100vh;position: absolute;
}
div {
display: none;position: absolute;will-change: offset-distance;width: 200px;
height: 40px;background: hsl(313,100%,50%);offset-anchor: top;
offset-rotate: auto;offset-path: path('M 0 0 L 600 0 L 600 400 L 0 400 L 0 0');
}
div:nth-of-type(4n+2) {background: hsl(343,100%,50%)}
div:nth-of-type(4n+3) {background: hsl(13,100%,50%)}
div:nth-of-type(4n+4) {background: rgb(37, 16, 226)}
body {margin: 0;padding: 0;}
svg, aside { display: none;}
div { display: block; }
* {box-sizing: border-box;}
</style>
</head> <body> <main><div></div> <div></div> <div></div> <div></div> <div></div><div></div> </main>
<script>
var rateRange = document.getElementById('playback-rate');
var shapers = [].slice.call(document.querySelectorAll('div'));
var DURATION = 200000;
var animations = [];
shapers.forEach(function(s, i) {
var animation = s.animate([
{offsetDistance: 0},
{offsetDistance: '100%'}
], {
duration: DURATION,
delay: -i / shapers.length * DURATION,
iterations: Infinity
});
animations.push(animation);
});
</script>
</body>
</html>
Upvotes: 4
Views: 118
Reputation: 33044
This is an svg solution. I'm using 4 overlapping paths where the stroke-dasharray is like this: stroke-dasharray: 2 2 2 2 2 2 2 2 2 242
If you are summing the dashes and the gaps the total is 260.
Also stroke-linecap: round
When the dashes are very near one of the other stroke-linecap: round
make them overlapping giving the apparence of a continuos line.
The total length of the path is also 260. I'm animating the stroke.dashoffset
property of the path.
path {
fill: none;
stroke-width: 10;
stroke-linecap: round;
stroke-dasharray: 2 2 2 2 2 2 2 2 2 242;
animation: dash 5s linear infinite;
}
@keyframes dash {
to {
stroke-dashoffset: -260;
}
}
<svg viewBox="0 0 100 70" >
<path id="pth" stroke="red" d="M10,10L90,10L90,60L10,60z" />
<path stroke="blue" d="M70,10L90,10L90,60L10,60L10,10z" />
<path stroke="green" d="M90,60L10,60L10,10L90,10z" />
<path stroke="orange" d="M30,60L10,60L10,10L90,10L90,60z" />
</svg>
In order to avoid the flickering at the corners I'm changing the rectangular paths to paths with rounded corners. T make it clear what I mean by this I'm adding an extra path: the #track
.
path {
fill: none;
stroke-width: 10;
stroke-linecap: round;
stroke-dasharray: 2 2 2 2 2 2 2 2 2 225;
animation: dash 5s linear infinite;
}
#track {
stroke-width: 1;
stroke-dasharray: 245 0;
}
@keyframes dash {
to {
stroke-dashoffset: -245;
}
}
svg {
width: 300px;
}
<svg viewBox="0 0 100 70">
<path id="pth" stroke="red" d="M27.000,10.000 Q37,10 47.000,10.000L80.000,10.000 Q90,10 90.000,20.000L90.000,50.000 Q90,60 80.000,60.000L20.000,60.000 Q10,60 10.000,50.000L10.000,20.000 Q10,10 20.000,10.000Z" />
<path stroke="blue" d="M90.000,27.000 Q90,37 90.000,47.000L90.000,50.000 Q90,60 80.000,60.000L20.000,60.000 Q10,60 10.000,50.000L10.000,20.000 Q10,10 20.000,10.000L80.000,10.000 Q90,10 90.000,20.000Z" />
<path stroke="green" d="M73.000,60.000 Q63,60 53.000,60.000L20.000,60.000 Q10,60 10.000,50.000L10.000,20.000 Q10,10 20.000,10.000L80.000,10.000 Q90,10 90.000,20.000L90.000,50.000 Q90,60 80.000,60.000Z" />
<path stroke="orange" d="M10.000,45.000 Q10,35 10.000,25.000L10.000,20.000 Q10,10 20.000,10.000L80.000,10.000 Q90,10 90.000,20.000L90.000,50.000 Q90,60 80.000,60.000L20.000,60.000 Q10,60 10.000,50.000Z" />
<path id="track" d="M90.000,27.000 Q90,37 90.000,47.000L90.000,50.000 Q90,60 80.000,60.000L20.000,60.000 Q10,60 10.000,50.000L10.000,20.000 Q10,10 20.000,10.000L80.000,10.000 Q90,10 90.000,20.000Z" stroke="black" />
</svg>
Upvotes: 4