ESPNCFB top 25 betting lines: Texas favored at Tennessee; Oregon favored at USCPunchCommuters groan as rainfall delays First Niger Bridge reopening by one weekBollywood HungamaHanuman Ansh team meets Home Minister Amit Shah in New DelhiDaily MaverickKremlin says AfD’s victory in Germany due in large part to lack of cheap Russian gasRTP DesportoFederação suíça castiga capitão Xhaka por falsificação de certificado covid-19ESPN DeportesIsaac del Toro conquista a rivales y aficionados en el MundialInquirerIloilo motorists rush to gas stations ahead of steep fuel price hikeEgypt IndependentRuling pro-Putin party set to win Russia’s tightly controlled wartime parliamentary electionRai NewsPontes: tokenizzazione e sovranità, l'euro nel futuro dei mercati digitaliABC NewsWATCH: Lucky trumpeter returns for Diamondbacks' World Series victory anniversarySRF NewsGeschichte der Pedalos – Wer hat das Pedalo erfunden? Die Thurgauer!TGCOM24 SpettacoloLewis Hamilton e Kim Kardashian "stellari" all'inaugurazione del museo di George Lucas
The Daily Newsstand · Free, Always
Monday, September 21, 2026

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

Translate

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

Вступление

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

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

Становление

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

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

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

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

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

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

Вызов брошен

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

Бой

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

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

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

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

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

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

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

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

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

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

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

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

Итог

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

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

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

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

Посмотреть и почитать документацию можно [на GitHub].
Собрать свой скролл и забрать готовый код — [в песочнице]

View the original on Хабр

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.