如何使用JS / jQuery制作此动画?

时间:2019-07-31 16:05:10

标签: javascript svg scroll css-animations

我正在使用CSS为沿路径的点设置动画。
如何滚动显示动画?
如何根据路径计算点的位置?

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 400">
  <g fill="none" fill-rule="evenodd">
    <path stroke="#29a0ec" stroke-width="2px" d="M22 1c417.705 78.667 631.039 274.847 640 588.542C657.222 953.18 436.555"></path>
  </g>

body {
  background-color: #cff;
  height: 3000px;
}

.pulse1 {
  width: 55px;
  height: 55px;
  position: absolute;
  top: -17px;
  left: 25px;
}

.pulse1:before,
.pulse1:after {
  content: "";
  position: absolute;
  top: -5px;
  left: -5px;
  width: calc(100% + 10px);
  height: calc(100% + 10px);
  border: 1px solid rgba(41, 160, 236, 0.6);
  border-radius: 100%;
  -webkit-animation: pulse 3s linear infinite;
  animation: pulse 3s linear infinite;
}

.pulse1:after {
  top: -10px;
  left: -10px;
  width: calc(100% + 20px);
  height: calc(100% + 20px);
  -webkit-animation: pulse 3s linear infinite;
  animation: pulse 3s linear infinite;
}

.pulse2 {
  width: 35px;
  height: 35px;
  margin: 10px;
  position: relative;
}

.pulse2:before,
.pulse2:after {
  content: "";
  position: absolute;
  top: -5px;
  left: -5px;
  width: calc(100% + 10px);
  height: calc(100% + 10px);
  border: 1px solid rgba(41, 160, 236, 0.3);
  border-radius: 100%;
  -webkit-animation: pulse 3s linear infinite;
  animation: pulse 3s linear infinite;
}

.pulse2:after {
  top: -10px;
  left: -10px;
  width: calc(100% + 20px);
  height: calc(100% + 20px);
  -webkit-animation: pulse 3s linear infinite;
  animation: pulse 3s linear infinite;
}

.pulse3 {
  width: 30px;
  height: 30px;
  position: absolute;
  top: 10px;
  left: 10px;
}

.pulse3:before {
  content: "";
  position: absolute;
  top: -10px;
  left: -10px;
  width: calc(100% + 5px);
  height: calc(100% + 5px);
  border: 1px solid rgba(41, 160, 236, 0.6);
  border-radius: 100%;
  -webkit-animation: pulse 3s linear infinite;
  animation: pulse 3s linear infinite;
}

.pulse3:after {
  content: "";
  position: absolute;
  top: -5px;
  left: -5px;
  width: calc(100% - 5px);
  height: calc(100% - 5px);
  border: 1px solid rgba(41, 160, 236, 0.5);
  border-radius: 100%;
  -webkit-animation: pulse 3s linear infinite;
  animation: pulse 3s linear infinite;
}

.pulse4 {
  width: 10px;
  height: 10px;
  background-color: rgba(41, 160, 236, 1);
  border-radius: 50%;
  position: absolute;
  top: 3px;
  left: 3px;
}

.pulse4:before {
  content: "";
  position: absolute;
  top: -5px;
  left: -5px;
  width: calc(100% + 10px);
  height: calc(100% + 10px);
  background-color: rgba(41, 160, 236, 0.6);
  border-radius: 100%;
}

@keyframes pulse {
  0% {
    opacity: 0;
    transform: scale(1);
  }
  50% {
    opacity: 1;
    transform: scale(1.4);
  }
  100% {
    opacity: 0;
    transform: scale(1.8);
  }
}

@-webkit-keyframes pulse {
  0% {
    opacity: 0;
    transform: scale(1);
  }
  50% {
    opacity: 1;
    transform: scale(1.4);
  }
  100% {
    opacity: 0;
    transform: scale(1.8);
  }
}
<div class="box">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 400">
      <g fill="none" fill-rule="evenodd">
        <path stroke="#29a0ec" stroke-width="2px" d="M22 1c417.705 78.667 631.039 274.847 640 588.542C657.222 953.18 436.555"></path>
        <circle cx="21.5" cy="1" r="5" fill="#29a0ec">
            <animateMotion id="animate" path="M22 1c417.705 78.667 631.039 274.847 640 588.542C657.222 953.18 436.555" begin="0s" dur="10s" repeatCount="indefinite" rotate="auto"></animateMotion>
        </circle>
      </g>
  </svg>
</div>

View on CodePen (with original SCSS)

1 个答案:

答案 0 :(得分:0)

以下是简单的二次贝塞尔曲线路径的点计算示例:

const a = {x: 20, y: 20};
const b = {x: 400, y: 20};
const c = {x: 480, y: 280};

const getCoordinate = (t,coord) => a[coord] * t * t + 2 * b[coord] * t * (1-t) + c[coord] * (1-t) * (1-t);

const qbPos = t => {
	
	const x = getCoordinate(t, 'x');
	const y = getCoordinate(t, 'y');
	return {x, y};
};

const point = document.getElementById("point");

const movePoint = t => {
	const pos = qbPos(t);
	point.setAttribute('cx', pos.x);
  point.setAttribute('cy', pos.y);
		
	t = t <= 0 ? 1 : t - 0.001;
	setTimeout(() => movePoint(t), 1);
};

movePoint(1);
<svg width="500" height="300">
	<path d="M 20,20 Q 400,20 480,280" stroke-width="3" stroke="blue" fill="none"/>
	<circle id="point" cx="20" cy="20" r="10" fill="blue"/>
</svg>

相关问题