Линейный ползунок на HTML5, SVG и JavaScript

Линейный ползунок на HTML5, SVG и JavaScript

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

Как и раньше svg помещается в label:

<label for="scale">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 33">
        <title>Scale</title>
            <defs>
                <clipPath id="triangle">
                    <polygon points="0 33, 100 33, 100 0" />
                </clipPath>
            </defs>
        <polygon points="0 33, 100 33, 100 0" />
        <rect x="0" y="0" height="50" width="50" clip-path="url(#triangle)" fill="yellow" />
    </svg>
</label>

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

<input id="scale" type="range" name="scale" min="0" max="100" value="50" oninput="scaleChange()" onchange="scaleChange()">

На все элементы хватает всего пары строк 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:

<label for="exponentialslider">
    Population Growth Over Time
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 627 350">
        <title>Exponential Growth</title>
            <defs>
                <clipPath id="exp">
                    <path d="M0,350c370-10,521.7,31.7,626.7-350c0,78.3,0,350,0,350S275,350,0,350z"/>
                </clipPath>
            </defs>
            <path d="M0,350c370-10,521.7,31.7,626.7-350c0,78.3,0,350,0,350S275,350,0,350z"/>
            <rect height="350" width="627" clip-path="url(#exp)" fill="yellow" />
        </svg>
</label>
<input id="exponentialslider" type="range" name="exponentialslider" 
    min="0" max="10" value="8" step=".1" 
    oninput="expChange()" onchange="expChange()">
</div>

Так как путь повторяется, то намного лучше ссылаться на оба режима через один <symbol>, но эту задачу я оставлю читателям. Скрипт стал немного больше:

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 структуру и автоматизировать весь процесс.

Источник: http://thenewcode.com/

Редакция: Команда webformyself.

Практика HTML5 и CSS3 с нуля до результата!

Получите бесплатный пошаговый видеокурс по основам адаптивной верстки с полного нуля на HTML5 и CSS3

Получить

Метки:

Комментарии Вконтакте:

Комментарии Facebook:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree