Крутящееся колесо SVG

244
25 марта 2018, 23:18

Необходимо сделать крутящийся круг из секторов.

В каждом секторе, а так же в центре показывается свой фон.

Есть два варианта, устроит любой:

  1. Количество секторов задаётся константой в JavaScript, которую можно настроить (посложнее, но более интересно).
  2. Решение с фиксированным количеством секторов.

Необходимо сделать решение не только технически верное, но и что бы смотрелось красиво.

Что бы не было мыслей что я на халяву хочу получить готовую работу, поясняю, что это задача для освоения технологий, которые мы делаем в SVG чате.

Answer 1

Смотреть желательно раскрыв на всю страницу.

Расчёт секторов делается через JavaScript.

/* картинки для анимации  */ 
var images = ["https://i.stack.imgur.com/SaKBd.jpg", "https://i.stack.imgur.com/cyQar.jpg", "https://i.stack.imgur.com/gzQrR.jpg", "https://i.stack.imgur.com/cyQar.jpg", "https://i.stack.imgur.com/1KW4v.jpg"]; 
 
var svg = document.getElementById("svg"); 
var all = document.getElementById("all"); 
var svgNS = "http://www.w3.org/2000/svg"; 
 
/* шаблон анимации поворота */ 
var anima = `<animateTransform id="at" 
    attributeName="transform" 
    begin="0s" 
    dur="20s" 
    type="rotate" 
    from="0" 
    to="360" 
    repeatCount="indefinite" 
        />`; 
 
/* шаблон картинки из которой будет обрезаться сектор */ 
var image = `<image xlink:href="[path]" clip-path="url(#cp[number])" x="-100" y="-100" width="100%" height="100%" preserveAspectRatio="xMinYMin slice"></image>`; 
 
/* делаем все сектора, количество секторов равно количеству картинок */ 
MakeAllArks(40, 100, images.length); 
 
/* функция расчёта всех секторов */ 
function MakeAllArks(dis1, dis2, number) { 
  var angle = (2 * Math.PI) / number; 
  for (var i = 0; i < number; i++) { 
    MakeArc(dis1, dis2, i * angle, angle, i); 
  } 
} 
 
/* функция расчёта сектора */ 
function MakeArc(dis1, dis2, angleStart, angle, number) { 
  var sumAngle = angleStart + angle; 
 
  /* далаем расчёт основных точек сектора на основе функции поворота */ 
  var point1 = RotateVector({ 
    x: 0, 
    y: dis1 
  }, angleStart); 
  var point2 = RotateVector({ 
    x: 0, 
    y: dis2 
  }, angleStart); 
  var point3 = RotateVector({ 
    x: 0, 
    y: dis2 
  }, sumAngle); 
  var point4 = RotateVector({ 
    x: 0, 
    y: dis1 
  }, sumAngle); 
 
  /* создаём элемент пути */ 
  var path = document.createElementNS(svgNS, "path"); 
 
  /* путь сектора на основе расчёта точек */ 
  var d = `M ${point1.x} ${point1.y} L ${point2.x} ${point2.y} A ${dis2} ${dis2} 0 0 1 ${point3.x} ${point3.y} L ${point4.x} ${point4.y} A ${dis1} ${dis1} 0 0 0 ${point1.x} ${point1.y}`; 
 
  path.setAttribute("d", d); 
 
  /* добавляем анимацию поворота */ 
  path.innerHTML = anima; 
 
  /* создаём вырезку с путём */ 
  var clipPath = document.createElementNS(svgNS, "clipPath"); 
  clipPath.setAttribute("id", "cp" + number); 
  clipPath.appendChild(path); 
 
  /* добавляем вырезку на холст */ 
  all.appendChild(clipPath); 
 
  /* создаём картинку которая будет показана по вырезке на основе шаблона */ 
  var group = document.createElementNS(svgNS, "g"); 
  group.innerHTML = image.replace("[path]", images[number]).replace("[number]", number); 
 
  /* добавляем картинку на холст */ 
  svg.appendChild(group); 
} 
 
