Перейти к содержимому
Поиск
Разработка

Электрический паук на JavaScript: 12 примеров и готовый код

Собственные Canvas-примеры электрического паука: 12 вариантов, настройки нитей и свечения, управление мышью и касанием. Разбираем алгоритм и скачиваем готовые HTML, CSS и JavaScript.

Александр Некрасов
Электрический паук: Canvas + JavaScript, светящиеся бирюзовые нити на тёмном фоне

Интерактивный эффект интереснее изучать руками: провести указателем, убрать свечение, уменьшить число линий и посмотреть, что осталось. В этой статье соберём собственного «электрического паука» на Canvas, разберём его устройство и заберём готовый HTML, CSS и JavaScript без внешних библиотек.

Отправная точка материала: Electric strings от Mertl на CodePen, где цепочки сегментов тянутся к движущейся цели. Ниже не встроенная копия Pen, а наша отдельная учебная реализация с двенадцатью вариантами, настройками, управлением с клавиатуры и экспортом.

Что здесь называется электрическим пауком

У оригинального примера название Electric strings, то есть «электрические нити»: в его коде есть опоры, сегментированные щупальца и цель, следующая за мышью. «Паук» здесь удобный образ для эффекта, а не готовая библиотека с анатомически правильным животным.

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

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

Живая мастерская: 12 собственных вариантов

Начните с первого примера и нажмите «Запустить анимацию». В режиме «Указатель» центр следует за мышью, а когда мышь покидает стенд, переходит к плавному автоматическому движению; на телефоне положение можно задать касанием.

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

При открытии страница ничего не анимирует автоматически. В паузе можно щёлкать по стенду, двигать цель стрелками, менять настройки и сохранять отдельные композиции.

Что попробовать в каждом примере

  • Электрические нити: случайное облако опор. Проведите указателем вдоль края и сравните радиус активной области при разной длине.
  • Восемь лап: восемь опор по кругу. Двигайте цель недалеко от центра, затем уменьшите длину и посмотрите, когда дальние лапы исчезнут.
  • Сетка контактов: регулярные ряды точек. Здесь проще увидеть границу между активными и неактивными нитями.
  • Кольцо нитей: радиальный веер с автоматическим движением. Переключитесь на указатель, чтобы сравнить симметрию и перекос.
  • Живая рамка: опоры по периметру. Проверяйте её в разных размерах контейнера: не всякая нить достанет до центра широкого баннера.
  • Мягкие щупальца: длинные цепочки с медленным откликом. Сначала меняйте отклик, а затем количество сегментов, не смешивая два эффекта.
  • Световой след: предыдущие кадры постепенно исчезают. Сравните 0%, 70% и 94% следа во время движения.
  • Тёплое свечение: золотистый вариант для другой палитры. Попробуйте свой цвет и небольшую интенсивность размытия.
  • Монохром: почти белые линии без свечения. Отделите красоту формы от яркости эффекта.
  • Лёгкий режим: меньше нитей и сегментов. Используйте как отправную точку для проверки на своём телефоне.
  • Скелет анимации: видимые стыки отрезков. Переключайте 3 и 24 сегмента, чтобы рассмотреть алгоритм.
  • Спокойный фон: неподвижный центр. Настройте композицию без движения и сохраните её как PNG.

Попробовать восемь лап ↑ · Показать скелет ↑ · Сравнить световой след ↑

Как устроены цель, цепочка и опора

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

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

// Фрагмент из нашей модели: поставить узел на расстоянии step.
const angle = Math.atan2(current.y - next.y, current.x - next.x);
current.x = next.x + Math.cos(angle) * step;
current.y = next.y + Math.sin(angle) * step;

Цель отдельно догоняет указатель. В нашем коде коэффициент зависит от времени между кадрами, а не от постоянного «делить на десять»; увеличение параметра response означает более быстрый отклик.

// dt: время с прошлого кадра в секундах.
const easing = 1 - Math.exp(-response * dt);
target.x += (pointer.x - target.x) * easing;
target.y += (pointer.y - target.y) * easing;

Это объясняющие фрагменты, а не полная программа. Полную функцию, обработчики и запуск вместе можно скопировать в панели «JavaScript: весь движок и запуск» или получить одной кнопкой в готовом HTML.

Мышь, касания и клавиатура

Pointer Events позволяют обрабатывать координатный ввод мышью, пером и пальцем одной моделью событий (MDN: Using Pointer Events). В нашем стенде обработчики закреплены за canvas, а не за всей страницей.

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

const rect = canvas.getBoundingClientRect();
const x = (event.clientX - rect.left) / rect.width;
const y = (event.clientY - rect.top) / rect.height;
// x и y затем ограничиваются диапазоном от 0 до 1.

По умолчанию вертикальное движение пальцем оставлено для прокрутки. Переключатель «Рисовать пальцем вместо прокрутки стенда» включает управление перетаскиванием только внутри рисунка; выключите его, чтобы снова листать страницу через эту область.

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

Свечение, след и чёткость Canvas

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

Световой след устроен иначе: вместо полной очистки на предыдущий кадр накладывается полупрозрачный тёмный прямоугольник. Чем больше сохранённая доля предыдущего кадра, тем длиннее шлейф; при смене параметров стенд очищается, чтобы старые линии не мешали сравнению.

Размер canvas в CSS и размер его буфера различаются: для более чёткого изображения буфер можно увеличить с учётом devicePixelRatio и масштабировать контекст (MDN: devicePixelRatio). В нашей реализации плотность ограничена значением 2, чтобы не увеличивать буфер без ограничения.

const dpr = Math.min(window.devicePixelRatio || 1, 2);
canvas.width = Math.round(width * dpr);
canvas.height = Math.round(height * dpr);
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);

При изменении размеров наши опоры пересоздаются, а центр возвращается в середину. Это осознанное упрощение учебной версии, а не сохранение физической сцены при любом ресайзе.

Готовые HTML, CSS и JavaScript для своего проекта

Самый простой путь: настройте эффект, нажмите «Скачать полный HTML», откройте файл в браузере и запустите анимацию. Внутри находятся разметка, стили, весь движок и выбранные параметры; сборщик, CDN и установка пакетов этому примеру не нужны.

Для существующей страницы возьмите три части из панели кода: разметку HTML, оформление CSS и JavaScript. Разметку поставьте в нужное место, стили подключите в head, а скрипт разместите после разметки или запускайте после загрузки DOM.

  1. Выберите подходящий вариант, например «Лёгкий режим».
  2. Настройте цвет, количество нитей и длину, проверьте движение в реальном размере контейнера.
  3. Скопируйте полный HTML для самостоятельной страницы либо все три раздельные части для встраивания.
  4. Проверьте результат на телефоне и оставьте кнопку паузы доступной.

JSON в панели является только конфигурацией. Он не заменяет движок; его можно передать функции createElectricSpider из полного JavaScript.

// Когда функция createElectricSpider уже подключена:
const effect = createElectricSpider(canvas, {
  count: 48,
  segments: 8,
  reach: 220,
  glow: 0,
  color: '#67e5de'
});
// Старт только по осознанному действию пользователя:
startButton.addEventListener('click', () => effect.resume());
pauseButton.addEventListener('click', () => effect.pause());
// Перед удалением компонента в SPA:
// effect.destroy();

Метод destroy удаляет обработчики, отключает наблюдатели и отменяет кадр анимации. В обычном скачанном HTML всё уже связано с кнопкой; в React, Vue или другом приложении жизненный цикл компонента нужно подключить самостоятельно.

Если браузер запрещает доступ к буферу обмена, мастерская выделяет код и предлагает Ctrl+C или Cmd+C. «Скачать PNG» сохраняет текущий кадр, а не анимацию: для видео понадобится отдельная запись.

Три практических сценария

Интерактивная карточка

Начните с «Живой рамки» и проверьте её в контейнере нужной ширины. Не перекрывайте canvas невидимым слоем над кнопками: интерактивный эффект должен оставаться отдельной областью, а основные действия страницы работать независимо.

// Конфигурация к нашему движку:
{ layout: 'edges', count: 48, segments: 12, reach: 420, glow: 3 }

Учебный разбор цепочки

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

{ layout: 'ring', count: 8, segments: 6, reach: 330, nodes: true, glow: 0 }

Статичная иллюстрация

Выберите «Спокойный фон», подберите сетку и цвет, затем скачайте PNG. Такой рисунок можно использовать там, где интерактивность не приносит пользы, а дополнительный JavaScript не нужен.

Настроить рамку ↑ · Начать с лёгкого режима ↑ · Собрать статичную композицию ↑

Как использовать паука в интерфейсе: 6 живых сцен

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

