Эта статья основана на общедоступной предварительной версии Windows 10 и Visual Studio 2015.
Продукты и технологии:
Windows 10, XAML, универсальные Windows-приложения
В статье рассматриваются:
- концепции перетаскивания (drag-and-drop);
- реализация источников (drag sources) и мишеней (drop targets) в операции перетаскивания;
- настройка визуальной обратной связи;
- применение асинхронных операций.
Исходный код можно скачать по ссылке msdn.microsoft.com/magazine/
Перетаскивание (операция «drag-and-drop») — интуитивно понятный способ переноса данных в рамках приложения или между приложения на рабочем столе Windows. Дебют этой функциональности состоялся в Windows 3.1 с File Manager, а затем она была распространена на все приложения, поддерживающие OLE 2, например на Microsoft Office. Когда вышла Windows 8, Microsoft ввела новый тип Windows-приложений — приложения Windows Store, которые были рассчитаны на планшеты и всегда отображались в полноэкранном режиме. Поскольку в любой момент на экране было видно только одно приложение, перетаскивание между приложениями потеряло смысл, и были разработаны другие способы обмена данными, такие как Share Charm. Однако в Windows 10 приложения на настольных ПК вновь выполняются в оконном режиме, а значит, на экране отображается несколько окон, и поэтому функциональность перетаскивания вернулась на сцену в виде Universal Windows App API с добавлением новых средств, улучшающих пользовательскую среду (UX).
Drag and Drop question type tutorial
Концепции перетаскивания
Перетаскивание дает возможность пользователю перемещать данные между приложениями или внутри одного приложения с помощью стандартного жеста («нажать-удерживать-сдвигать» пальцем или «нажать-сдвигать» мышью или пером).
Источник, которым является приложение или область, где инициирован жест перетаскивания, предоставляет данные для перемещения, заполняя объект пакета данных. Этот объект может содержать данные как в стандартных форматах, включая текст, RTF, HTML, битовые карты, элементы хранилища, так и в собственных форматах. Источник также указывает вид поддерживаемых им операций: копирование, перемещение или связывание. Когда указатель освобождается, происходит отпускание объекта (drop). Мишень, которой является приложение или область под указателем, обрабатывает этот пакет данных и возвращает тип выполненной ею операции.
При операции «drag-and-drop» UI перетаскивания обеспечивает визуальное обозначение типа этой операции. Визуальная обратная связь изначально предоставляется источником, но может изменяться мишенями, по которым движется указатель.
Современные операции «drag-and-drop» доступны на настольных компьютерах, планшетах и смартфонах. Они позволяют перемещать данные между любыми видами приложений или внутри них, включая традиционные Windows-приложения, хотя в этой статье основное внимание уделяется XAML API для современных операций «drag-and-drop».
Реализация перетаскивания
Источник и мишень играют разные роли. В приложении могут быть UI-компоненты, которые выступают только в роли источников, только в роли мишеней или и тех, и других одновременно, например как в приложении-примере Photo Booth (рис. 1).
How to Add Drag and Drop in React with React Beautiful DnD
Рис. 1. Источники и мишени
The photomontage is a drag source which can be dropped as an image in Wordpad and other apps | Фотомонтаж — это источник, который можно перетащить как изображение в Wordpad и другие приложения |
Each image becomes a drag source when it contains an image | Каждое изображение становится источником, когда оно содержит некое изображение |
Each image placeholder is a drop target accepting images | Любое место для изображения является мишенью, принимающей изображения |
The photomontage is a drop target accepting text to add a caption | Фотомонтаж является мишенью, которая принимает текст, добавляемый как надпись |
Операция «drag-and-drop» полностью управляется пользовательским вводом, поэтому ее реализация основывается почти всегда на событиях, как показано на рис. 2.
Рис. 2. События «drag-and-drop»
DragStarting event is raised on source | В источнике генерируется событие DragStarting |
DragEnter event is raised on Target #1 | В мишени 1 генерируется событие DragEnter |
DragOver events are raised on Target #1 | В мишени 1 генерируются события DragOver |
DragLeave event is raised on Target #1 | В мишени 1 генерируется событие DragLeave |
DragEnter event is raised on Target #2 | В мишени 2 генерируется событие DragEnter |
DragOver events are raised on Target #2 | В мишени 2 генерируются события DragOver |
Drop event is raised on Target #2 | В мишени 2 генерируется событие Drop |
Source | Источник |
Target #1 | Мишень 1 |
Target #2 | Мишень 2 |
DropCompleted event is raised on source | В источнике генерируется событие DropCompleted |
Left button is pressed | Левая кнопка нажата |
Pointer is moved while button is still pressed | Указатель перемещается при удерживаемой левой кнопке |
Button is released when on a target | Кнопка отпускается, когда указатель попадает на мишень |
Реализация источника В Windows 8.1 элемент управления ListView может быть источником операции «drag-and-drop» внутри приложения, если его свойство CanDragItems установлено в true:
» ItemTemplate=»» />
Приложение может обрабатывать событие DragItemsStarting в источнике. Это по-прежнему поддерживается в Windows 10 с добавлением события DragItemsCompleted, которое не требовалось приложениям в Windows 8.1, где мишень и источник должны были относиться к одному и тому же процессу.
Основной источник в современной функциональности «drag-and-drop» — это UIElement, который открывает доступ ко всем средствам современной функциональности «drag-and-drop» и находится в центре внимания этой статьи.
Один из способов сделать UIElement перетаскиваемым — установить его свойство CanDrag в true. Это можно сделать в разметке или в отделенном коде (codebehind). Инфраструктура XAML обрабатывает распознавание жестов и генерирует событие DragStarting, сообщая о начале операции перетаскивания. Приложение должно сконфигурировать DataPackage, заполнив его содержимое и указав, какие операции поддерживаются.
Приложение-источник может помещать в DataPackage данные разных форматов, которые сделают его совместимым с большим количеством мишеней (рис. 3). Поддерживаемые операции определяются в типе DataPackageOperation и могут быть Copy, Move, Link или любой их комбинацией.
Рис. 3. Обработка DragStarting и заполнение DataPackage
private void DropGrid_DragStarting(UIElement sender, DragStartingEventArgs args) < if (Picture == null) < args.Cancel = true; >else if (_fileSource != null) < args.Data.RequestedOperation = DataPackageOperation.Copy | DataPackageOperation.Move; args.Data.SetStorageItems(new IStorageItem[] < _fileSource >); . >
Вы можете отменять операцию Drag в обработчике событий, установив свойство Cancel параметра DragStartingEventArgs. Так, в нашем приложении-примере в месте для размещения изображений операция Drag начнется, только если на него перетаскивают изображение или файл.
Обработчик DragStartingEvent также является местом, где приложение-источник может настраивать UI перетаскивания, но об этом позже.
В некоторых случаях приложению может потребоваться использовать особый жест для запуска операции «drag-and-drop» или разрешить перетаскивание какого-то элемента управления, который при обычном взаимодействии препятствует использованию стандартного жеста перетаскивания, например TextBox, реагирующий на события, связанные с движением указателя вниз, изменением выделенной в нем области. В таких случаях приложение может реализовать распознавание собственного жеста, а затем инициировать операцию «drag-and-drop» вызовом метода StartDragAsync. Заметьте, что этот метод ожидает передачи идентификатора указателя (pointer identifier) и поэтому вы не можете начать операцию «drag-and-drop» с помощью нестандартных устройств вроде датчика Kinect. После вызова StartDragAsync остальная часть операции «drag-and-drop» следует тому же шаблону, что и при использовании CanDrag=True, включая событие DragStarting.
Как только пользователь освобождает указатель, операция «drag-and-drop» завершается, и источник уведомляется через событие DropCompleted, содержащее DataPackageOperation, возвращаемое мишенью, на которой пользователь отпустил указатель, или DataPackageOperation.None, если указатель был отпущен на мишени, которая не принимает данные, или если была нажата кнопка отмена (Cancel):
private void DropGrid_DropCompleted(UIElement sender, DropCompletedEventArgs args) < if (args.DropResult == DataPackageOperation.Move) < // Перемещение означает, что мы должны очистить изображение Picture = null; _bitmapSource = null; _fileSource = null; >>
StartDragAsync возвращает IAsyncOperation; приложение-источник может обработать завершение операции либо ожидая на IAsyncOperation, либо обрабатывая событие DropCompleted. Программная отмена после события DragStarting возможна через интерфейс IAsyncOperation, но может озадачить пользователя.
Заметьте: хотя операции «drag-and-drop» как ListView, так и UIElement реализуются одними и теми же системными сервисами и полностью совместимы, они генерируют разные события на стороне источника. То есть, если у ListView свойство CanDragItems установлено в true, генерируются лишь DragItemsStarting и DragItemsCompleted. DragStarting и DropCompleted — события, связанные со свойством CanDrag в UIElement.
Реализация мишени Любой UIElement может быть мишенью при условии, что его свойство AllowDrop установлено в true. В ходе операции «drag-and-drop» в мишени могут генерироваться следующие события: DragEnter, DragOver, DragLeave и Drop. Эти события уже есть в Windows 8.1, но класс DragEventArgs был расширен в Windows 10, чтобы обеспечить приложениям доступ ко всем средствам современной поддержки «drag-and-drop».
При обработке события «drag-and-drop» приложение-мишень должно сначала проверить содержимое DataPackage через свойство DataView аргумента события; в большинстве случаев проверка на наличие типа данных достаточна, и это можно делать синхронно. В некоторых случаях, например при передаче файлов, приложению может понадобиться проверка типа доступных файлов до приема или игнорирования DataPackage. Эта операция асинхронная (данный шаблон будет подробно изложен далее в этой статье).
Определив, можно ли обработать эти данные, мишень должна установить свойство AcceptedOperation экземпляра DragEventArgs, чтобы дать возможность системе обеспечить пользователя корректную обратную связь.
Заметьте: если приложение возвращает DataTransferOperation.None из обработчика событий (или операция не принимается источником), перетаскивание будет безрезультатным, даже когда пользователь отпустит указатель прямо над мишенью; вместо этого будет сгенерировано событие DragLeave.
Приложение может обрабатывать либо DragEnter, либо DragOver; AcceptedOperation, возвращаемое DragEnter, сохраняется, если DragOver не обрабатывается. Когда DragEnter вызывается лишь раз, его следует предпочесть в сравнении с DragOver по причинам большей производительности. Однако в случае вложенных мишеней необходимо возвращать корректное значение из DragOver, чтобы родительская мишень могла переопределить его (задание Handled в true предотвращает передачу события вверх к родителю). В приложении-примере в каждом месте для изображений делаются проверки на изображения в DataPackage, и событие направляется родительской сетке, только если изображения нет; это позволяет сетке принимать Text, даже если физически он помещается на место для изображения (рис. 4).
Рис. 4. Обработка DragEnter и проверка DataPackage
private async void DropGrid_DragEnter(object sender, DragEventArgs e) < if (!App.IsSource(e.DataView)) < bool forceMove = ((e.Modifiers if (e.DataView.Contains(StandardDataFormats.Bitmap)) < _acceptData = true; e.AcceptedOperation = (forceMove ? DataPackageOperation.Move : DataPackageOperation.Copy); e.DragUIOverride.Caption = «Drop the image to show it in this area»; e.Handled = true; >else if (e.DataView.Contains( StandardDataFormats.StorageItems)) < // Уведомляем XAML, что окончание DropGrid_Enter не // означает, что мы завершили обработку события var def = e.GetDeferral(); _acceptData = false; e.AcceptedOperation = DataPackageOperation.None; var items = await e.DataView.GetStorageItemsAsync(); foreach (var item in items) < try < StorageFile file = item as StorageFile; if ((file != null) file.ContentType.StartsWith(«image/»)) < _acceptData = true; e.AcceptedOperation = (forceMove ? DataPackageOperation.Move : DataPackageOperation.Copy); e.DragUIOverride.Caption = «Drop the image to show it in this area»; break; >> catch (Exception ex) < Debug.WriteLine(ex.Message); >> e.Handled = true; // Уведомляем XAML, что теперь мы закончили def.Complete(); > > // Иначе мы позволяем событию подниматься // к возможной родительской мишени >
Более сложные концепции
Настройка визуальной обратной связи В OLE 2 операция «drag-and-drop» обеспечивала обратную связь лишь изменение курсора мыши согласно ответу мишени на событие DragOver. Современный функционал «drag-and-drop» допускает более сложные сценарии, например более богатую визуальную обратную связь с пользователем. UI перетаскивания состоит из трех частей: визуального контента, глифа и надписи (caption).
Визуальный контент представляет перетаскиваемые данные. Это могут быть перетаскиваемый UIElement (если источником является XAML-приложение), стандартный значок, выбранный системой на основе содержимого DataPackage или пользовательское изображение, заданное приложением.
Глиф отражает тип операции, принятой мишенью. Он может принимать одну из четырех форм в соответствии со значением типа DataPackageOperation. Глиф нельзя настраивать из приложения, но можно скрывать.
Надпись (caption) — это описание, предоставляемое мишенью. В зависимости от приложения-мишени операция Copy может быть, например, добавлением песни в список воспроизведения, загрузкой файла в OneDrive или обычным копированием файла. Надпись дает более точную обратную связь, чем глиф, и играет роль, очень похожую на всплывающую подсказку.
В табл. 1 показано, как источник и мишень могут настраивать эти части. Когда указатель не находится над мишенью, UI перетаскивания выглядит именно так, как его сконфигурировал источник. Когда указатель оказывается над мишенью, некоторые части визуального интерфейса могут быть переопределены мишенью. Как только указатель покидает мишень, все переопределения очищаются.
Табл. 1. Настройки, доступные источнику и мишени
Источник: learn.microsoft.com
Проектируем Drag and Drop: лучшие UX-практики (часть 1)
Drag and drop (или перетаскивание) — сложное, но популярное взаимодействие, которое встречается в разных продуктах — от графических и текстовых редакторов до систем управления проектами.
Сегодня речь пойдет об одной из самых сложных и интересных задач взаимодействия. С чем же мы имеем дело? При проектировании drag and drop (функции перетаскивания) необходимо учитывать практически все аспекты дизайна взаимодействия.
Эффективно донести до пользователя, что взаимодействие вообще доступно, — лишь часть проблемы. Объект должен перемещаться, важна живая обратная связь, и нужно принять множество решений, чтобы функция «воспринималась» правильным образом. А для индикации состояния необходимо учитывать больше нюансов, чем обычно.
На разных устройствах все может пойти не так, как надо, а для работы над ошибками неизменно требуется вдумчивое сотрудничество дизайнеров и разработчиков.
Как ни крути , перед нами стоит нешуточная задачка.
Что нужно учесть при проектировании функции перетаскивания
Когда вы приступаете к проектированию перетаскивания, вашей команде нужно учесть множество вещей.
Общие вопросы
- Какими способами мы можем решить эту проблему (в целом)?
- Нужна ли пользователям функция перетаскивания?
- Какие устройства будут задействованы?
- Является ли перетаскивание подходящим решением для нашей проблемы взаимодействия? Соответствует ли оно знакомым пользователям шаблонам? Или это что-то новое для них?
Технические вопросы
- Должны ли мы использовать конкретный JS-фреймворк? Или можем свободно создать свой дизайн?
- Достаточно ли пропускной способности сети для реализации такого взаимодействия?
- Нужно ли такое взаимодействие на мобильных устройствах?
- Можем ли мы протестировать фреймворк с фейковыми данными?
Вопросы про взаимодействие
- Необходимы ли здесь какие-либо ограничения? Ограничение движения в том или ином направлении?
- Хотим ли мы реализовать полностью гибкое или поэтапное поведение?
- Есть ли какая-то ключевая логика информирования о том, что разрешено и что не разрешено перетаскивать? Если да, то какова эта логика?
- Насколько точной и чувствительной должна быть эта функция?
Анатомия drag and drop
UI-компоненты, задействованные в перетаскивании, довольно просты, сложность заключается в работе с состояниями, обратной связью и логикой взаимодействия.
Элемент списка — то, что перетаскивается, обычно это элемент списка, карточка или другой объект (для простоты мы будем называть их просто “элемент” или “элемент списка” до конца этой статьи).
Источник — контейнер с элементами, которые вы собираетесь перетаскивать.
Цель перетаскивания — она может быть статичной (находится в одном месте постоянно) или динамичной. Ее предназначение состоит в том, чтобы давать обратную связь о перетаскиваемых элементах в режиме реального времени (своего рода пустое состояние), и она заслуживает времени и внимания, особенно если вы руководствуетесь какой-то определенной логикой и хотите её показать.
Типы перетаскивания
UI/UX с перетаскиванием довольно разнообразен, и его используют во многих контекстах. Все они подразумевают разные потребности и требования к взаимодействию — поэтому существует множество паттернов перетаскивания.
Это особенно характерно для корпоративного программного обеспечения, где сценарии использования могут быть весьма разнообразными, поэтому UX-паттерны могут становиться все сложнее и сложнее. Основные сценарии: перемещение элементов, изменение порядка элементов в списке, изменение размера контейнера и пользовательские взаимодействия.
1. Перемещение
Это «классический» пример drag and drop, когда мы предполагаем, что существует статичная и четко определенная зона перетаскивания — большую часть времени мы будем обращаться именно к этому примеру, поскольку он является наиболее сложным и запутанным.
Примеры распространенных шаблонов перемещения:
2. Изменение порядка элементов
Этот сценарий использования очень распространен во всех операционных системах и на всех платформах — это изменение порядка элементов в списке или карточке. Здесь цель перетаскивания динамически отображается на экране и показывает точное место, где окажется элемент после того, как вы его отпустите.
Примеры распространенных шаблонов изменения порядка элементов:
3. Изменение размера
Изменение размера — когда пользователи могут перетаскивать контейнер на экране в пределах доступного пространства (оно ограничено в большинстве SaaS-продуктов). У этого взаимодействия есть несколько уникальных аспектов.
- Здесь нет четкой цели перетаскивания, но действие «отпускания» выбранного элемента все еще присутствует.
- Подтверждающая обратная связь менее выражена, потому что обратной связью здесь по сути является само изменение размера объекта.
Распространенные шаблоны изменения размера:
4. Пользовательские взаимодействия
Этот сценарий характерен для корпоративных продуктов, которые допускают сложные взаимодействия с перетаскиванием, когда пользователи могут манипулировать элементами интерфейса практически без ограничений.
Возьмем, к примеру, рисование прямоугольника в Figma (или любом другом ПО для проектирования). Пользователи могут менять размер объекта, сохраняя соотношение сторон (удерживая Shift), изменять высоту и ширину, и даже перетаскивать опорные точки (кликнув дважды несколько раз), чтобы превратить прямоугольник в любую другую форму.
Это уже совсем другой, продвинутый уровень взаимодействия, который мы не будем затрагивать в этой статье.
Во многих дизайн-программах вы можете создавать объекты или изменять их посредством перетаскивания — ниже пример Figma:
Этапы и состояния
Чтобы проиллюстрировать каждый этап взаимодействия, мы будем использовать в качестве примера интерфейс приложения, которое позволяет перетаскивать элементы списка (один или несколько) в определенную область.
1. Состояние по умолчанию
В этом состоянии элементы списка (и их контейнер) статичны, а цель перетаскивания находится в состоянии по умолчанию.
Триггер: завершение загрузки страницы
Цель перетаскивания: состояние по умолчанию
Важно добавить в целевую зону правильный UX-текст. В состоянии по умолчанию здесь может располагаться два типа надписей: основной текст и дополнительный. Основной — это самая важная информация, он отвечает на вопрос: что делать? В дополнительном же многие корпоративные или SaaS-продукты разъясняют особенности взаимодействия, которые необходимо учитывать.
Если в основе вашего продукта лежит сложная логика, разместите тут ссылку на вашу базу знаний, которая поможет людям лучше понять свои действия
Когда это возможно, мы призываем сообщать аудитории об ошибках заранее, а не постфактум, это эвристика юзабилити (предотвращение ошибок и информирование о состоянии системы).
Состояние наведения (на экранах компьютеров)
Триггер: наведение курсора мыши на область перетаскивания
Захват области перетаскивания
Триггер: клик мышкой или касание пальцем на мобильных устройствах
По завершении первого этапа вы захватили элемент и готовы начать его перемещение. Поехали!
2. В движении
“Захват» прошел успешно, теперь элемент(ы) перемещается(ются) в пространстве вместе с курсором — это шаг перед началом активации цели перетаскивания.
Триггер: движение курсора или пальца
Переход при множественном выборе (необязательно)
Если выбрано несколько элементов, возможен еще один переход, который показывает пользователям, что перетаскивание началось — отображение количества выбранных элементов.
☝️ Контейнер-источник. Не забудьте про контейнер элемента списка или «источник» перетаскиваемых элементов.
Есть несколько вариантов его поведения. Можно показать, что элементы «покинули» свое место, или применить к ним определенное состояние — показать, что они находятся в процессе перехода, но сохранить их в статичном положении.
3. Целевая зона в пределах досягаемости
Целевая зона сигнализирует, что элементы находятся в пределах досягаемости — визуальная обратная связь может усиливаться по мере их приближения.
Триггер: целевая зона оказывается в пределах досягаемости
Визуальная обратная связь целевой зоны
Это хорошая возможность как предоставить визуальную обратную связь, так и использовать UX-копирайтинг, чтобы рассказать пользователям о том, что происходит и что нужно делать.
Более подробная визуальная обратная связь может быть необходима, когда имеется несколько целевых зон, и люди должны различать их, чтобы движение было точным. Такая обратная связь может быть поэтапной — первоначальная, чтобы убедить пользователей, что они на правильном пути и т.д.
Целевые зоны могут быть динамическими и меняться с учетом координат элемента: возьмем пример иерархической структуры, в которой вы выстраиваете отношения «родитель-потомок» между элементами.
Предупреждения об ошибках в зоне досягаемости
Триггер: логика допустимых значений нарушена или «будет нарушена», если пользователь отпустит элементы — мы всегда советуем предупреждать людей, а не сообщать об ошибках постфактум.
Продолжение в следующей части
Источник: www.uprock.ru
Drag and Drop в дизайне сайтов и приложений
Drag and Drop используется практически во всех интерфейсах — сортировка писем в почте, перемещения карточек Trello или перетаскивание вкладок в Chrome.
Публикация: 14.03.2018 Kirill Lipovoy
Drag and Drop взаимодействие часто пропускается или остается незамеченным. Иногда они случаются так естественно, что вы даже этого не понимаете. Но если вы внимательно посмотрите и сравните эти три примера, каждый из них демонстрирует очень разные стандарты UX в области перетаскивания.
Нет ничего плохого в том, что эти интерфейсы имеют разные стандарты UX. Например, возможно, Трелло решил наклонить карточки, во время перетаскивания, потому что это поведение соответствует их языку дизайна. Но там, где проблема заключается в том, что нет четких стандартов UX для перетаскивания в общий интерфейс.
Вы можете столкнуться с примерами, когда перетаскивание чего-то в одной части интерфейса является совершенно другим опытом. Чтобы проиллюстрировать это, давайте посмотрим на доступную библиотеку drag and drop Salesforce. Он демонстрирует пять моделей для перетаскивания, каждая из которых представляет собой совершенно другой.
В то время как много замечаний в отношении доступности, к сожалению, в этих пяти моделях мало согласованности дизайна. В каждом из пяти шаблонов используется другой курсор, а в качестве инструментов перетаскивания используются три разных значка:
Значок три строки указывает на перетаскиваемый элемент?
Или это значок с тремя точками? Какой из курсоров показывает, что можно перетащить элемент? Лучше не использовать разные элементы обозначающие одно действие в одном проекте. В системе проектирования компоненты должны выглядеть и сочетаться друг с другом как единое целое. Подобным образом, взаимодействие с перетаскиванием должно выглядеть и согласовано со всеми компонентами в интерфейсе.
Примеры использования drag and drop в дизайне
- Изменения порядка в списке элементов;
- Переупорядочение столбцов в таблице;
- Переупорядочение строк в таблице;
- Реорганизация и слияние карточек;
Для пользовательских интерфейсов с большим объемом данных, перетаскивание имеет решающее значение для того, чтобы пользователи могли организовать сложные и большие объемы данных.
Создание библиотеки доступности
Если вы работаете в команде, вам необходимо начать с создания библиотеки доступности, это может помочь вам начать думать о том, как обращаться с шаблонами перетаскивания для вашей дизайн-системы.
1. Выбор цвета
Для обозначения drag and drop взаимодействия избегайте цветов, которые уже имеют значение в вашем интерфейсе. Так вы сможете использовать пользовательский опыт, и, когда пользователи будут сталкиваться с выбранным цветом, они смогут ожидать именно этого взаимодействия.
2. Стили состояний
Установите стили для разных состояний перетаскиваемого элемента. Укажите, какое именно визуальное воздействие получит элемент во время его перетаскивания, после его перетаскивания и т. д.
Например, когда элемент перетаскивается, он будет иметь следующие стили:
Добавление тонкой тени для тени создает впечатление, что элемент фактически снимается со страницы.
Светлое, прежнее положение элемента во время перетаскивания. Это действует как небольшое напоминание пользователям, где элемент был ранее.
3. Системные курсоры
Используйте системные курсоры, чтобы указать, когда элемент перетаскивается. Это кажется незначительным, но это значительно улучшит возможность обнаружения перетаскиваемых элементов.
Для Mac мы используем перчатку. Курсор захвата отображается при наведении, когда элемент перетаскивается. Для областей, где элемент нельзя перетащить, мы использовали курсор указывающий на недоступность.
Для Windows мы используем курсор перемещения (крестообразные стрелки). Опять же, для областей, где элемент нельзя перетащить, мы использовали курсор указывающий на недоступность.
4. Перетаскивыемае цели
Установите шаблоны для целевых объектов, которые являются допустимыми областями, где можно перетаскивать элементы. Подобно стилям состояний выше, явно выделяйте какие цели доступны.
Будет полезно казать место перемещения, например добавив круг в конец позиции, чтобы было проще отличить позицию от обычной линии или границы.
Резюме
Эти стандарты помогут создать базовую основу для подключения Drag and Drop элементов в интерфейсе, но есть много других способов стандартизации перетаскивания компонентов.
Источник: cloudmakers.ru