/* функция поворота вектора с помощью матрицы поворота */ 
function RotateVector(vector, angle) { 
  var cosa = Math.cos(angle); 
  var sina = Math.sin(angle); 
  var rez = { 
    x: vector.x * cosa - vector.y * sina, 
    y: vector.x * sina + vector.y * cosa 
  }; 
  return rez; 
}
<svg id="svg" style="width:500px; height:500px" viewBox="-104 -104 208 208" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 
  <defs> 
    <pattern id="pat1" height="100%" width="100%" viewBox="0 0 100 100"> 
      <image xlink:href="https://i.stack.imgur.com/otCrT.jpg" x="0" y="0" width="100" height="100" preserveAspectRatio="xMinYMin slice"/> 
    </pattern> 
    <g id="all"></g> 
  </defs> 
  <circle cx="0" cy="0" r="40" fill="url(#pat1)"/> 
</svg> 
 
<!-- что бы StackOverflow не удалил эти картинки  --> 
<img src="https://i.stack.imgur.com/SaKBd.jpg" width="0"> 
<img src="https://i.stack.imgur.com/cyQar.jpg" width="0"> 
<img src="https://i.stack.imgur.com/gzQrR.jpg" width="0"> 
<img src="https://i.stack.imgur.com/cyQar.jpg" width="0"> 
<img src="https://i.stack.imgur.com/1KW4v.jpg" width="0">

Answer 2

Анимация вращения колеса со смещением фонов секторов:

path, 
circle { 
  stroke: black; 
} 
 
.p1 { 
  fill: #d3dd00; 
} 
 
.p2 { 
  fill: #d30000; 
} 
 
.p3 { 
  fill: #682db4; 
} 
 
.p4 { 
  fill: #60dd00; 
} 
 
.p5 { 
  fill: #c9145e; 
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="500" height="500"> 
  <g> 
    <path class="path p1" d="m167.64407 188.9322 7.98305 107.77119C223.6166 289.30677 269.2895 272.64387 298.0339 188.26695L192.25847 162.98729c-2.04033 11.777-7.16015 19.43869-24.6144 25.94491z"/> 
    <path class="path p2" d="m130.38983 169.63983-95.131355 49.22881c33.190286 58.58315 80.570885 83.10953 140.368645 77.83475L167.64407 188.9322c-14.2749 0.62194-27.86502-1.35712-37.25424-19.29237z"/> 
    <path class="path p3" d="m242.8178 41.245763c-0.66526 2.661017-61.24117 91.177607-61.24117 91.177607 8.28324 9.10114 13.63439 18.95888 10.68184 30.56392L298.0339 188.26695C305.49036 137.70818 297.69487 88.064523 242.8178 41.245763Z"/> 
    <path class="path p4" d="m242.8178 41.245763-61.24117 91.177607c-12.1511-7.53907-24.70121-10.29013-38.10287-2.82244L78.08736 42.105458C127.00653 12.408637 180.14831 3.4410112 242.8178 41.245763Z"/> 
    <path class="path p5" d="M143.47376 129.60093 78.08736 42.105458C12.358445 101.72182 8.4036304 160.50341 35.258475 218.86864l95.131355-49.22881c-4.64922-21.60596 2.82031-32.10305 13.08393-40.0389z"/> 
    <circle cx="160" cy="155" r="35" fill="orange"/> 
    <animateTransform attributeName="transform" type="rotate" values="0 161 155;360 160 155" dur="10s" repeatCount="indefinite"/> 
  </g>	 
</svg>

P.S. Вышло не слишком ровным, если присмотреться:)

READ ALSO
Проблема с дополенеием Cannot set property &#39;onclick&#39; of null

Проблема с дополенеием Cannot set property 'onclick' of null

Разрабатываю расширения для Chrome (Opera and Yandex)Появилась ошибка в консоли "popup

218
Как перенести проект с create-react-app в gatsby.js

Как перенести проект с create-react-app в gatsby.js

Привет!Нужно перенести проект созданный на react-create-app в Gatsbyjs но там разная структура файлов и нету файла сss

225
При обращении к массиву внутри $rootScope выдает undefined

При обращении к массиву внутри $rootScope выдает undefined

В контроллере из $rootScope хочу достать данные пользователяОчень странные вещи происходят

227
Элементы массива в строку

Элементы массива в строку

Есть массив, вывожу из него только нужные мне значения следующим кодом:

182