Круговая загрузка анимации
Я пытаюсь создать анимацию загрузки круга Apple OS X.
То, что я пробовал до сих пор:
.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>
Линейные градиенты не кажутся правильными, так как я не мог найти способ сделать градиенты в двух направлениях.
Есть ли способ создать это, используя только CSS или SVG, не смешивая их, как я сделал?
Или есть ли другие решения, которые я могу использовать, например, в виде холста или какой-либо магии изображения?
Вот мои усилия. Конический градиент представляет собой встроенное растровое изображение, извлеченное путем вычисления максимального значения каждого пикселя в анимированном GIF, размещенном OP. Полупрозрачный черный шаблон ветряной мельницы накладывается поверх этого и анимируется, а фильтр размытия избавляется от артефактов JPEG.
(Edit: добавлена подсветка, чтобы она выглядела немного больше 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>
Связанные вопросы
Похожие вопросы
Подход к холсту
Так как это анимация загрузки, где размеры, вероятно, будут исправлены с почти нулевыми пользовательскими взаимодействиями, Canvas также будет хорошим вариантом, потому что он не добавляет никаких дополнительных элементов в DOM, Команды рисования холста довольно похожи на SVG, а поддержка браузера не хуже.
Одним из недостатков было бы то, что Canvas не имеет собственного фильтра размытия (в отличие от SVG). Но это можно преодолеть либо с помощью фильтра размытия CSS (с очень низкой поддержкой браузера), либо с библиотек, упомянутых в этом потоке.
Фоновое градиентное колесо:
Фоновое градиентное колесо создается с использованием подхода, аналогичного описанному в моем ответе здесь. В основном мы находим несколько точек в круге и рисуем линии, каждая из которых имеет разный цветной ход. Изменив значение hue
для каждой строки, мы можем нарисовать градиентное колесо.
На следующем снимке экрана первое изображение показывает, как выглядел бы фон, если бы мы нарисовали всего 24 строки (с изменением hue
15 между каждой строкой), а второе - наше фактическое градиентное колесо, которое имеет 360 линий в общей сложности при hue
увеличивается на 1 для каждой строки.
Fan:
Вентилятор создается с использованием того же подхода, который используется в вашем фрагменте SVG. Путь команд используется для рисования каждой спицы. Хотя тег use
используется в SVG для повторения фигуры, петли могут использоваться в Canvas.
Основное различие между SVG и Canvas заключается в том, что Canvas не может принимать начало преобразования в качестве параметра для функции rotate
, поэтому контекст должен быть переведен в центральную точку перед применением поворота.
Наконец, холст должен быть обрезан в круг, потому что форма по умолчанию - это квадрат (так как высота и ширина одинаковы). На приведенном ниже снимке показаны незашифрованные и обрезанные версии вентилятора.
Этот вентилятор затем помещается поверх фонового градиента.
3D-эффект:
3D-эффект сверху обеспечивается добавлением небольшой дуги с большей прозрачностью над фоном и вентилятором.
Ниже приведен скриншот полной картинки без анимации.
Анимация:
Анимация добавляется с помощью метода window.requestAnimationFrame
, который вызывает функцию, переданную как аргумент через равные промежутки времени. Этот метод обычно вызывается функцией около 60 раз в секунду (согласно MDN). Увеличивая значение переменной counter
во время каждой итерации и добавляя ее к углу спиц вентилятора, эффект анимации может быть достигнут.
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
Такой же подход, как описано выше, можно использовать и с SVG. Единственным недостатком будет отсутствие. дополнительных элементов, которые добавляются в DOM как для фона, так и для вентилятора.
window.onload = function() {
var colorWheel = document.querySelector("#color-wheel");
for (var i = 0; i < 360; i++) {
lineColor = "hsl(" + (180 - i) + ", 60%, 50%)";
x = 50 + 50 * Math.cos((i / 360) * Math.PI * 2);
y = 50 + 50 * Math.sin((i / 360) * Math.PI * 2);
line = document.createElementNS("http://www.w3.org/2000/svg", "line");
line.setAttribute('x1', 50);
line.setAttribute('y1', 50);
line.setAttribute('x2', x);
line.setAttribute('y2', y);
line.setAttribute('stroke', lineColor);
line.setAttribute('stroke-width', 2);
colorWheel.appendChild(line);
}
}
<svg class="rotating-spinners" width="100px" height="100px" 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 50,50 c0,0 30,50 100,0 l-5,-35 c0,0 -30,50 -95,35Z" />
<clipPath id="shape">
<circle r="50" cx="50" cy="50" />
</clipPath>
<clipPath id="shade">
<path d='M-5,55 a55,55 1 0,1 110,0 h-5 a50,50 1 0,0 -100,0' />
</clipPath>
</defs>
<g id='color-wheel' clip-path='url(#shape)'>
</g>
<g id='fan' fill-opacity="0.5" clip-path='url(#shape)'>
<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)" />
<animateTransform attributeType="xml" attributeName="transform" type="rotate" from="0,50,50" to="360,50,50" dur="6s" repeatCount="indefinite" />
</g>
<circle r='50' cx='50' cy='50' fill-opacity='0.15' clip-path='url(#shade)' />
</svg>
Смешанный подход
Или, если у вас нет проблем с дополнительными элементами для вентилятора, но просто хотите избежать элементов 360 line
, которые будут добавлены, вы можете использовать смесь Canvas (для фона) и SVG для поклонников как в приведенном ниже фрагменте.
window.onload = function() {
var canvas = document.querySelector("#canvas");
var ctx = canvas.getContext("2d");
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();
}
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();
}
div {
position: relative;
height: 100px;
width: 100px;
}
canvas,
svg {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='container'>
<canvas width='100px' height='100px' id='canvas'></canvas>
<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 50,50 c0,0 30,50 100,0 l-5,-35 c0,0 -30,50 -95,35Z" />
<clipPath id="shape">
<circle r="50" cx="50" cy="50" />
</clipPath>
</defs>
<g id='fan' fill-opacity="0.5" clip-path="url(#shape)">
<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)" />
<animateTransform attributeType="xml" attributeName="transform" type="rotate" from="0,50,50" to="360,50,50" dur="6s" repeatCount="indefinite" />
</g>
</svg>
</div>
Мне пришлось сделать это со смесью градиентов SVG и CSS, которые, как я знаю, относятся к запросу, но это то, что я знаю. Я использовал часть вашего исходного кода, в основном части SVG для форм пропеллера.
Радиальный градиент выполняется с использованием элементов 12 li
.
.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>
Эти 12 элементов затем могут быть размыты вместе, чтобы сформировать гладкий градиент.
Затем я анимировал части спина, чтобы сделать эффект, который вам нужен.
var rotation = 0;
$(document).ready(function() {
setInterval(function() {
rotation += 1;
$('.wheel svg').css({
'transform': 'rotate(' + rotation + 'deg)'
});;
}, 10);
});
.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;
filter: blur(.75em);
-webkit-filter: blur(.75em);
-moz-filter: blur(.75em);
-o-filter: blur(.75em);
-ms-filter: blur(.75em);
filter: url(#blur);
filter: progid: DXImageTransform.Microsoft.Blur(PixelRadius='.75');
-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);
}
body {
padding: 5px;
}
.wheel svg {
position: absolute;
top: 0;
opacity: .5;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<figure class="animation-wrapper 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>
<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>
Вот чистое решение CSS, в котором я рассмотрю использование только одного элемента. Я буду полагаться на форму, которую я создал в этом предыдущем ответе, а выше я рассмотрю conic-gradient()
.
На самом деле conic-gradient()
поддерживается только в Chrome и Safari, но у нас скоро будет лучшая поддержка:
.box {
--R:50px; /*Radius*/
--c1:grey; /*first color*/
--c2:#fff; /*second color*/
--g1:var(--c1) 98%, transparent 100%;
--g2:var(--c2) 98%, transparent 100%;
width:calc(2*var(--R));
height:calc(2*var(--R));
border-radius:100%;
border:1px solid;
position:relative;
overflow:hidden;
display:inline-block;
background:conic-gradient(rgba(128, 0, 128,0.7), rgba(0, 0, 255,0.7),rgba(0, 128, 0,0.7),rgba(255, 255, 0,0.7), rgba(255, 0, 0,0.7), rgba(128, 0, 128,0.7));
box-shadow:0 3px 5px inset rgba(0,0,0,0.5);
}
.box::before,
.box::after{
content:"";
position:absolute;
z-index:-1;
top:0;
bottom:0;
left:0;
width:50%;
background:
/*we rotate by 30deg so will use :
sin(30deg)*R = 0.5xR
cos(30deg)*R = 0.866xR
*/
radial-gradient(circle var(--R) at calc(var(--R) + 0.866*var(--R)) calc(var(--R) - 0.5*var(--R)) ,var(--g1)),
radial-gradient(circle var(--R) at calc(var(--R) + 0.5*var(--R)) calc(var(--R) - 0.866*var(--R)),var(--g2)),
radial-gradient(circle var(--R) at var(--R) 0 ,var(--g1)),
radial-gradient(circle var(--R) at calc(var(--R) - 0.5*var(--R)) calc(var(--R) - 0.866*var(--R)),var(--g2)),
radial-gradient(circle var(--R) at calc(var(--R) - 0.866*var(--R)) calc(var(--R) - 0.5*var(--R)) ,var(--g1)),
radial-gradient(circle var(--R) at 0 var(--R) ,var(--g2)),
radial-gradient(circle var(--R) at calc(var(--R) - 0.866*var(--R)) calc(var(--R) + 0.5*var(--R)) ,var(--g1));
transform-origin:right;
animation:animate 3s linear infinite;
}
/*the same shape rotated*/
.box::after {
animation-delay:-1.5s;
}
@keyframes animate {
to {
transform:rotate(-360deg);
}
}
<div class="box"></div>
Выход
Здесь в другом направлении (как ваша анимация)
.box {
--R:50px; /*Radius*/
--c1:grey; /*first color*/
--c2:#fff; /*second color*/
--g1:var(--c1) 98%, transparent 100%;
--g2:var(--c2) 98%, transparent 100%;
width:calc(2*var(--R));
height:calc(2*var(--R));
border-radius:100%;
border:1px solid;
position:relative;
overflow:hidden;
display:inline-block;
background:conic-gradient(rgba(128, 0, 128,0.7), rgba(0, 0, 255,0.7),rgba(0, 128, 0,0.7),rgba(255, 255, 0,0.7), rgba(255, 0, 0,0.7), rgba(128, 0, 128,0.7));
box-shadow:0 3px 5px inset rgba(0,0,0,0.5);
}
.box::before,
.box::after{
content:"";
position:absolute;
z-index:-1;
top:0;
bottom:0;
left:0;
width:50%;
background:
/*we rotate by 30deg so will use :
sin(30deg)*R = 0.5xR
cos(30deg)*R = 0.866xR
*/
radial-gradient(circle var(--R) at calc(var(--R) + 0.866*var(--R)) calc(var(--R) - 0.5*var(--R)) ,var(--g1)),
radial-gradient(circle var(--R) at calc(var(--R) + 0.5*var(--R)) calc(var(--R) - 0.866*var(--R)),var(--g2)),
radial-gradient(circle var(--R) at var(--R) 0 ,var(--g1)),
radial-gradient(circle var(--R) at calc(var(--R) - 0.5*var(--R)) calc(var(--R) - 0.866*var(--R)),var(--g2)),
radial-gradient(circle var(--R) at calc(var(--R) - 0.866*var(--R)) calc(var(--R) - 0.5*var(--R)) ,var(--g1)),
radial-gradient(circle var(--R) at 0 var(--R) ,var(--g2)),
radial-gradient(circle var(--R) at calc(var(--R) - 0.866*var(--R)) calc(var(--R) + 0.5*var(--R)) ,var(--g1));
transform-origin:right;
animation:animate 3s linear infinite;
}
/*the same shape rotated*/
.box::after {
animation-delay:-1.5s;
}
@keyframes animate {
from {
transform:scale(-1,1) rotate(0deg);
}
to {
transform:scale(-1,1) rotate(-360deg);
}
}
<div class="box"></div>
Выход
Посмотрите другие вопросы по меткам html css css3 css-shapes svg или Задайте вопрос