shadow - создание теневого элемента

Dragula предоставляет мощный инструмент для организации перетаскивания элементов между контейнерами. Одной из ключевых функций является возможность создания shadow-элемента — визуального индикатора, который отображается в момент перетаскивания и помогает пользователю понять, куда будет перемещён объект. Shadow облегчает восприятие перемещаемого элемента, особенно в сложных интерфейсах.

Основные принципы работы shadow

Shadow в Dragula — это копия перетаскиваемого элемента, которая вставляется в DOM в момент начала drag-and-drop. По умолчанию Dragula создает простой прямоугольник, стилизованный автоматически, но поведение и оформление можно полностью кастомизировать.

Ключевые особенности shadow:

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

Включение и настройка shadow

Dragula предоставляет несколько опций для управления shadow через объект конфигурации при инициализации:

const drake = dragula([container1, container2], {
    copy: false, 
    revertOnSpill: true,
    moves: function (el, source, handle, sibling) {
        return true; 
    },
    accepts: function (el, target, source, sibling) {
        return true; 
    },
    direction: 'vertical', 
    mirrorContainer: document.body
});

Здесь важной является опция mirrorContainer. Она определяет контейнер, в котором будет создаваться shadow-элемент (так называемый mirror). По умолчанию shadow вставляется в <body>, что обеспечивает его независимость от структуры исходных контейнеров и позволяет свободно перемещать его поверх других элементов.

Стилизация shadow

Dragula добавляет классы CSS для shadow-элемента:

  • .gu-mirror — основной класс shadow.
  • .gu-transit — класс для элемента, который перемещается в контейнере.

Пример базовой стилизации:

.gu-mirror {
    position: fixed;
    margin: 0;
    z-index: 9999;
    opacity: 0.8;
    background-color: #f0f0f0;
    border: 2px dashed #aaa;
    padding: 10px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
    pointer-events: none;
}

Особенности:

  • position: fixed гарантирует, что shadow всегда виден поверх других элементов.
  • pointer-events: none предотвращает взаимодействие shadow с событиями мыши.
  • Можно динамически изменять стили через JS во время drag, используя события Dragula.

Работа с событиями для управления shadow

Dragula предоставляет набор событий, которые позволяют гибко контролировать shadow:

  • drag — срабатывает при начале перемещения, позволяет модифицировать shadow или применить эффекты к исходному элементу.
  • shadow (mirror) — непосредственно для кастомизации shadow во время drag можно использовать событие cloned или изменять содержимое через el.cloneNode.
  • drop — удаляет shadow и фиксирует позицию исходного элемента.
  • cancel — удаляет shadow при отмене перемещения (например, при revertOnSpill).

Пример использования события drag для изменения shadow:

drake.on('drag', function(el, source) {
    const mirror = document.querySelector('.gu-mirror');
    mirror.style.backgroundColor = '#e0f7fa';
    mirror.style.transform = 'scale(1.05)';
});

Создание кастомного shadow

В случаях, когда стандартного shadow недостаточно, можно полностью контролировать процесс через клонирование элемента:

drake.on('cloned', function(clone, original, type) {
    if (type === 'mirror') {
        clone.style.border = '3px solid #2196f3';
        clone.style.backgroundColor = '#ffffff';
        clone.style.boxShadow = '0 6px 12px rgba(0,0,0,0.3)';
    }
});
  • clone — это shadow-элемент, который будет отображаться во время drag.
  • original — исходный элемент, позволяющий синхронизировать содержимое.
  • type может быть 'mirror' или 'copy', что помогает различать shadow и копии элементов.

Практические советы

  • Производительность: при большом количестве элементов лучше использовать mirrorContainer: document.body, чтобы избежать перерисовки родительских контейнеров.
  • Анимации: добавление CSS-переходов к shadow позволяет создать эффект плавного перемещения.
  • Совместимость с touch: shadow корректно работает на мобильных устройствах при использовании Dragula v3+ с поддержкой touch-событий.

Shadow — это не просто визуальный эффект, это элемент, который повышает юзабилити интерфейсов, делает перетаскивание интуитивным и позволяет реализовать сложные логики перемещения без вмешательства в DOM исходных контейнеров.