В первом экране нити остаются спокойным декоративным акцентом. В остальных сценах их концы подписаны, а активные связи отражают состояние интерфейса: выбранный раздел, тариф, найденные материалы или готовность полей. Информация продублирована обычным HTML, и задачи работают при отключённом canvas. Постоянной анимации нет: действие вызывает короткий переход, после которого рисунок снова неподвижен.

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

  • Первый экран: живая иллюстрация рядом с коротким заголовком и кнопкой. В нашем примере кнопка открывает описание, а текст не пересекается с нитями. Попробовать первый экран ↑
  • Разделы продукта: одна иллюстрация откликается на выбранную вкладку. Сами вкладки работают мышью и клавиатурой; активный пункт не зависит от цвета или анимации. Переключить разделы ↑
  • Выбор тарифа: визуальный акцент следует за выбором, а стоимость пересчитывается отдельной функцией. Цены в демо вымышленные; годовой вариант равен месячной цене × 12 × 0,8. Сравнить варианты ↑
  • Чтение файла: эффект сопровождает реальное локальное чтение TXT, CSV или JSON до 2 МБ. Индикатор использует события FileReader, а не придуманный таймер; маленький файл может прочитаться сразу. Файл на сервер не загружается. Выбрать локальный файл ↑
  • Пустой поиск: небольшой каталог действительно фильтруется. Когда ничего не найдено, появляются объяснение и кнопка сброса, а не только красивая картинка. Проверить пустое состояние ↑
  • Подтверждение формы: поля проходят локальную проверку, после чего интерфейс показывает завершение. Это не подписка: данные не отправляются и не сохраняются. Заполнить демо-форму ↑

Принцип подключения: нити показывают состояние

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

// Наша адаптация для сцены «Разделы продукта».
// Контейнер canvas содержит также .visual-caption.
const threads = createInterfaceThreads(canvas, { id: 'tabs' });

// 0: Проекты, 1: Аналитика, 2: Команда.
// Обработчик вкладки обновляет содержимое и активную связь.
threads.update({ selected: 1 });

// Отключить плавность: следующее состояние появится сразу.
threads.setMotion(false);
// Скрыть декоративную схему, не выключая интерфейс.
threads.setVisible(false);
// Перед удалением компонента:
threads.destroy();

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

В скачиваемом HTML уже есть разметка выбранной сцены, CSS, адаптированный рендерер и её обработчики. Для переноса используйте mountInterface(root, config, createInterfaceThreads), а при размонтировании вызовите возвращённый destroy(): он удалит обработчики, наблюдатели и остановит чтение файла, если оно ещё идёт.

/* Canvas декоративный и не блокирует кнопки. */
.visual { position: relative; }
.visual canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
/* Текст и действия находятся в соседнем HTML-контейнере. */
.surface { position: relative; background: #fff; }

Практическая проверка простая: выключите «Показать связи» и выполните ту же задачу ещё раз. Если без нитей непонятно, какой тариф выбран, что произошло с файлом или почему форма не прошла проверку, нужно исправлять сам интерфейс, а не добавлять свечение.

Производительность и бережное движение

Для анимации Canvas MDN рекомендует requestAnimationFrame вместо setInterval (MDN: Optimizing canvas). В нашей реализации работает одна цепочка кадров: повторный запуск не создаёт второй цикл, а смена размера только пересчитывает рисунок.

Сначала уменьшайте количество нитей, затем количество сегментов и свечение. Произведение «нити × сегменты» помогает сравнить объём геометрии, но само по себе не является замером производительности: скорость зависит и от устройства, размера буфера и затрат на отрисовку.

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

Настройка prefers-reduced-motion сообщает о предпочтении пользователя уменьшить необязательное движение (MDN: prefers-reduced-motion). У нас начальное состояние всегда статичное; если настройка уменьшения движения включается во время работы, эффект ставится на паузу.

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

Когда этот эффект стоит использовать

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

Начните с минимального числа нитей, найдите понятное пользователю поведение и только потом добавляйте визуальные детали. Если результат нравится без свечения и без автоматического движения, значит в нём уже есть интересная форма, а не только яркий эффект.

Для сравнения оставляем ссылку на оригинальный Electric strings; для основ Canvas полезно руководство MDN по базовым анимациям. Наши готовые файлы собираются прямо в мастерской из её собственного движка и текущих настроек.