圆形加载animation

我正在尝试创buildApple的OS X圈子加载animation。

在这里输入图像说明

我到目前为止所尝试的:

.animation-wrapper { width: 200px; height: 200px; border: 1px solid black; border-radius: 50%; position: relative; overflow: hidden; filter: brightness(0.8); -webkit-filter: brightness(0.8); } .pie-piece1 { position: absolute; width: 50%; height: 50%; bottom: 0; left: 0; background: linear-gradient(to right, rgba(255, 0, 0, 1) 0%, rgba(255, 255, 0, 1) 100%); } .pie-piece2 { position: absolute; width: 50%; height: 50%; bottom: 0; right: 0; background: linear-gradient(to right, rgba(255, 255, 0, 1) 0%, rgba(0, 255, 0, 1) 100%); } .pie-piece3 { position: absolute; width: 50%; height: 50%; top: 0; left: 0; background: linear-gradient(to right, rgba(255, 0, 0, 1) 0%, rgba(255, 0, 255, 1) 100%); } .pie-piece4 { position: absolute; width: 50%; height: 50%; top: 0; right: 0; background: linear-gradient(to right, rgba(255, 0, 255, 1) 0%, rgba(0, 0, 255, 1) 100%); } .rotating-spinners { position: absolute; } .spike { fill: rgba(22, 22, 22, 0.5); } 
 <figure class="animation-wrapper"> <div class="pie-piece1"></div> <div class="pie-piece2"></div> <div class="pie-piece3"></div> <div class="pie-piece4"></div> <svg class="rotating-spinners" width="100%" height="100%" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <defs> <path id="spin-part" class="spike" d="M 65,-40 C 65,-40 80,20 50,50 60,40 50,-40 50,-40Z" /> </defs> <use x="0" y="0" xlink:href="#spin-part" /> <use x="0" y="0" xlink:href="#spin-part" transform="rotate(60, 50, 50)" /> <use x="0" y="0" xlink:href="#spin-part" transform="rotate(120, 50, 50)" /> <use x="0" y="0" xlink:href="#spin-part" transform="rotate(180, 50, 50)" /> <use x="0" y="0" xlink:href="#spin-part" transform="rotate(240, 50, 50)" /> <use x="0" y="0" xlink:href="#spin-part" transform="rotate(300, 50, 50)" /> </svg> </figure> 

线性渐变似乎没有正确排列,因为我找不到使渐变沿两个方向进行的方法。

有没有一种方法来创build这只使用CSS或SVG,而不像我所做的那样混合它们?

还是有其他解决scheme,我可以使用像canvas或某种图像魔术?

这是我的努力。 圆锥渐变是通过计算由OP发布的animationGIF中的每个像素的最大值提取的embedded式位图图像。 一个半不透明的黑色风车模式叠加在顶部和animation,模糊filter摆脱JPEG文物。

(编辑:添加了一个reflection亮点,使其看起来更多的3D)

 <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="121" height="121" viewBox="0 0 121 121"> <defs> <clipPath id="circ"> <circle r="60" cx="60.5" cy="60.5"/> </clipPath> <linearGradient id="shine" x1="0%" y1="0%" x2="0%" y2="100%"> <stop offset="0%" style="stop-color:#fff;stop-opacity:0.6" /> <stop offset="10%" style="stop-color:#fff;stop-opacity:0.3" /> <stop offset="20%" style="stop-color:#fff;stop-opacity:0.1" /> <stop offset="40%" style="stop-color:#fff;stop-opacity:0" /> </linearGradient> <filter id="blur"> <feGaussianBlur in="SourceGraphic" stdDeviation="2"/> </filter> </defs> <image width="121" height="121" filter="url(#blur)" xlink:href="data:image/jpeg;base64, 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 hIYYg5SFtM/cMbbeoFFHwc04MnGHKcXl/9k=" clip-path="url(#circ)" /> <g transform="translate(60.5,60.5)"> <path d="M0 0A56 56 0 0 0 0 56 56 56 0 0 0 32.916 45.305 56 56 0 0 1 0 0 56 56 0 0 0 53.259 17.305 56 56 0 0 0 53.259-17.305 56 56 0 0 1 0 0 56 56 0 0 0 32.916-45.305 56 56 0 0 0 0-56 56 56 0 0 1 0 0 56 56 0 0 0 -32.916-45.305 56 56 0 0 0-53.259-17.305 56 56 0 0 1 0 0 56 56 0 0 0 -53.259 17.305 56 56 0 0 0-32.916 45.305 56 56 0 0 1 0 0Z" stroke="none" fill="#000" opacity="0.25" transform="rotate(0)"> <animateTransform attributeName="transform" type="rotate" from="0" to="72" begin="0s" dur="0.6s" repeatCount="indefinite" /> </path> <circle r="59" stroke="#000" stroke-width="2" fill="none" opacity="0.25" /> <circle r="55" fill="url(#shine)" stroke="none" /> </g> </svg> 

