我试图创建跟随其他事物旋转的圆形动画...我很难创建渐变圆形动画:https://jsfiddle.net/rmtu913c/

圆圈的动画代码为:

.circular-loader {
height: 116%;
width: 121%;
animation: rotate 5s ease-in-out infinite;
transform-origin: center center;
position: absolute;
top: 0;
left: 0;
margin: auto;
}


到目前为止,我的问题是渐变始终可见,而现在我只是旋转svg容器,而我某种程度上需要创建某种“蒙版”以实现所需的效果...

我试图达到的目标是:
Circle Animation Illustrated

我希望有人对如何实现这一目标有所了解...我一直在尝试各种方式,大约7小时,但还是没有运气:( :(

最佳答案

生成使用线性渐变近似圆弧渐变的半圆形渐变版本非常容易。



body {
  background-color: #2f2f2f;
}

path {
  animation: rot 1.5s linear infinite;
}

@keyframes rot {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

<svg width="300" height="300">
  <defs>
    <linearGradient id="bluefade" x1="0" y1="1" x2="0" y2="0">
      <stop offset="0.05" stop-color="#fff" stop-opacity="0"/>
      <stop offset="1" stop-color="#12b1db" stop-opacity="1"/>
    </linearGradient>
  </defs>

  <g transform="translate(150,150)">
    <path d="M 0,-120 A 120,120 0 0 0 0,120"
          fill="none" stroke="url(#bluefade)" stroke-width="25"/>
  </g>
</svg>





但是您的一个人并非一直都是完整的半圆。它似乎从12点的零长度开始增长,直到6点才达到180度的全长。有点棘手。

我认为您将需要使用Javascript修改渐变设置(位置),因此它适合每个进度百分比。这需要一些三角函数来计算正确的位置。



var progress = document.getElementById("progress");
var bluefade = document.getElementById("bluefade");
var RADIUS = 120;

function setProgress(percent)
{
  // Rotation of our semicircular disc representing the progress
  var rotateDeg = (percent * 360) / 100;

  // Calculate position of trailing position of arc segment.
  // At progress=0%, it will be at the same position as the leading point
  // (0,-120),, a zero degree arc segment.
  // At 25% (3 o'clock) it will be at the 9 o'clock position of the semicircle.
  // At 50% (6 o'clock) it will be at the other side of the semicircle (ie 180deg
  // or (0,120). At >50% it doesn't move from that position.
  // This is also made the trailing point of the gradient.
  var trailAngleRad = Math.min(Math.PI, (percent * Math.PI * 2)/100);
  var x1 = -Math.sin(trailAngleRad) * RADIUS;
  var y1 = -Math.cos(trailAngleRad) * RADIUS;

  // Update the path
  progress.setAttribute("d", "M 0,-120 A 120,120 0 0 0 " + x1 + "," + y1);
  // Update the gradient
  bluefade.x1.baseVal.value = x1;
  bluefade.y1.baseVal.value = y1;

  progress.setAttribute("transform", "rotate(" + rotateDeg + ")");
}

setProgress(20);

body {
  background-color: #2f2f2f;
}

<svg width="300" height="300">
  <defs>
    <linearGradient id="bluefade"
                    gradientUnits="userSpaceOnUse"
                    x1="0" y1="120" x2="0" y2="-120">
      <stop offset="0.05" stop-color="#fff" stop-opacity="0"/>
      <stop offset="1" stop-color="#12b1db" stop-opacity="1"/>
    </linearGradient>
  </defs>

  <g transform="translate(150,150)">
    <path id="progress" d="M 0,-120 A 120,120 0 0 0 0,120"
          fill="none" stroke="url(#bluefade)" stroke-width="25"/>
  </g>
</svg>





或以动画形式在这里:



var progress = document.getElementById("progress");
var bluefade = document.getElementById("bluefade");
var RADIUS = 120;

function setProgress(percent)
{
  // Rotation of our semicircular disc representing the progress
  var rotateDeg = (percent * 360) / 100;

  // Calculate position of trailing position of arc segment.
  // At progress=0%, it will be at the same position as the leading point
  // (0,-120),, a zero degree arc segment.
  // At 25% (3 o'clock) it will be at the 9 o'clock position of the semicircle.
  // At 50% (6 o'clock) it will be at the other side of the semicircle (ie 180deg
  // or (0,120). At >50% it doesn't move from that position.
  // This is also made the trailing point of the gradient.
  var trailAngleRad = Math.min(Math.PI, (percent * Math.PI * 2)/100);
  var x1 = -Math.sin(trailAngleRad) * RADIUS;
  var y1 = -Math.cos(trailAngleRad) * RADIUS;

  // Update the path
  progress.setAttribute("d", "M 0,-120 A 120,120 0 0 0 " + x1 + "," + y1);
  // Update the gradient
  bluefade.x1.baseVal.value = x1;
  bluefade.y1.baseVal.value = y1;

  progress.setAttribute("transform", "rotate(" + rotateDeg + ")");
}


var start = null;

function step(timestamp) {
  if (!start) start = timestamp;
  var percent = ((timestamp - start)/50) % 100;
  setProgress(percent);
  window.requestAnimationFrame(step);
}

window.requestAnimationFrame(step);

body {
  background-color: #2f2f2f;
}

<svg width="300" height="300">
  <defs>
    <linearGradient id="bluefade"
                    gradientUnits="userSpaceOnUse"
                    x1="0" y1="120" x2="0" y2="-120">
      <stop offset="0.05" stop-color="#fff" stop-opacity="0"/>
      <stop offset="1" stop-color="#12b1db" stop-opacity="1"/>
    </linearGradient>
  </defs>

  <g transform="translate(150,150)">
    <path id="progress" d="M 0,-120 A 120,120 0 0 0 0,120"
          fill="none" stroke="url(#bluefade)" stroke-width="25"/>
  </g>
</svg>

09-25 17:10
查看更多