Вход на сайт

Просмотр новости

Найдите то, что Вас интересует

История npm‑библиотеки morphing‑scroll

Дата публикации: 21-09-2026 11:28:51

Хочу рассказать о своей npm‑библиотеке — это мой второй и самый сложный npm‑проект на момент написания статьи.
Библиотека решает ряд проблем и ограничений связанных с дефолтным поведением браузерного элемента скролл.Глубоко в код погружаться не буду — поделюсь историей создания и мотивацией.✨ Читать далее →

Основное содержимое страницы с новостью.

Уровень сложностиПростой

Время на прочтение6 мин

Охват и читатели9.1K

Кейс

Хочу рассказать о своей npm‑библиотеке — это мой второй и самый сложный npm‑проект на момент написания статьи. Глубоко в код погружаться не буду — поделюсь историей создания и мотивацией.

8b95d6c5af792413ea4c69baa755f78b.pngВступление

Примерно в 2015 году я получил свою первую работу UI/UX‑дизайнером. Рисовал интерфейсы мобильных и десктопных приложений в популярном тогда Sketch, на выделенном мне Mac, и был этому искренне рад. Шло всё неплохо: я соблюдал гайдлайны iOS и Android, а когда идея приложения во мне откликалась, старался уделить дизайну больше внимания — наполнял интерфейс своими иллюстрациями (я художник по образованию) и необычными решениями отдельных элементов. Иногда выходило вполне достойно.

Но был один элемент, изменения которого не принимались никогда, — полоса прокрутки. Разработчики, которым я передавал макет, очень не любили, когда её трогали, и прямо об этом говорили. Скролл, а особенно его бегунок, был тёмным лесом, в который лучше не заходить. И когда я в очередной раз слышал «это сделать нельзя», я начинал чувствовать себя тем самым парнем, который весело рисует облачка на кнопках под звуки поп‑исполнителей, пока разработчик страдает, перенося художественный замысел в код. Именно так макет UI и финальная реализация прощаются друг с другом.

b1d159d82985fcb00d8a59fda68611f3.pngСтановление

Шло время, и постепенно я начал не только рисовать макеты, но и верстать их на React. Так я всё глубже погружался в разработку — и однажды встретился со своим старым врагом: скроллом в браузере. Тогда я и ощутил на себе тот урон, который терпели тысячи разработчиков, разбивая труды дизайнеров о скалы невозможного.

Но что же с ним не так, о каких ограничениях речь? Поговорим о тех самых проклятьях, обрекающих на страдания невинных разработчиков.

8b67f511bb6b3e8cf15b6afb373a3947.pngПроклятье первое — «Вавилонская башня»

Когда‑то давно у всех был один язык, все друг друга понимали, и о кроссплатформенных бедах никто не слышал. Потом разработчики браузеров, при отсутствие единой спецификации и стандартов, начали делать одно и то же, но по‑разному. Как итог один и тот же элемент выглядит немного иначе в зависимости от того, чем вы открыли страницу.

141fcd37cc21b6b66ed855050df560de.pngПроклятье второе — «Лишение»

Кастомизации этот элемент почти не поддаётся, а то, что есть, изменениями назвать трудно: цвет через CSS да три варианта ширины. Есть ещё ::-webkit-scrollbar, но и это лишь покраска: поставить вместо бегунка свой элемент — с анимацией или реакцией на движение, просто нельзя. Дизайнеру же остаётся только чувство беспомощности. Странно, правда? Элемент, который пользователь видит на каждой странице, почти нельзя оформить.

a17c3a3c8fd6d50a638b47835f4b692a.pngВызов брошен

И вот, имея при себе знания JS и React, в 2023 году я решил дать бой этим бедствиям. Я не до конца понимал, какой длинный и тернистый путь меня ждёт, но награда того стоила: где‑то вдалеке виднелся тот самый UI мечты, где вместо скучного серого бегунка можно поставить свой — любой формы и стиля, светящийся при наведении, растущий при нажатии, какой угодно. Да хоть фаербол вместо бегунка — я должен иметь возможность это сделать. Зачем эти ограничения?!

59d0d9141448c8ccd0e8f84b75dd7f16.pngБой

Цель ясна, а вот способа её реализации пока не было. Хотелось, чтобы библиотека работала сразу, из коробки. С моими знаниями я мог написать React‑компонент, и это было неплохим решением, но оставался вопрос стилизации: стили по умолчанию должны были приезжать вместе с компонентом. Можно было бы при монтировании рендерить в HTML тег <style>, но это ненадёжно, значит, стили должны жить внутри компонента — и ответ оказался предельно простым: инлайн‑стили. Я не фанат инлайн‑стилей, но здесь они разом решали целый пласт проблем: стилизация сразу оказывалась на месте и именно там, где нужно. Это заставило меня хорошо продумать элементы скролла и попутно ответить на вопросы реализации. Было также ясно, что без TypeScript я не справлюсь: в какой‑то момент просто не смогу поддерживать проект. Ну что ж, стек ясен — делаем.

58137a113a09827ca97603ed51989c30.pngРаунд первый — «Смешение»

