Skip to content

css 运动路径与暂停动画

基于offset-path进行不规则动画

1、offset-path:指定运动的几何路径,接收svg里的path
2、offset-distance:控制当前元素基于 offset-path 运动的距离
3、offset-position:指定 offset-path 的初始位置(目前浏览器并没有任何变化,不建议使用该属性
4、offset-anchor:定义沿 offset-path 定位的元素的锚点。 这个也算好理解,运动的元素可能不是一个点,那么就需要指定元素中的哪个点附着在路径上进行运动
5、offset-rotate:定义沿 offset-path 定位时元素的方向,说人话就是运动过程中元素的角度朝向

示例代码

css
.ball {
  position: aboslute;
  width: 40px;
  height: 40px;
  clip-path: polygon(0 0, 100% 50%, 0 100%);
  background: linear-gradient(#fc0, #f0c);
  offset-path: path('M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80');
  animation: move 3000ms infinite alternate linear;
}
@keyframes move {
  0% {
    offset-distance: 0%;
  }
  100% {
    offset-distance: 100%;
  }
}

offset-path:表示运动的路径
offset-distance:表示运动的距离,可以是数值或者百分比单位,如果是100%则表示正好把所有的路都跑完了。如果路径是一个闭环的路径,百分比是可以大于100%的。

css
.ball {
  position: aboslute;
  width: 40px;
  height: 40px;
  clip-path: polygon(0 0, 100% 50%, 0 100%);
  background: linear-gradient(#fc0, #f0c);
  offset-path: path('M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80');
  offset-rotate: 39deg;
  animation: move 3000ms infinite alternate linear;
}
/* 
offset-rotate: auto;
offset-rotate: 39deg;
offset-rotate: reverse;
offset-rotate: auto 39deg;
*/

offset-rotate:表示运动的角度,默认是auto,表示自动计算当前路径的切线方向,并朝着这个方向前进。可以设置为固定值,保持一个角度运行。 也可以设置为一个关键字reverse,表示旋转180度。也可以把属性值组合起来,如:auto 39deg,表示自动计算当前路径的切线,但是偏移一定的角度。

css
.ball {
  position: aboslute;
  width: 40px;
  height: 40px;
  clip-path: polygon(0 0, 100% 50%, 0 100%);
  background: linear-gradient(#fc0, #f0c);
  offset-path: path('M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80');
  offset-anchor: center;
  animation: move 3000ms infinite alternate linear;
}

offset-anchor表示锚定的中心点,其属性值和transform-origin类似,元素运动的时候,会让这个点和路径重合进行运动。

暂停css动画

css
.stop-animate {
  animation-play-state: paused;
}

.run-animate {
  animation-play-state: running;
}

希望动画停止运行,只要给运动元素添加animation-play-state: paused即可。反之,设为 running,或移除 animation-play-stated 可以让动画继续

完整示例

html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    html,
    body {
      width: 100%;
      height: 100%;
      display: flex;
      flex-direction: column;
    }

    .g-svg {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }

    .g-wrap {
      position: relative;
      width: 400px;
      height: 160px;
      margin: auto;
    }

    .ball {
      position: absolute;
      width: 40px;
      height: 40px;
      clip-path: polygon(0 0, 100% 50%, 0 100%);
      offset-path: path('M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80');
      background: linear-gradient(#fc0, #f0c);
      animation: move 3000ms infinite alternate linear;
    }

    @keyframes move {
      0% {
        offset-distance: 0%;
      }

      100% {
        offset-distance: 100%;
      }
    }
  </style>
</head>

<body>
  <svg class="g-svg" width="400" height="160" xmlns="http://www.w3.org/2000/svg">
    <path d="M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80" stroke="black" fill="transparent" />
  </svg>
  <div class="g-wrap">
    <div class="ball"></div>
  </div>
</body>

</html>

Designed & Powerd by liujun