我试图创建跟随其他事物旋转的圆形动画...我很难创建渐变圆形动画: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>