компилируется...
Перейти к основному содержанию
Рекомендовать во Вконтакте Рекомендовать в Фейсбуке Рекомендовать в Твиттере

Круговая и кольцевая svg диаграммы на HTML5 с нуля

"Кухня" веб-разработчика отчасти похожа на домашнюю кухню. Разработчик имеет доступ к разнообразию библиотек из готового кода, которые помогут ему сделать веб-приложение практически так же, как повар дома может использовать полуфабрикаты, чтобы приготовить свое блюдо более эффективно. В обоих случаях качество предварительно подготовленных вещей должно быть очень важно. Однако, иногда качество приносится в жертву удобству. Не поймите меня неправильно, удобство - не всегда плохо. Оно может быть полезно, когда плюсы и минусы известны и хорошо проанализированы. Анализируя варианты для круговых и кольцевых диаграмм в HTML, мы можем выделить лишь несколько: 

  1. Диаграмма, основанная на элементе Canvas, сгенерированная на клиенте (т.е. JavaScript) 
  2. Диаграмма, основанная на SVG и сгенерированная на клиенте (т.е. JavaScript) 
  3. Диаграмма, основанная на SVG и сгенерированная на сервере

Готовые библиотеки с использованием Canvas и SVG JavaScript

JavaScript-библиотеки для отрисовки диаграмм часто более удобные и загруженные кучей классных опций типа интерактивности. Вот несколько библиотек:

  1. D3.js
  2. Chartist.js
  3. Google Charts

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

Так зачем заморачиваться и писать код для них своими руками? Это отличный вопрос, который я также задал себе. В конце концов, я убедился в трех вещах:

  1. Большинство JavaScript-библиотек являются труднодоступными, особенно те, что основаны на элементе Canvas (за исключением Google Charts)
  2. Если информация в диаграмме очень важна (как это было в моей ситуации), должны ли мы рассчитывать на скрипт, выполняющийся на клиенте, чтобы генерировать информацию? Я так не думаю.
  3. Если я копну SVG-код глубже и запачкаю руки, я могу узнать немного больше про ту лежащую в его основе магическую чепуху. Другими словами, процесс обучения может оказаться веселым и стоящим моих усилий.

Моя ситуация

Моей команде нужен был простой компонент, который мог быть собран на сервере и отображать простую информацию об использовании аккаунтов. Кроме того, нашим предпочтением была легкость этого компонента (избежание JavaScript, если возможно); он не должен был быть чрезмерно мудреным или интерактивным, от него нужно было только отображение важных данных.

Дополнительная заметка о диаграммах, основанных на элементе Canvas

Вы могли заметить (если знакомы с созданием диаграмм для веба), что я не включил Chart.js в список рекомендованных библиотек выше. Хотя вы определенно можете ее использовать, стоит иметь в виду, что Chart.js использует элемент Canvas для отрисовки его диаграмм, и содержание элемента не является частью DOM. Следовательно, они недоступны для программ чтения с экрана. Это значит, что вам придется принять дополнительные меры, чтобы убедиться в доступности ваших данных.

Введение в CSS и SVG диаграммы

CSS- и SVG-диаграммы по своей сути более доступные и семантические, чем остальные технологии. Но они могут быть сложными, и, возможно, занимающими больше времени, если писать их код вручную.

CSS-ниндзя Леа Вероу предлагает несколько вариантов создания круговых диаграмм с нуля в ее статье "Designing Flexible, Maintainable Pie Charts With CSS and SVG" ("Разрабатываем гибкие, поддерживаемые круговые диаграммы с помощью CSS и SVG"). Ее методы могут быть применимы и для кольцевых диаграмм.

Робин Рэндл также написал о создании диаграмм чисто с помощью CSS, где он тоже указывает на свои провалы в подходе.

Необъяснимое

Я немного погуглил про SVG и кольцевые диаграммы и столкнулся со статьями Леа Вероу и Робина Рэндла (они упомянуты выше) в дополнении к еще нескольким. Почти во всех из них обсуждалось использование атрибутов stroke-dasharray и stroke-dashoffset в SVG для расположения частей диаграммы. Эти свойства идентичны "stroke" при создании векторов в программах типа Adobe Illustrator.

В некоторых из этих статьей даже обсуждалась анимация в SVG, что есть круто, но это также не то, что я искал.

После моего исследования я смог понять, что использование <circle> из SVG вместе с stroke и stroke-dasharray могло обеспечить мне те сегменты вложенной круговой диаграммы, что были мне нужны. Я также понял, что stroke-dashoffset позволит мне сделать "анимацию", или, другими словами, расположить сегмент в том месте круга, где я хотел.

Однако, кажется, я не нашел никакого четкого объяснения тому, как именно работали stroke dash атрибуты и какое они имели отношение к окружности круга. А что было более недостижимым, так это прикрепление нескольких элементов (один за другим) вокруг круга. Еще лучше, какова же формула получения этих относительных позиций с использованием уникальных/динамических размеров сегментов и stroke-атрибутов SVG?

Итак, я стал полон решимости выяснить это для себя. 

Примечание: Если вы нашли какие-либо ресурсы, объясняющие эти концепты, пожалуйста, поделитесь.

Как сделать SVG-диаграмму своими руками

Объяснение stroke-dasharray и stroke-dashoffset  

Давайте начнем с простой SVG-"кольцевой диаграммы".7e626ca7d8b8f18c6f30073d5a6f.png


<svg width="100%" height="100%" viewBox="0 0 42 42" class="donut">
  <circle class="donut-hole" cx="21" cy="21" r="15.91549430918954" fill="#fff"></circle>
  <circle class="donut-ring" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#d2d3d4" stroke-width="3"></circle>
  <circle class="donut-segment" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#ce4b99" stroke-width="3"></circle>
</svg>

Вы заметите пару вещей:

  1. Радиус (атрибут "r") выглядит абсурдно! Почему? Я хотел сделать размеры моих сегментов логичными, доступными для понимания и читабельными. Для того, чтобы достичь этого, я решил основать все на 100% (или на окружности, равной 100). SVG-фигуры масштабируемы, так что не очень важно, насколько большими они в конце концов окажутся; по крайней мере, математика здесь будет проста. Заходим дальше в ту область, что я помню из математики старшей школы: я знаю, что радиус окружности равен r = C/(2π) или r = 100/(2π). Результат равен 15.91549430918952. Безумное число с кучей цифр, да, знаю, но позже оно облегчит нам всем жизни.
  2. Для viewBox заданы значения "0 0 42 42". Они должны быть удвоенными cx & cy (center x и center y) значениями <circle> и быть чуть больше, чем диаметр кругов (включая ширину контура).
  3. Там есть <circle> с классом "donut-hole". Вот что гарантированно делает центр белым. Если вам это не важно (в случае с простой круговой диаграммой), тогда этот пункт можно убрать.
  4. Также там есть <circle> с классом "donut-ring". Он служит в качестве светло-серого фона в случае, если секторы не заполняют 100% окружности.

Итак, нам необходимо скорректировать размер сектора до желаемого процента. Давайте используем 85%:

0165134e2b1b9d219d395614daad.png

<svg width="100%" height="100%" viewBox="0 0 42 42" class="donut">
  <circle class="donut-hole" cx="21" cy="21" r="15.91549430918954" fill="#fff"></circle>
  <circle class="donut-ring" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#d2d3d4" stroke-width="3"></circle>
  <circle class="donut-segment" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#ce4b99" stroke-width="3" stroke-dasharray="85 15" stroke-dashoffset="0"></circle>
</svg>

Сектора созданы с помощью использования SVG stroke-атрибута, называемого stroke-dasharray. Значение, которое мы задали в примере выше, равняется "85 15".

Если мы будем думать о диаграмме, как о круговой, то из наличия 85%-го сектора можно судить об остатке в 15%. Эти два значения - это массив, разграниченный пробелом. Вот что происходит: создаётся черта в 85 единиц, затем пробел в 15 единиц, затем черта в 85, пробел в 15 и так далее и тому подобное. Но поскольку мы используем круг, и общее значение равняется 100, все повторяется снова. Если мы не сделали второе значение в массиве таким, что оно дополняет первое число до ста, то мы получим третью черту (или часть) или больше. Например, вот stroke-dasharray от "10 10":

25681615de31e334b1187d3f509d.png

Так, на фигуре 2 и фигуре 3 вы можете заметить, что stroke-dasharray не начинается на самом верху (на 12:00). Вместо этого, на самом деле оно начинается на правой стороне (3:00), и движется по часовой стрелке по кругу. 

Если мы хотим расположиться (или начать) сверху, то мы должны использовать stroke-dashoffset. Однако в отличие от stroke-dasharray, stroke-dashoffset двигается против часовой стрелки. Итак, нам необходимо будет задать значение "25" (на 25% в другую сторону от 3:00, назад к 12:00). Помните, что это - не отрицательное число, потому что offset движется против стрелки. 

1a5b66bd2e4abeeacac8c88b258a.png

<svg width="100%" height="100%" viewBox="0 0 42 42" class="donut">
  <circle class="donut-hole" cx="21" cy="21" r="15.91549430918954" fill="#fff"></circle>
  <circle class="donut-ring" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#d2d3d4" stroke-width="3"></circle>
  <circle class="donut-segment" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#ce4b99" stroke-width="3" stroke-dasharray="85 15" stroke-dashoffset="25"></circle>
</svg>

Как расположить сектора кольцевой диаграммы вокруг SVG

Теперь нам нужно добавить дополнительные сектора вокруг круга. Давайте используем сектор, занимающий 15% от окружности. Оставшийся процент для stroke-dasharray будет равен 85%, независимо от любых других секторов. Следовательно, код будет выглядеть так: 

<svg width="100%" height="100%" viewBox="0 0 42 42" class="donut">
  <circle class="donut-hole" cx="21" cy="21" r="15.91549430918954" fill="#fff"></circle>
  <circle class="donut-ring" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#d2d3d4" stroke-width="3"></circle>
  <circle class="donut-segment" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#ce4b99" stroke-width="3" stroke-dasharray="85 15" stroke-dashoffset="25"></circle>
  <circle class="donut-segment" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#b1c94e" stroke-width="3" stroke-dasharray="15 85" stroke-dashoffset="25"></circle>
</svg>

Мы оставили stroke-dashoffset на значении 25, поэтому зеленый сектор начинается сверху и идет по часовой стрелке, перекрывая первый сектор (розовый).

93be825cc95a56167a589751492a.png

Очевидно, это не совсем то, чего мы хотели. Мы хотим, чтобы пятнадцатый процент (зеленый цвет) впритык вписывался в пространство, оставленное восемьдесят пятым процентом (розовый). Мы можем корректировать stroke-dashoffset, пока не повезет, но это было бы не так просто, имей мы еще два сектора. Вместо этого нам нужна формула:

Окружность - общая длина всех предыдущих секторов + смещение первого сектора = смещение текущего сектора

Подключая наши числа, мы получаем:

100 − 85 + 25 = 40
<svg width="100%" height="100%" viewBox="0 0 42 42" class="donut">
  <circle class="donut-hole" cx="21" cy="21" r="15.91549430918954" fill="#fff"></circle>
  <circle class="donut-ring" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#d2d3d4" stroke-width="3"></circle>
  <circle class="donut-segment" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#ce4b99" stroke-width="3" stroke-dasharray="85 15" stroke-dashoffset="25"></circle>
  <circle class="donut-segment" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#b1c94e" stroke-width="3" stroke-dasharray="15 85" stroke-dashoffset="40"></circle>
</svg>

64ce88ecd71fb8318dc50d3ef82b.png

Добавляем больше секторов нашей диаграмме!

Эта же самая формула работает для добавления дополнительных секторов. Давайте заполним диаграмму 40, 30, 20 процентами, и оставшиеся 10 не будут использованы.
 
Код:

<svg width="100%" height="100%" viewBox="0 0 42 42" class="donut">
  <circle class="donut-hole" cx="21" cy="21" r="15.91549430918954" fill="#fff"></circle>
  <circle class="donut-ring" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#d2d3d4" stroke-width="3"></circle>
  <circle class="donut-segment" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#ce4b99" stroke-width="3" stroke-dasharray="40 60" stroke-dashoffset="25"></circle>
  <circle class="donut-segment" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#b1c94e" stroke-width="3" stroke-dasharray="20 80" stroke-dashoffset="85"></circle>
  <circle class="donut-segment" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#377bbc" stroke-width="3" stroke-dasharray="30 70" stroke-dashoffset="65"></circle>
  <!-- unused 10% -->
</svg>

Результат:

76bb4e9ec9834b732ac0ee4dd0c1.png

Добавляем текст внутрь диаграммы

Это не была бы кольцевая диаграмма без текста внутри и посередине; для этого и предназначена дыра, правильно? Что ж, добавить текст просто. Мы просто используем элемент <text>, который нативен для SVG-фигур.

<svg width="100%" height="100%" viewBox="0 0 42 42" class="donut">
  <circle class="donut-hole" cx="21" cy="21" r="15.91549430918954" fill="#fff"></circle>
  <circle class="donut-ring" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#d2d3d4" stroke-width="3"></circle>
  <circle class="donut-segment" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#ce4b99" stroke-width="3" stroke-dasharray="40 60" stroke-dashoffset="25"></circle>
  <circle class="donut-segment" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#b1c94e" stroke-width="3" stroke-dasharray="20 80" stroke-dashoffset="85"></circle>
  <circle class="donut-segment" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#377bbc" stroke-width="3" stroke-dasharray="30 70" stroke-dashoffset="65"></circle>
  <!-- unused 10% -->
  <g class="chart-text">
    <text x="50%" y="50%" class="chart-number">
      10
    </text>
    <text x="50%" y="50%" class="chart-label">
      Beers
    </text>
  </g>
</svg>

Вы заметите, что я разделил текст диаграммы на 2 элемента <text> и сгруппировал их (<g>). Это было сделано затем, чтобы мы могли легче наложить заголовок и число друг на друга, а также расположить их, как одну единицу. Я настроил атрибуты X и Y так, чтобы начать с центра фигуры на линии основания и выровнить их по левому краю. 

b28a86fd0e423f520593c51eeab3.png

Как вы можете увидеть, позиционирование не совсем верно, так что нам надо будет украсить его капелькой CSS:

<style>
@import url(https://fonts.googleapis.com/css?family=Montserrat:400);
.chart-text {
  font: 16px/1.4em "Montserrat", Arial, sans-serif;
  fill: #000;
  -moz-transform: translateY(0.25em);
  -ms-transform: translateY(0.25em);
  -webkit-transform: translateY(0.25em);
  transform: translateY(0.25em);
}
.chart-number {
  font-size: 0.6em;
  line-height: 1;
  text-anchor: middle;
  -moz-transform: translateY(-0.25em);
  -ms-transform: translateY(-0.25em);
  -webkit-transform: translateY(-0.25em);
  transform: translateY(-0.25em);
}
.chart-label {
  font-size: 0.2em;
  text-transform: uppercase;
  text-anchor: middle;
  -moz-transform: translateY(0.7em);
  -ms-transform: translateY(0.7em);
  -webkit-transform: translateY(0.7em);
  transform: translateY(0.7em);
}
</style>

Для начала, давайте добавим шрифт Montserrat (просто потому, что он мне нравится). Затем нам надо скорректировать font-size ("размер шрифта") и line-height ("высота строки"). После добавления "translateY" в 0.25em текст немного выравнивается по вертикали, но на этом мы еще не закончили. 

Нам надо сделать оба текстовых блока меньше и выровнять их до центра, корректируя font-size дотуда, докуда нам нравится (0.6em для более крупного числа и 0.2em для названия выглядят, что надо) и используя свойство "text-anchor" со значением "middle".

Теперь текст находится в центре. Все, что осталось, это сделать его в верхнем регистре (это легко) и расположить его индивидуальные элементы, используя "translateY", чтобы они сложились должным образом. И вот что мы имеем сейчас:

dd90372f8d13953946f76a3c7e28.png

Проблемы с доступностью

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

Первый уровень проблем с доступностью - сделать SVG-диаграмму более семантической, обернув ее в элемент <figure> (поскольку это - диаграмма). Как фигура, мы можем воспользоваться элементом <figcaprion>, чтобы предоставить заголовок или описание для кольцевой диаграммы. 

Помимо этого, мы можем добавить контент-теги <title> и <desc> (которые нативны для SVG) и связать их с заголовками ARIA, ID и ролью "предоставления большего количества контекста для программ чтения с экрана".

<style>
@import url(https://fonts.googleapis.com/css?family=Montserrat:400);
body {
  font: 16px/1.4em "Montserrat", Arial, sans-serif;
}
* {
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
          box-sizing: border-box;
}
.chart-text {
  /*font: 16px/1.4em "Montserrat", Arial, sans-serif;*/
  fill: #000;
  -moz-transform: translateY(0.25em);
  -ms-transform: translateY(0.25em);
  -webkit-transform: translateY(0.25em);
  transform: translateY(0.25em);
}
.chart-number {
  font-size: 0.6em;
  line-height: 1;
  text-anchor: middle;
  -moz-transform: translateY(-0.25em);
  -ms-transform: translateY(-0.25em);
  -webkit-transform: translateY(-0.25em);
  transform: translateY(-0.25em);
}
.chart-label {
  font-size: 0.2em;
  text-transform: uppercase;
  text-anchor: middle;
  -moz-transform: translateY(0.7em);
  -ms-transform: translateY(0.7em);
  -webkit-transform: translateY(0.7em);
  transform: translateY(0.7em);
}
figure {
  display: flex;
  justify-content: space-around;
  flex-direction: column;
  margin-left: -15px;
  margin-right: -15px;
}
@media (min-width: 768px) {
  figure {
    flex-direction: row;
  }
}
.figure-content,
.figure-key {
  flex: 1;
  padding-left: 15px;
  padding-right: 15px;
  align-self: center;
}
.figure-content svg {
  height: auto;
}
.figure-key {
  min-width: calc(8 / 12);
}
.figure-key [class*="shape-"] {
  margin-right: 6px;
}
.figure-key-list {
  margin: 0;
  padding: 0;
  list-style: none;
}
.figure-key-list li {
  margin: 0 0 8px;
  padding: 0;
}
.shape-circle {
  display: inline-block;
  vertical-align: middle;
  width: 32px;
  height: 32px;
  -webkit-border-radius: 50%;
     -moz-border-radius: 50%;
          border-radius: 50%;
}
.shape-fuschia {
  background-color: #ce4b99;
}
.shape-lemon-lime {
  background-color: #b1c94e;
}
.shape-blue {
  background-color: #377bbc;
}
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0,0,0,0);
  border: 0;
}
</style>
<figure>
  <div class="figure-content">
    <svg width="100%" height="100%" viewBox="0 0 42 42" class="donut" aria-labelledby="beers-title beers-desc" role="img">
      <title id="beers-title">Beers in My Cellar</title>
      <desc id="beers-desc">Donut chart showing 10 total beers. Two beers are Imperial India Pale Ales, four beers are Belgian Quadrupels, and three are Russian Imperial Stouts. The last remaining beer is unlabeled.</desc>
      <circle class="donut-hole" cx="21" cy="21" r="15.91549430918954" fill="#fff" role="presentation"></circle>
      <circle class="donut-ring" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#d2d3d4" stroke-width="3" role="presentation"></circle>
      <circle class="donut-segment" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#ce4b99" stroke-width="3" stroke-dasharray="40 60" stroke-dashoffset="25" aria-labelledby="donut-segment-1-title donut-segment-1-desc">
        <title id="donut-segment-1-title">Belgian Quadrupels</title>
        <desc id="donut-segment-1-desc">Pink chart segment spanning 40% of the whole, which is 4 Belgian Quadrupels out of 10 total.</desc>
      </circle>
      <circle class="donut-segment" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#b1c94e" stroke-width="3" stroke-dasharray="20 80" stroke-dashoffset="85">
        <title id="donut-segment-2-title">Imperial India Pale Ales</title>
        <desc id="donut-segment-2-desc">Green chart segment spanning 20% of the whole, which is 2 Imperial India Pale Ales out of 10 total.</desc>
      </circle>
      <circle class="donut-segment" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#377bbc" stroke-width="3" stroke-dasharray="30 70" stroke-dashoffset="65">
        <title id="donut-segment-3-title">Russian Imperial Stouts</title>
        <desc id="donut-segment-3-desc">Blue chart segment spanning 3% of the whole, which is 3 Russian Imperial Stouts out of 10 total.</desc>
      </circle>
      <!-- unused 10% -->
      <g class="chart-text">
        <text x="50%" y="50%" class="chart-number">
          10
        </text>
        <text x="50%" y="50%" class="chart-label">
          Beers
        </text>
      </g>
    </svg>
  </div>
  <figcaption class="figure-key">
    <p class="sr-only">Donut chart showing 10 total beers. Two beers are Imperial India Pale Ales, four beers are Belgian Quadrupels, and three are Russian Imperial Stouts. The last remaining beer is unlabeled.</p>
    <ul class="figure-key-list" aria-hidden="true" role="presentation">
      <li>
        <span class="shape-circle shape-fuschia"></span> Belgian Quadrupels (4)
      </li>
      <li>
        <span class="shape-circle shape-lemon-lime"></span> Imperial India Pale Ales (2)
      </li>
      <li>
        <span class="shape-circle shape-blue"></span> Russian Imperial Stouts (3)
      </li>
    </ul>
  </figcaption>
