Drag preview разные стили
Интересует вопрос поведения Drag preview у draggable элементов, в частности, какие свойства влияют на изменения его отображения?
Когда-то превью прозрачное
Но при изменении некоторых условий (высота, ширина, масштаб окна) превью становится менее прозрачным (см. желтый).
Причем, это происходит в лайв режиме. Изменил соотношение сторон браузера, изменилось поведение. Я попробовал несколько вариантов назначения высоты и ширины: фиксированные, в зависимости от высоты/ширины окна (vh/vw), но так или иначе, при изменении высоты/ширины или масштаба окна браузер, какой-то из элементов изменяет свое отображение превью.
Возможно, кто-нибудь подскажет правила, по которым происходит изменение стиля?
Не забывайте пример во все окно разворачивать.
let dp200 = document.getElementById("drag-preview-200");
let dp500 = document.getElementById("drag-preview-500");
let preview200 = document.createElement('img');
let preview500 = document.createElement('img');
preview200.setAttribute('src', 'https://via.placeholder.com/200.png/09f');
preview500.setAttribute('src', 'https://via.placeholder.com/500.png/3f1');
dp200.addEventListener("dragstart", (event)=>{
event.dataTransfer.setDragImage(preview200, 150, 150);
console.log();
})
dp500.addEventListener("dragstart", (event)=>{
event.dataTransfer.setDragImage(preview500, 150, 150);
console.log();
})
.drag-px-small{
width: 300px;
height: 300px;
background: lightblue;
}
.drag-px-big {
width: 400px;
height: 400px;
background: lightgreen;
}
.drag-vw{
width: 25vw;
height: 25vw;
background: red;
}
.drag-vh {
width: 25vh;
height: 25vh;
background: pink;
}
.drag-vwvh {
width: 25vw;
height: 25vh;
background: tan;
}
.drag-preview {
width: 200px;
height: 200px;
}
#drag-preview-200 {
background: purple;
}
#drag-preview-500 {
background: brown;
}
<div class="drag-px-small" draggable="true">
px: 300x300
</div>
<div class="drag-px-big" draggable="true">
px: 400x400
</div>
<div class="drag-vw" draggable="true">
vw: 25x25
</div>
<div class="drag-vh" draggable="true">
vh: 25x25
</div>
<div class="drag-vwvh" draggable="true">
vw/vh: 25x25
</div>
<div class="drag-preview" id="drag-preview-200" draggable="true">
Small custom drag preview / dataTransfer.setDragImage
</div>
<div class="drag-preview" id="drag-preview-500" draggable="true">
Big custom drag preview / dataTransfer.setDragImage
</div>
Примечание
В ходе обсуждения подтвердился факт того, что на разных ОС и разных браузерах поведение dragPreview различается.
- Windows. Firefox. Поведение в FF отличается от поведения в Chrome и Opera, в частности, FF начинает добавлять прозрачный градиент при одинаковых условиях, голубой кубик 300х300 пикселей, из исходного примера выше, в FF при 100% масштабе имеет градиент с прозрачностью, в то время как в Opera и Chrome на 300х300 кубе градиента в dragPreview нет.
- Linux. Firefox. Градиент отсутствует полностью. В случае, если элемент драга занимает большУю площадь окна, FF уменьшает размер dragpreview (см. картинку ниже). При назначении
setDragImagedragPreview появляется без градиента и без размера для больших элементов.
ОС:Linux, Браузер: Firefox, Размер элемента: 400x400xp, масштаб 150%

ОС:Linux, Браузер: Firefox, Размер setDragImage: 500x500xp, масштаб 100%. При увеличении масштаба окна браузера поведение не изменяется. Увеличение масштаба окна браузера влияет на увеличение масштаба dragPreview.

ОС:Linux, Браузер: Firefox, Размер setDragImage: 500x500xp, масштаб 170%.

Linux. Opera. Градиент отсутствует полностью. DragPreview всегда отображается по размерам исходного элемента. При увеличении масштаба окна отображение не изменяется.
Linux. Opera. Масштабирование окна не применяется к масштабированию картинки, назначенной через setDragImage (см пример ниже)
ОС:Linux, Браузер: Opera, Размер элемента 400х400px, масштаб 175%. Масштабирование окна браузера влияет на размер dragPreview

ОС:Linux, Браузер: Opera, Размер setDragImage 500х500px, масштаб 175%. Масштабирование окна браузера НЕ влияет на dragPreview.

Вывод
Судя по всему, поведение dragPreview реализуется в каждом браузере для каждой операционной системы по разному. Как следствие, независимо от того, используется setDragImage или нет, реальной возможности контроля отображения dragPreview, при использовании html draggable, нет, и во всех браузерах/операционных системах dragPreview будет отображаться с некоторыми отличиями.
Тем не менее, некоторые из результатов обсуждения могут быть кому-либо интересны и полезны.
Ответы (2 шт):
Согласно официальным рекомендациям HTML5.2 от W3C отображение картинок является опциональной функцией:
The following information, used to generate the UI feedback during the drag:
- User-agent-defined default feedback information, known as the drag data store default feedback.
- Optionally, a bitmap image and the coordinate of a point within that image, known as the drag data store bitmap and drag data store hot spot coordinate.
К примеру, в Хроме и Сафари на MacOS нет градиента прозрачности не зависимо от размеров.
Градиент, который присутствует на Windows, отчасти показывает координаты точки за которую и происходит перетаскивание.
Немного информации также даёт раздел Drag operations на MDN:
Setting the drag feedback image
When a drag occurs, a translucent image is generated from the drag target (the element the "dragstart" event is fired at)...
Так или иначе полагаться на это поведение не стоит, поскольку оно не стандартизировано. В случаях, когда это поведение имеет значение стандарт предусматривает использование DataTransfer.setDragImage
dataTransfer.setDragImage(element, x, y)Uses the given element to update the drag feedback, replacing any previously specified feedback.
То же рекомендует и MDN:
...you can use setDragImage() to specify a custom drag feedback image.
UPD. Такое поведение есть только на Windows. Все картинки размер которых больше 240 пикселей по любой отрисовываются с градиентом. В 2013 году это значение было 300 пикселей.
Действительно, к сожалению, картинки поставленные через setDragImage, тоже подвержены этому. В этом случае стоит использовать javascript для манипуляции перетаскиваемыми объектами.
Единственный вариант, который приходит в голову - это способ отрисовки draggable-элементов GUI операционной системы. По-умолчанию определённые разрешения отрисовывает как в первом случае, с эффектом фокусирования цвета на курсоре при перемещении. Однако если элемент не соответствует каким-либо пропорциям относительно экрана, подобная отрисовка становится либо плохо выглядящей, либо требующей больше ресурсов. Поэтому элемент становится просто прозрачным.

