Кругові елементи інтерфейсу за допомогою HTML5, CSS, JS і SVG. Частина 1

319

Від автора: такі вимірювання як час, відсотки і величина кута найкращим чином можна візуально уявити, найчастіше у вигляді дуги або кола. В HTML5 немає вбудованих кругових елементів управління, але це не повинно зупиняти вас, адже ви можете створити їх самостійно. У цьому прикладі я покажу, як створити інтерактивний елемент інтерфейсу, який буде виступати в ролі таймера або у вигляді кола з відсотками.

Потрібний нам це елемент input типу range:

…і SVG елемент, на який виводяться дані. Ми взяли цей приклад в Lea Verou з її статті CSS Secrets:

(З допомогою div позиціонуються всі елементи, в тому числі і SVG. CodePen демо).

Стилізуємо коло

Периметр SVG кола дорівнює 2πr, тобто 2 × 3.14 × 25 або приблизно 158. Знаючи це, SVG можна зробити коло з допомогою border-radius. Обведення зробити можна за допомогою властивості stroke, а з допомогою властивості stroke – dasharray ми будемо показувати тільки її частину:

#readout {
position: relative;
}
svg {
transform: rotate(-90deg);
color: #333;
background: currentcolor;
border-radius: 50%;
width: 100%;
}
#pie {
fill: currentcolor;
stroke: hsl(0,0%,50%);
stroke-width: 50;
stroke-dasharray: 55 158;
}

Зверніть увагу, що для оголошення SVG і елемента circle з допомогою CSS змінної я використовував currentcolor. Властивість stroke-width – діаметр кола: всі обведення в SVG 1.1 проходять точно через центр елемента path. Властивість border-radius «обрізає» зовнішній край обведення, а обертання робить так, що обведення перетворюється в сектор кола.
Задаємо значення

Для відображення дій користувача у вигляді лічильника ми додамо елементи label і output. Наша розмітка стане такою:

Task CPU Utilization

15%

Стилі до цих елементів я не став включати в статтю, переглянути їх можна в демо CodePen. А нашу увагу ми звернемо на код JavaScript у нижній частині сторінки. В першу чергу знайдемо посилання на потрібні нам об’єкти та змінні:

var utilslider = document.getElementById(“utilslider”),
circle = document.getElementById(“pie”),
radius = parseInt(circle.getAttribute(‘r’), 2),
circumference = 2 * radius * Math.PI,
percentDisplay = document.querySelector(“#readout output”);

Ми не будемо прописувати статичні значення радіуса і довжини окружності в JS. Ми будемо зчитувати значення радіуса (переводити значення з текстового типу в число з плаваючою точкою) і обчислювати довжину кола по цьому значенню.
Зверніть увагу: хоча SVG і адаптивний, довжина окружності буде залишатися однією і тією ж і не буде залежати від розміру вікна, так як радіус SVG не змінюється.

Щоб правильно обчислювати сектор елемента circle з поточним значенням utilsider, необхідно викликати певну функцію. З допомогою цієї функції буде задаватися сектор кола від значення utilsider:

utilslider.addEventListener. (“input”,
function() { pieSlicer(); }
)
pieSlicer();

Сама функція pieSlicer:

function pieSlicer() {
var percentValue = (utilslider.value / 100) * circumference;
pie.style.strokeDasharray = percentValue + “” + circumference;
percentDisplay.innerHTML = utilslider.value + “%”;
}

Як міняти кольори

За замовчуванням колір сектора кола завжди буде таким, який був заданий у CSS. Найпростіший спосіб змінювати його динамічно це HSL. Червоний буде задаватися так (0, 50%, 50%), насиченість кольору задається середнім значенням. Якщо в нашій функції замість насиченості передавати значення utilslider:

pie.style.stroke = “hsl(0 ,” + utilslider.value + “%, 50%)”;

…колір сектора буде змінюватися від чорного до яскраво червоного із збільшенням значення. Також можна змінювати колір з збільшенням значення, про це я розповім в наступній статті.

Tony Downey запропонував використовувати плавні переходи разом з обведенням, тоді величина сектора буде змінюватися по кліку на елемент range моментально і не буде «перестрибувати» на нове значення. CSS код:

#pie {
transition:stroke-dasharray 2s;
}

Також сектор підхоплює будь-які зміни з utilslider. Це лише візуальне представлення числа у формі кола. Наступного разу я розгляну елементи інтерфейсу, більш підходящі для такої інтеграції.