Создание вращающейся ручки на основе Input Range

от автора

Рад приветствовать тебя,%username%. В этой статье я поделюсь тем, как создать вращающуюся ручку (в зарубежной литературе именуемой Knob). Далее по тексту я её буду называть «кноб». Перейдём к сути вопроса.

Что меня сподвигло на написание данной статьи, или как я докатился до жизни такой

Когда-то давно, будучи ещё совсем зелёным и несмышлёным кодером, мне взбрело в голову сделать своё приложение. Моих знаний хватало на какой‑нибудь «Hello, World!», но кое‑что выдать я мог. И на тот момент мне позарез нужно было реализовать кноб — тот самый круглый регулятор, который можно крутить и он будет менять значения. И как любой уважающий себя программист, я сразу же полез гуглить стековерфлоу и прочее непотребство, дабы найти тот самый рецепт хлеба сладкого ответ на вопрос, который так долго меня волновал. Однако перешерстив весь интернет, ничего путёвого я не нашёл. Расстроившись, я забил на эту идею. Но какие‑то угольки веры в то, что у меня получится это сделать, тлели в моей охолодевшей к этому миру душонке. И вот на днях, когда я начал работать над своим проектом (небольшая программка, если она найдёт отклик в народных массах, то и по ней напишу парочку руководств, но пока что спустимся на землю), мне опять ударила моча в голову с этими кнобами. Тем более, что все предпосылки ведут именно к этому. Они нужны в интерфейсе. Забравшись в православный яндекс и одновременно в бездуховный гугл, я опять наткнулся на мель отсутствия нужной мне информации. Были только решения с какими‑то библиотеками и интересными историями на jQuery. Плюнув на всё и засучив рукава, я вдруг осознал, что этот мир нуждается в моём компетентном и всем так очень нужном мнении (спойлер: нет). Тогда я принялся за gehirnsturm и молниеносно придумал пару решений. Первое заключалось в SVG на основе path, но оно показалось мне чересчур геморройным. Там много JS надо написать, но не надо никаких стилей зато. И вот второе решение отчасти продолжает идею первого, но с некоторыми отличиями: оно немножко проще в том плане, что начальное, конечное и текущее значение, а также шаг уже вмонтированы в него, что существенно сокращало труды мои праведные. Но, как гласит закон сохранения энергии, энергия не приходит и не уходит, она лишь изменяется. Поправьте, если не так. А это значит, что если где‑то стало проще, то где‑то стало сложнее.

И вот тут я плавно перехожу к сути дела и раскрываю тему полностью

Наша реализация будет самой бюджетной, но самой выполнимой. Для начала создаём файлы index.html, styles.css и main.js соответственно. Желательно в одной папочке. Вот код файла index.html:

<!DOCTYPE html> <html> <head>     <!-- Подключаем файл с CSS --> <link href="styles.css" rel="stylesheet"/> </head> <body>     <!-- Берём рандомные значения и задаём:          идентификатор элемента (id),          тип (type)          максимальное (max) и          минимальное (min) значения,          шаг (step) и          непосредственно значение (value) --> <input type="range" id="Knob" max="100" min="0" step="0.01" value="14.8"/>      <!-- Подключаем файл с JavaScript -->     <script src="main.js"></script> </body> </html>

Код файла styles.css:

/* Всё, что нам необходимо, делаем здесь */ input[type="range"] { appearance: none; /* Убираем дефолтный стиль */     border-radius: 100%; /* Округляем элемент */     /* Задаём ширину (width) и высоту (height) */     height: 64px;     width: 64px; }  /* А здесь мы отключаем дорожку */ input[type="range"]::-webkit-slider-runnable-track { appearance: none; /* Убираем дефолтный стиль */ height: 64px; /* Задаём высоту, равную элементу */ opacity: 0; /* Скрываем элемент, убрав непрозрачность */ width: 64px; /* Задаём ширину, равную элементу */ }  /* И убираем сам ползунок */ input[type="range"]::-webkit-slder-thumb { appearance: none; /* Убираем дефолтный стиль */ height: 64px; /* Задаём высоту, равную элементу */ opacity: 0; /* Скрываем элемент, убрав непрозрачность */ width: 64px; /* Задаём ширину, равную элементу */ }  /* Об элементе input с типом range можете ознакомиться в документациях Google, Mozilla и прочих */

Код файла main.js:

// Создаём функцию, которая вычислит угол поворота function countAngle(e) {     var fieldOfView = 240; // Т. н. "поле зрения"     var half_of_fov = fieldOfView / 2; // Половина от поля зрения      /* Нормализуем значение:      * Делим разность значения с минимумом на разность максимума с минимумом      */      var normalized = (e.target.value - e.target.min) / (e.target.max - e.target.min); var result = (normalized * fieldOfView) - half_of_fov; // Масштабируем значение и смещаем на половину  return result; }  var elem = document.querySelector("#Knob"); // Получаем элемент по идентификатору  elem.style.background = "conic-gradient(from " + ((((elem.value - elem.min) / (elem.max - elem.min)) * 240) - 120) + "deg, #008081, #FFFFFF)"; // Устанавливаем в качестве фона конический градиент со значением вычисленным вручную, потому что функция принимает в качестве аргумента событие элемента. Здесь же мы получаем все значения напрямую и вычисляем их  // Создаём событие, реагирующее на ввод наших данных elem.oninput = function (e) {     // e.target - это наш элемент, к которому мы прикрутили стиль e.target.style.background = "conic-gradient(from " + countAngle(e) + "deg, #008081, #FFFFFF)"; // Обновляем значение      // Важно! Если мы вместо знака "=" укажем "+=", то у нас получится не то, потому что мы будем к текущему значению прибавлять новое значение и получится к примеру вот так:     // conic-gradient(from 0deg, #008081, #FFFFFF)conic-gradient(from 1deg, #008081, #FFFFFF)     // А нам нужно, чтобы значение было таким:     // Сначала: conic-gradient(from 0deg, #008081, #FFFFFF)     // А потом только conic-gradient(from 1deg, #008081, #FFFFFF) };

Достоинства данного подхода:

  • Быстро

  • Дёшево

  • Не нужно библиотек или фреймворков

Недостатки

  • Нужно скрывать все элементы интерфейса

  • Трудность создания фона

  • Дополнительная нагрузка (тут уже у меня сработал ген осторожности)

В комментариях вы сами найдёте другие положительные и отрицательные стороны данного решения, ну а ниже вы можете уже увидеть результат работы нашего кода:


ссылка на оригинал статьи https://habr.com/ru/articles/914660/


Комментарии

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

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