vaadin / flow

Vaadin Flow is a Java framework binding Vaadin web components to Java. This is part of Vaadin 10+.
Apache License 2.0
619 stars 167 forks source link

Custom drag image for drag source #6793

Closed pleku closed 1 month ago

pleku commented 5 years ago

When creating a draggable component, I want to be able to specify a custom drag image to it, so that I can perfect the end user experience (for those browsers that support customizing it)

Split out from #3978

Not sure if it would be enough to just provide API on server side to set the Element which would need be attached to the UI and then will be used as the drag image element instead of the element that is made draggable. That would at least make it possible to have one element as the designated "drag handle" but then have the "whole component" as the drag image.

Another option would be to have API that allows specifying an image file to be set as the drag image.

enver-haase commented 3 months ago

When I asked:

https://vaadin.com/docs/latest/flow/create-ui/dnd/drag-source "HTML 5 has an API for setting a custom drag image element, but it isn’t yet available from the server-side API, because it works unreliably in some browsers (Edge / Safari)" https://caniuse.com/?search=setDragImage What is the later and "more correct" statement?

A colleague told me:

That statement is no longer correct. The support is missing in IE11 so there was good reason not to implement it for V14, but things has progressed since then. The feature is doable in context of V23 and V24. And it is not particularly worksome to implement either.

mshabarov commented 2 months ago

Added to Vaadin 24.6 backlog that is planned in December 2024.

mshabarov commented 1 month ago

Acceptance Criteria

Implementation/API details and suggestions: to set an image, one can call a new method in DragStartEvent:

public class DraggableItem extends Div
        implements DragSource<DraggableItem> {

    public DraggableItem() {
        addDragStartListener(event -> {
            Image image = new Image("images/flower.jpeg", "A flower");
            event.setDragImage(image);
        });
    }
} 

then the image resource is registered as a StreamResource or stored as a src/alt pair, transferred to browser and thrown forward to dndConnector.js and available in __dragstartListener, where Flow can run event.dataTransfer.setDragImage(img).

See this demo for insights https://codepen.io/webgeeker/full/KBzrxE/

tltv commented 1 month ago

Instead of adding setDragImage to DragStartEvent in the server side API I suggest to add it to DragSource.

This way developer can set the drag image before dragstart event without having any delays in rendering the image. Otherwise if client-server round trip takes too long, browser would just fallback to default image.

mshabarov commented 1 month ago

@tltv fair suggestion, let's stick with this design.

vaadin-bot commented 1 month ago

This ticket/PR has been released with Vaadin 24.6.0.alpha1 and is also targeting the upcoming stable 24.6.0 version.

johannest commented 1 week ago

Tested (V24.6.0.alpha2) with the following source code:

Div dragBox = new Div("Drag box");
DragSource<Div> dragSource = DragSource.configure(dragBox);
dragSource.setDraggable(true);
dragSource.setDragImage(new Div("Drag Source Image"));
add(dragBox);

Chrome (130 arm64): only the default(?) drag image is shown:

image

Safari (18.1): Dragging does not activate, but unexpected text selection happens:

image

FF (132.0.1 aarch64): No drag image is show