Skip to content

InView

v0.1.0UI-компонентыVanilla JSVueNuxtReact

Framework-agnostic движки для скролла, видимости элементов и их позиции во viewport — с адаптерами для Vue 3, Nuxt и React, объединённые в один shared rAF-loop и пул IntersectionObserver.

InView
Начать знакомство →
npm install @macrulez/inview-core
01 — Назначение

Когда это пригодится

Reveal-эффекты при скролле, параллакс, индикатор прогресса чтения — типовая задача, которую обычно решают либо тяжёлой анимационной библиотекой, либо самописным набором scroll-листенеров и IntersectionObserver, дублирующимся в каждом компоненте. InView берёт эту механику на себя один раз, на уровне общего движка.

Фон на лендинге должен двигаться медленнее, чем сама страница

Классический приём глубины: иллюстрация или фотография на фоне сдвигается медленнее (или быстрее) самого контента, пока страница прокручивается. Обычно ради этого вручную считают позицию элемента на каждом кадре скролла и переводят её в CSS-трансформацию с нуля. Готовый эффект уже умеет ограничивать сдвиг на краях, задавать скорость и направление — и сам отключается, если пользователь попросил операционную систему снизить анимацию.

Секции ленты должны проявляться по мере прокрутки

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

Индикатор прогресса чтения наверху длинной статьи

Тонкая полоса, которая по мере прокрутки заполняется от края до края, — частый элемент у блогов и лонгридов. Обычно ради неё вручную делят пройденное расстояние на высоту документа и пересчитывают на каждом кадре скролла. Готовое значение прогресса — уже число от 0 до 1, обновляется само на одном общем цикле анимации вместе с остальным состоянием скролла.

Шапка сайта должна прятаться при скролле вниз и появляться при скролле вверх

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

02 — Фичи

Коротко о главном

Скролл-движок на общем цикле анимации

Скролл-движок на общем цикле анимации

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

Видимость элементов с общим пулом наблюдателей

Видимость элементов с общим пулом наблюдателей

Реактивно показывает, виден ли элемент, с какой стороны он появился или исчез, и умеет сработать один-единственный раз. Элементы с одинаковыми настройками отслеживания используют общий обозреватель вместо отдельного на каждый — заметная экономия на страницах с их большим числом.

Позиция элемента относительно viewport

Позиция элемента относительно viewport

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

Параллакс-слой с учётом сниженной анимации

Параллакс-слой с учётом сниженной анимации

Превращает положение элемента в области видимости в CSS-трансформацию с настраиваемой скоростью, осью, ограничением на краях и своей кривой плавности — и сам отключается для тех, кто попросил операционную систему снижать анимацию.

Модуль для Nuxt с автоматическими импортами

Модуль для Nuxt с автоматическими импортами

Все функции доступны без явного импорта в любом компоненте Nuxt-приложения. Настройки по умолчанию задаются один раз в конфиге проекта и подхватываются сами — ничего дополнительно передавать на каждый вызов не нужно.

React-хуки, зеркалящие Vue-версию один в один

React-хуки, зеркалящие Vue-версию один в один

То же API и то же поведение, что и во Vue-версии, только без реактивных ссылок — обычные значения, обновляющиеся сами по себе, и безопасный снимок состояния при рендере на сервере.

03 — Быстрый пример

Как это работает

Полоса прогресса скролла — без фреймворка

createScrollEngine() объединяет события скролла в один общий цикл requestAnimationFrame и отдаёт progress, direction и velocity — всего через один subscribe().

scroll-progress.ts
import { createScrollEngine } from '@macrulez/inview-core'

const progressBar = document.querySelector('#progress-bar') as HTMLElement
const scroll = createScrollEngine()

scroll.subscribe((state) => {
  progressBar.style.transform = `scaleX(${state.progress})`
})

Проявление элемента по мере прокрутки

createElementTracker() отслеживает, как далеко элемент прошёл через viewport; bindCSSVar() записывает это прямо в CSS custom property, так что сам fade/translate живёт в обычном CSS.

reveal-on-scroll.ts
import { createElementTracker, bindCSSVar } from '@macrulez/inview-core'

const card = document.querySelector('#card') as HTMLElement
const tracker = createElementTracker(card)

tracker.subscribe((state) => {
  bindCSSVar(card, 'reveal', state.viewportProgress)
})