这是我的SVG版本。 背景色轮不是很完美,但是我觉得我相当接近。

 <svg width="135" height="135" viewBox="0 0 200 200"> <defs> <filter id="blur" color-interpolation-filters="linear"> <feGaussianBlur in="SourceGraphic" stdDeviation="11"/> </filter> <mask id="mask"> <circle cx="0" cy="0" r="90" fill="white"/> </mask> <linearGradient id="gloss" x2="0" y2="0.4"> <stop offset="0" stop-color="white" stop-opacity="0.5"/> <stop offset="1" stop-color="white" stop-opacity="0"/> </linearGradient> </defs> <g transform="translate(100,100)" mask="url(#mask)"> <g filter="url(#blur)"> <polygon points="0,0, -100,-26.8, -100,26.8" fill="#c44"/> <polygon points="0,0, -100,-26.8, -100,26.8" fill="#c09" transform="rotate(30)"/> <polygon points="0,0, -100,-26.8, -100,26.8" fill="#c0c" transform="rotate(60)"/> <polygon points="0,0, -100,-26.8, -100,26.8" fill="#90c" transform="rotate(90)"/> <polygon points="0,0, -100,-26.8, -100,26.8" fill="#44c" transform="rotate(120)"/> <polygon points="0,0, -100,-26.8, -100,26.8" fill="#09c" transform="rotate(150)"/> <polygon points="0,0, -100,-26.8, -100,26.8" fill="#0cc" transform="rotate(180)"/> <polygon points="0,0, -100,-26.8, -100,26.8" fill="#0c9" transform="rotate(210)"/> <polygon points="0,0, -100,-26.8, -100,26.8" fill="#4c4" transform="rotate(240)"/> <polygon points="0,0, -100,-26.8, -100,26.8" fill="#9c0" transform="rotate(270)"/> <polygon points="0,0, -100,-26.8, -100,26.8" fill="#cc0" transform="rotate(300)"/> <polygon points="0,0, -100,-26.8, -100,26.8" fill="#c90" transform="rotate(330)"/> </g> <g transform="scale(0.9,0.9)"> <path d="M0,0C5,-61,-32,-86,-95,-90L-100,-46C-65,-53,-24,-35,0,0Z" fill="black" fill-opacity="0.4"/> <path d="M0,0C5,-61,-32,-86,-95,-90L-100,-46C-65,-53,-24,-35,0,0Z" fill="black" fill-opacity="0.4" transform="rotate(60)"/> <path d="M0,0C5,-61,-32,-86,-95,-90L-100,-46C-65,-53,-24,-35,0,0Z" fill="black" fill-opacity="0.4" transform="rotate(120)"/> <path d="M0,0C5,-61,-32,-86,-95,-90L-100,-46C-65,-53,-24,-35,0,0Z" fill="black" fill-opacity="0.4" transform="rotate(180)"/> <path d="M0,0C5,-61,-32,-86,-95,-90L-100,-46C-65,-53,-24,-35,0,0Z" fill="black" fill-opacity="0.4" transform="rotate(240)"/> <path d="M0,0C5,-61,-32,-86,-95,-90L-100,-46C-65,-53,-24,-35,0,0Z" fill="black" fill-opacity="0.4" transform="rotate(300)"/> <animateTransform attributeType="xml" attributeName="transform" type="rotate" from="0" to="360" dur="4s" repeatCount="indefinite"/> </g> <circle r="83" fill="url(#gloss)"/> <circle r="90" fill="none" stroke="black" stroke-width="2"/> </g> </svg> 

帆布方法

由于这是一个加载animation,其维度几乎可以通过零用户交互进行修复,所以Canvas也是一个不错的select,因为它不会为DOM添加额外的元素。 Canvas绘图命令与SVG非常相似, 浏览器的支持也不差。

一个缺点是Canvas没有自己的模糊滤镜(不像SVG)。 但是,这可以通过使用CSS模糊filter(具有非常低的浏览器支持)或在此堆栈溢出线程中提到的库克服。


背景渐变轮:

背景渐变轮是使用类似于我在这里回答中详细描述的方法创build的。 基本上我们可以在圆圈中find多个点,并画出不同颜色的笔划。 通过修改每一行的hue值,我们可以绘制渐变轮。

在下面的屏幕截图中,第一张图片显示了如果我们只绘制了24行(每行之间hue变化为15),背景将会如何显示,第二张是我们实际的梯度轮,总共有360行, hue每行增加1。

风扇:

风扇使用与您的SVG代码片段中使用的相同的方法创build。 path命令用于绘制每个辐条。 虽然在SVG中use标签来重复形状,但可以在“canvas”中使用循环。

SVG和Canvas之间的主要区别在于Canvas不能将转换原点作为rotate函数的参数,所以在应用旋转之前上下文必须被转换为中心点。

最后,由于默认形状是正方形(高度和宽度相同),因此必须将canvas裁剪成圆形。 下面的屏幕截图显示了风扇的未剪切和剪切版本。

这个风扇然后被放置在背景渐变轮的顶部。

3D效果:

顶部的3D效果通过在背景和风扇上添加具有较高透明度的小弧线来提供。

下面是没有任何animation的全画面的截图。

animation:

通过使用window.requestAnimationFrame方法添加animation,该方法以有规律的间隔调用作为parameter passing的函数。 这种方法通常会每秒调用大约60次(根据MDN)。 通过在每次迭代中递增countervariables的值并将其添加到风扇的辐条angular度,可以实现animation效果。

 window.onload = function() { var canvas = document.querySelector("#canvas"), ctx = canvas.getContext("2d"), counter = 360; function fan() { ctx.clearRect(0, 0, 100, 100); for (var i = 0; i < 360; i++) { ctx.strokeStyle = "hsl(" + (180 - i) + ", 60%, 50%)"; ctx.beginPath(); ctx.moveTo(50, 50); x = 50 + 50 * Math.cos((i / 360) * Math.PI * 2); y = 50 + 50 * Math.sin((i / 360) * Math.PI * 2) ctx.lineTo(x, y); ctx.lineWidth = 2; ctx.stroke(); } counter++; for (var j = 0; j < 6; j++) { ctx.save(); ctx.beginPath(); ctx.arc(50, 50, 50, 0, Math.PI * 2, true); ctx.clip(); ctx.translate(50, 50); ctx.rotate(((60 * j) + counter) * Math.PI / 180); ctx.beginPath(); ctx.moveTo(0, 0); ctx.bezierCurveTo(0, 0, 30, 50, 100, 0); x = 75 * Math.cos((-20 / 360) * Math.PI * 2); y = 75 * Math.sin((-20 / 360) * Math.PI * 2) ctx.lineTo(x, y); ctx.bezierCurveTo(x, y, (x - 30), (y + 40), 0, 0); ctx.closePath(); ctx.fillStyle = "rgba(0,0,0,0.5)"; ctx.fill(); ctx.restore(); } ctx.save(); ctx.beginPath(); ctx.arc(50, 50, 50, 0, Math.PI, true); ctx.arc(50, 55, 50, Math.PI, 0, false); ctx.fillStyle = "rgba(0,0,0,0.15)"; ctx.closePath(); ctx.fill(); ctx.restore(); window.requestAnimationFrame(fan); } fan(); } 
 <canvas width='100px' height='100px' id='canvas'></canvas> 

我不得不这样做与SVG和CSS渐变的混合,我知道是违背了要求,但是我知道。 我使用了一些原始代码,主要是螺旋桨形状的SVG部分。

径向渐变使用12个元素。

 .wheel, .umbrella, .color { content: ""; position: absolute; border-radius: 50%; width: 15em; height: 15em; margin: 0; padding: 0; } .wheel { overflow: hidden; width: 15em; height: 15em; position: relative; } .umbrella { position: relative; -webkit-transform: scale(1.35); } .color, .color:nth-child(n+7):after { clip: rect(0, 15em, 15em, 7.5em); } .color:after, .color:nth-child(n+7) { content: ""; position: absolute; border-radius: 50%; left: calc(50% - 7.5em); top: calc(50% - 7.5em); width: 15em; height: 15em; clip: rect(0, 7.5em, 15em, 0); } .color:nth-child(1):after { background-color: #9ED110; transform: rotate(30deg); z-index: 12; } .color:nth-child(2):after { background-color: #50B517; transform: rotate(60deg); z-index: 11; } .color:nth-child(3):after { background-color: #179067; transform: rotate(90deg); z-index: 10; } .color:nth-child(4):after { background-color: #476EAF; transform: rotate(120deg); z-index: 9; } .color:nth-child(5):after { background-color: #9f49ac; transform: rotate(150deg); z-index: 8; } .color:nth-child(6):after { background-color: #CC42A2; transform: rotate(180deg); z-index: 7; } .color:nth-child(7):after { background-color: #FF3BA7; transform: rotate(180deg); } .color:nth-child(8):after { background-color: #FF5800; transform: rotate(210deg); } .color:nth-child(9):after { background-color: #FF8100; transform: rotate(240deg); } .color:nth-child(10):after { background-color: #FEAC00; transform: rotate(270deg); } .color:nth-child(11):after { background-color: #FFCC00; transform: rotate(300deg); } .color:nth-child(12):after { background-color: #EDE604; transform: rotate(330deg); } 
 <div class="wheel"> <ul class="umbrella"> <li class="color"></li> <li class="color"></li> <li class="color"></li> <li class="color"></li> <li class="color"></li> <li class="color"></li> <li class="color"></li> <li class="color"></li> <li class="color"></li> <li class="color"></li> <li class="color"></li> <li class="color"></li> </ul> </div>