TransWikia.com

Прямоугольники следуют по криволинейному пути

Stack Overflow на русском Asked by Alexandr_TT on December 1, 2020

С помощью 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.

One Answer

Это решение 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>

Свободный перевод ответа от участника @enxaneta.

Answered by Alexandr_TT on December 1, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP