Прямоугольники следуют по криволинейному пути
С помощью div, shapes или svgs можно ли изогнуть элемент, чтобы он следовал по криволинейному пути?
Ниже просто пример, но представьте прямоугольники, изгибающиеся по краям, прямо сейчас он только что повернул на 90 градусов от одного кадра к другому.
<!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>
Свободный перевод вопроса Curve rectangle to follow a path от участника @Mateus Silva.
Ответы (1 шт):
Это решение SVG. Я использую 4 перекрывающихся paths, где stroke-dasharray выглядит следующим образом: stroke-dasharray: 2 2 2 2 2 2 2 2 2 2 242 Если вы суммируете тире и промежутки, общее количество равно 260.
Также добавлено stroke-linecap: round. Когда тире находятся очень близко к одному из других
stroke-linecap: round, они накладываются друг на друга, создавая видимость непрерывной линии.
Общая длина path также составляет 260. Я анимирую свойство stroke-dashoffset 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>
UPDATE
Чтобы избежать мерцания в углах, я меняю прямоугольные path на path со скругленными углами. Чтобы прояснить, что я имею в виду, я добавляю дополнительный path: #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>