В первой версии я пытался собрать странное смешение: браузерный скролл со скрытым бегунком и моим элементом вместо него. Он умел только вертикальную прокрутку и горизонтальную, которая по сути была повёрнутой вертикальной. Очень быстро я упёрся во множество ограничений и понял, что писать придётся всё самому — и обработку событий прокрутки, и анимацию движения. А ещё нужно было учесть прокрутку по горизонтали и вертикали одновременно. Стало ясно, что текущая реализация несерьёзна и больше похожа на первые шаги, чтобы нащупать направление. Что делать дальше, я уже понимал, но немного выгорел и взял паузу, чтобы всё обдумать и вернуться со свежими силами.

9afa66ce18a9a4a8954093a1e5035d4e.pngРаунд второй — «Всё сам»

Сев за вторую версию, я уже лучше понимал, что библиотека должна уметь и что для этого нужно. Я глубже погрузился в разработку и в создание внутренних механик, и у меня начало получаться. Но чем дольше я работал, тем больше идей приходило в голову, и список «что можно сделать ещё» вышел внушительным. Например, я понял, что написанное легко превращает компонент не только в скролл, но и в слайдер, — и добавил такой режим, а с ним стрелки и отдельную анимацию перелистывания. А по опыту работы со списками я знал, что нужны и ленивая отрисовка (объект появляется, когда до него докрутили, и остаётся), и виртуализация (в DOM живёт только то, что видно).

В какой‑то момент самым сложным стало не наличие механик, а то, как они уживаются друг с другом.

Простой пример. На странице есть горизонтальная лента карточек, а сама страница прокручивается вертикально. Пользователь ставит на ленту палец и ведёт — кому достаётся жест? Если палец пошёл вбок — ленте, если вниз — странице, и решать это нужно по первым же пикселям движения, пока человек ничего не заметил. А если он тянет не карточки, а бегунок ленты? Тогда жест принадлежит только ей, и страница не должна сдвинуться ни на пиксель. По отдельности каждое правило простое, но мышь, палец, колесо, клавиатура, вложенные скроллы и слайдеры начинают спорить друг с другом — и больше всего времени уходило именно на их регулировку.

Всё это сводило с ума и требовало огромного количества проверок и тестов. Стоило мне решить, что сделано всё, что можно, как я придумывал что‑то классное, что немедленно хотелось добавить, — и это начинало раздражать. Так библиотека разрослась, а API перестал быть цельным. Я снова выгорел и взял паузу.

7f704349427bca7cf3d1ffd3ae5f7237.pngРаунд третий — «Порядок»

К третьей версии подступиться было трудно: всего накопилось много, но надо было наводить порядок и переделывать API. Тут я подключил к разработке ИИ, чтобы ничего не упустить при переделке и покрыть код тестами — иначе, чиня одно, я неизбежно ломал другое. И вот на горизонте забрезжил финальный API, который меня устраивал, а тесты были готовы. Добавилось и несколько новых фич: плитка из элементов разных размеров, бесконечная прокрутка и список, который начинается справа, — для языков, где читают справа налево.

Добавлю, что название выбрано не случайно: компонент может вести себя совершенно по‑разному и даже вовсе не походить на скролл — всё зависит от вашего воображения.

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

ebc7236fbb967a17669d224a6f84807a.pngИтог

Всё получилось, но по дороге библиотека заставила меня ответить на множество вопросов о том, как скролл должен себя вести и что уметь.

Читая эту статью, можно задаться вопросом: зачем столько трудов ради одного элемента и кому это нужно? Берите библиотеку, если хотите сделать что‑то необычное, а не то, что даёт браузер по умолчанию. Ещё она пригодится разработчикам игр — там стандартных решений почти не бывает.

От себя добавлю: если вас когда‑то пугали злым драконом, к встрече с которым вы были не готовы из‑за недостаточной квалификации, но который всё время попадается на пути, — попробуйте бросить ему вызов при следующей встрече. Как минимум вы приобретёте новые знания и навыки. Как максимум — сделаете мир немного дружелюбнее или просто интереснее.

Отдельно хочу поблагодарить коллег за терпение, пока я внедрял эту библиотеку на проде.

Посмотреть и почитать документацию, а так же собрать свой скролл можно [на странице morphing-scroll].

Удачи и успехов в разработке!

PS: тот самый [фаербол вместо бегунка]

714850a9056d53b9b8c84df5335165cb.png

Если эта публикация вас вдохновила и вы хотите поддержать автора — не стесняйтесь нажать на кнопку

Схожие новости

#Наименование новостиТональностьИнформативностьДата публикации
1[Перевод] 10 браузерных API, заменяющих библиотеки, которые я раньше все время устанавливал09.3528-09-2026
2О том, как я написал свой стейт‑менеджер09.1427-09-2026
3Как писать стили в 2026: CSS Modules, CSS‑in‑JS, Tailwind и zero‑runtime010.8401-10-2026
4Кризис идентичности, или как Vue-разработчик мигрировал enterprise-проект на Angular 1809.9425-09-2026
5Почему архитектура важнее выбора стейт-менеджера в React08.3701-10-2026
6Продвинутый статический анализ в TypeScript-проектах: выходим за рамки tsc и ESLint014.7501-10-2026
7Удалить что угодно со страницы одним кликом: как устроен «пипеточный» блокировщик на Manifest V308.9725-09-2026
8Как я писал сервер и нечаянно пробил 1М RPS01031-08-2026
9Как мы создали Open-Source альтернативу закрытым платёжным системам на React, Node.js и WebNFC08.9826-09-2026

Классификация: . Схожих патентов: 0. Схожих новостей: 9. Тональность: 0. Информативность: 7.81. Источник: habr.com.