Лінійний повзунок на HTML5, SVG і JavaScript

19

Від автора: у більшій мірі користувачі легко розбираються в елементах інтерфейсу з чисельною системою вимірювання, але графічний інтерфейс може «направляти» користувача і підвищує асоціативну складову, особливо при роботі з великими діапазонами значень. Як і в попередньому прикладі з кільцем, тут також використовується SVG, JavaScript і input типу range.

Як і раніше svg поміщається в label:

Scale

Головним елементом в SVG є rect — він обрізається трикутним полігоном polygon. input змінюється в діапазоні від 0 до 100: зверніть увагу на те, що по ширині він дорівнює polygon; значення инпута співпадає з шириною елемента rect.

На всі елементи вистачає всього кількох рядків CSS:

label, input {
display: block;
width: 25%;
margin: 0 auto;
}
#scale {
margin-top: 2rem;
}

За трикутним SVG полігоном розташований ще один трикутник без стилів; цей трикутник не обрізається, але має ті ж розміри, що і жовтий – він виступає як рамка або задній фон.

На инпут повішені обидві події onchange і oninput, які викликають одну функцію, що працює у всіх браузерах. Функція з кодом JS:

var scale = document.getElementById(«scale»),
svg = document.querySelector(«label[for=’scale’] svg»),
svgns = «http://www.w3.org/2000/svg»,
triangle = svg.getElementsByTagNameNS(svgns, «rect»)[0];
function scaleChange() {
triangle.setAttribute(«width»,scale.value);
}

Експоненціальний повзунок

Про зрозумілості лінійних графічних елементів інтерфейсу можна сперечатися і сперечатися, але дана техніка буде особливо корисна при роботі з нелінійними значеннями, такими як експоненціальні функції. Зазвичай ці функції складні для розуміння звичайного користувача. Приклад експоненціального повзунка представлений в демо Codepen.

Перший лінійний приклад працює тільки за умови, що ширина SVG боксу дорівнює максимальному значенню слайдера. У реальному житті це не підходить. У цьому демо я з допомогою JS зчитую і порівнюю ширину viewbox’а й значення слайдера. Розмітка залишається майже та ж, але для ясності я змінив значення name id:

Population Growth Over Time
Exponential Growth

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

var exponentialslider = document.getElementById(«exponentialslider»),
expsvg = document.querySelector(«label[for=’exponentialslider’] svg»),
expsvgns = «http://www.w3.org/2000/svg»,
mask = expsvg.getElementsByTagNameNS(expsvgns, «rect»)[0],
box = expsvg.getAttribute(‘viewBox’),
viewBoxCords = box.split(/\s+|,/),
viewBoxWidth = viewBoxCords[2] — viewBoxCords[0],
sliderMax = exponentialslider.max;
function expChange() {
mask.setAttribute(«width»,exponentialslider.value * (viewBoxWidth / sliderMax));
}
expChange();

Безпосередньо через DOM ми поки що не може отримати точні значення ширини та висоти viewbox’а, але ми можемо взяти рядок зі значенням з viewbox’а, розбити її в масив, відняти з третього значення перше і отримати ширину. Щоб все вийшло, необхідно дотримати кілька умов:

Viewbox повинен вимірюватися в пікселях

Не можна вставляти нічого зайвого між viewBox і елементами в SVG

SVG повинен займати всю ширину viewbox’а

В самому кінці викликається функція expChange і встановлює вихідну позицію експоненціального графа. Дану техніку можна використовувати і по-іншому: в теорії з допомогою JS можна створювати всю SVG структуру і автоматизувати весь процес.