Get the Drop coordinates (x / y) relative to the DropTarget in Vaadin 23 via build-in drag and drop feature - vaadin

I'm using the Drag Source and Drag Target features from https://vaadin.com/docs/latest/create-ui/dnd (Vaadin 23).
I want to realize a moving operation on a map. This means I got points on a map (as custom Vaadin components) and ...
when dragging them the source position should be hidden (this could be done via point.addDragStartListener(...); as far as I can see)
when dropping them I need to know the drop position relative to the map as x/y coordinates (e.g. clientX and clientY).
As result, the component should be moved from the dragging start position to the drop position. It's parent div has the style attribute position: relative; and the component itself has an absolute position with top and left coordinates in px, e.g.: position: absolute; top: 183px; left: 254px;. With the drop event I have to update the top and left values in the css styling and therefore I need the coordinates of the drop position.
I can't see a suitable method in dropTarget.addDropListener(...); to get the coordinates. Do you have any hint / code samples for me? Thanks!

I found a solution:
dropTarget.getElement().addEventListener("drop", this::onDrop)
.addEventData("event.offsetX")
.addEventData("event.offsetY");
And an apropriate method onDrop:
private void onDrop(DomEvent event) {
JsonObject eventData = event.getEventData();
double x = eventData.getNumber("event.offsetX");
double y = eventData.getNumber("event.offsetY");
[do some stuff...]
}

Related

set individual Area inside Map in MapKit

I am trying to set an individual Frame which defines the visible area of the Map.
Currently all the annotations are shown with mapView.showAnnotations but they aligned to fit in the whole iPad screen view. So they are partially hidden by Floating UI Elements (Green). Also the center of the screen is aligned to be the center of the iPad screen.
What I try to accomplish: I want something like a defined rectangle inside the Map to be the only regarded area in the map. But the Map itself (blue) shall still be shown behind the UI Elements.
I thought it would be able to accomplish this by using setVisibleMapRect but when I ever I try to use this it does not take any effect. Is setVisibleMapRectactually the needed method to solve this problem?
The actual answer I found out later is defining
mapView.layoutMargins = UIEdgeInsets(top: X, left: X, bottom: X, right: X)
so the map wont use the space defined by the margin
For others finding this via google, looking for a solution with MapKit JS:
In MapKit JS, the property to modify is called padding:
var map = new mapkit.Map("map");
// When showing the translucent side panel, shift the map content a little to the right.
if (window.innerWidth >= 768) {
map.padding = new mapkit.Padding({top: 0, left: 600, bottom: 0, right: 0})
}
Documentation: mapkit.Padding

trying to create a bounding box by click and drag in a web component

I am dealing with event handlers, and getting the start and end position of a mouse.
That way i can create a selection box.
I start by on mousedown, i store the current position: new Point(event.target.clientLeft, event.target.clientTop); which seems to work for that location when i set the selection div accordingly.
The next step is where everything seems wrong. While in the mousemove event, I am trying to get the coordinates of the mouse do i can use the difference to define the Height and Width of the bounding box. It seems that everything is off by the coordinates of the web component i had created.
How should I go about this?
I have been dabbling with the event more, trying to get the position of the mouse, but i think what happens is that my start point is in reference to the webcomponent I created, and not the absolute position.
Has anyone else figured out how to do this correctly, because I have been setting things as absolute, but not correctly rendering.
As a side note, if i could subtract the absolute position of the webcomponent this is in, i think it should render the height and width correctly.
You might have an easier time using global position information rather than target-relative position. You can get the global position point from a MouseEvent directly with event.screen.
since a PolymerElement will use HtmlElements, you will have access to a full suite of functions built into the application. For example:
var top = selectedHtml.getBoundingClientRect().top - getBoundingClientRect().top + selectedHtml.clientHeight;
var left = selectedHtml.getBoundingClientRect().left - getBoundingClientRect().left + selectedHtml.clientWidth;
Point coord = new Point(left,top);
then you can just determine the distance from that point to get your width/height:
var top = selectedHtml.getBoundingClientRect().top - getBoundingClientRect().top + selectedHtml.clientHeight;
var left = selectedHtml.getBoundingClientRect().left - getBoundingClientRect().left + selectedHtml.clientWidth;
var h = top - coord.y;
var w = left - coord.x;
and then apply it to your Div.
_item.style.top = top;
_item.style.left = left;
_item.style.width = w;
_item.style.height = h;