</figure>

Мы также можем добавить ключ легенды для диаграммы в качестве части <figcaption>, отмечая его ролью "представления" и атрибутом aria-hidden, поскольку он и вправду нужен для наглядности. 

С щепоткой магии CSS Flexbox мы можем расположить ключ справа и выровнять его по вертикали с диаграммой. Что даст нам финальный продукт:

7e34162bb1b3c192540f14eb093d.png

Поскольку CSS-дизайн с ключом, к которому применяется свойство border-radius и Flexbox могли бы быть отдельными статьями (второе требует гораздо более долгого объяснения), я оставлю эти темы на потом.

Конечные результаты

Как я упоминал ранее, написание кода для объектов SVG вручную может занимать много времени, особенно если принять во внимание тот факт, что существует множество прекрасных JavaScript библиотек, которые построят эти объекты за вас. Но могут быть случаи (как моя ситуация), где вам или вашей команде нужен метод, который не затрагивает JavaScript, тот, что будет собран на стороне сервера. 

Хорошие новости в том, что, как только вы разберетесь с подобным способом, он сможет быть применен вами где-нибудь еще с минимальной затратой усилий. Плюс, замарать руки в работе с объектами SVG - это хороший способ узнать больше о том, как они работают, и узнать преимущества их использования.

Мои результаты:

  • Применять математику к чему-то вроде этого гораздо более интересно, чем в старшей школе. 
  • Оглядываясь назад, я понимаю, что логика, стоящая за stroke-dasharray и stroke-dashoffset не такая сложная, как я думал изначально. 
  • Не забудьте добавить сюда дополнительные уровни доступности. В конце концов, доступность нужна не только в угоду программам чтения с экрана. Она также нужна, чтобы сделать ваш контент более доступным и потребляемым всеми людьми и всеми устройствами (включая поисковые системы). Если ваша JavaScript-библиотека не имеет функций доступности, подумайте над ее изменением. 


Комментарии

Пока что нет комментариев, ты можешь быть первым.
Войти или Регистрация , чтобы оставлять комментарии.
Наш сайт использует куки. Узнайте больше о нашем использовании куки: политика в отношении файлов cookie
Наш сайт существует только благодаря показу онлайн-рекламы нашим посетителям.
Пожалуйста, поддержите нас, отключив блокировку рекламы.