Dynamically move highstock navigator

I'm having some trouble with highstock. I've figured out how to shuffle around other series via the y axis object, however I'm looking to dynamically add more series, and shift the navigator down after I add additional series, along with increasing the height of the containing div as more series are added.
My current approach to moving the navigator is to update the top property of the y axis assigned to the navigator, as informed by this answer:
Move the Highstock navigator position
function moveNavigator(){
chart.navigator.yAxis.update({
height : 50,
top: 202
});
}
http://jsfiddle.net/dwhcj3e7/2/
If my understanding were correct this fiddle should move the navigator from on top of the chart to the bottom of the chart. Is there a way to accomplish this behavior without completely making a new chart object?
Use chart.update() method (available from version 5) and update navigator's top property.
chart.update({
navigator: {
top: 202,
height: 50
}
});
example: http://jsfiddle.net/dwhcj3e7/3/

Restrict a smooth drag in draggable jquery-ui

I am dragging a div within a main div with respect to y-axis.
$("#childdiv").draggable({axis:'y'});
It drags smoothly in y axis. But I want a drag with jerks..
For Example : When I start drag .. the draggable component directly moves to 50px and if I again drag next jump will be to 100px next drag will directly jump to 150px . It should be simillar like sortable with placeholder but using draggable.
You can use the grid option to get this:
Snaps the dragging helper to a grid, every x and y pixels. The
array must be of the form [ x, y ].
eg.
$("#childdiv").draggable({
axis:'y',
grid: [0, 50]
});
Here's an example fiddle: https://jsfiddle.net/g1epL4ea/

How to make css3 scaled elements draggable

I've noticed that the CSS3 scale attribute does really bad things to jquery ui, specifically to sortable. The problem is that the mouse still needs to move as much as if the elements were not scaled. Check out this jsfiddle example.
Does anybody have thoughts on how to fix this? Is it possible to change the speed that the mouse moves? I'm going to look into the html5 native drag and drop next, and try to write my own sortable function.
UPDATE:
Jquery ui draggable works ok with CSS3 scaled elements, here is a fiddle for it.
It turns out the real answer does not require writing special move functions. Jquery ui sortable can be used as long as the items being sorted have been wrapped in a div of the appropriate size with overflow hidden. Check this jsfiddle for an example.
The problem was that I had forced the scaled divs to be close to one another using a negative margin. Then when I started to drag an item it was taking up the wrong amount of space. With the scaled item wrapped in a non-scaled div everything works as expected.
I don't have a solution for working with jquery ui but I do have a solution for working with Raphael and by extension other svg objects.
First, using chrome or firefox, go drag the dots around in this jsfiddle. Be sure to drag both dots and to use the slider at the bottom to change the scale of the box. The slider has a default scale range of .4 to 1.2. In Chrome the slider is actually a slider but in Firefox it shows up as a textbox. If you are using firefox enter values that are 100 x the scale, i.e. 70 => 0.7.
What you should have just experienced is that the black dot tracks with the mouse regardless of the scale and the red dot only tracks when the scale is 1.0.
The reason for this is the two dots are using different 'onMove' functions. The black dot moves according to 1/scale while the red dot moves normally.
var moveCorrected = function (dx, dy) {
// move will be called with dx and dy
this.attr({
cx: this.ox + (1/scale)*dx,
cy: this.oy + (1/scale)*dy
});
}
var move = function (dx, dy) {
// move will be called with dx and dy
this.attr({
cx: this.ox + dx,
cy: this.oy + dy
});
}
So, in answer to my original question. You can't (and shouldn't) be able to change how the mouse moves, that is clearly user defined behavior, but you can change the move function of the object being moved to track with the mouse.

Resources