-
-
Notifications
You must be signed in to change notification settings - Fork 5.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix of fix of scaling bug, also changed Draggable to use getMousePosition #5997
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,6 @@ import * as Browser from '../core/Browser'; | |
import * as DomEvent from './DomEvent'; | ||
import * as DomUtil from './DomUtil'; | ||
import * as Util from '../core/Util'; | ||
import {Point} from '../geometry/Point'; | ||
|
||
/* | ||
* @class Draggable | ||
|
@@ -44,7 +43,8 @@ export var Draggable = Evented.extend({ | |
// @option clickTolerance: Number = 3 | ||
// The max number of pixels a user can shift the mouse pointer during a click | ||
// for it to be considered a valid click (as opposed to a mouse drag). | ||
clickTolerance: 3 | ||
clickTolerance: 3, | ||
mapContainer: undefined | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. does it mean that mapContainer is required for every single usage of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cherniavskii not required, but optional. if you haven't specified it nothing shall be broken. But i must give container instance to getMousePosition, it must have access to it. haven't other idea how to have that access in better way. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As @yarsky-tgz figured out, in order to have With the current PR state, this new Thinking about it further, this shows that
…but what about the drag area, which is potentially affected by a CSS scale? Therefore adding a new parameter or option is necessary in order to be able to take into account the container CSS scale. Maybe a more generic There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. …or maybe " No reference to "map" is needed, since There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All right, there should be an interesting workaround that would enable getting rid of the What we need is to retrieve the CSS scale which applies on the dragged element (i.e. This works fine for the map, but for a draggable Marker, the difficulty is that the function getNonNullSizeParentNode(element) {
do {
element = element.parentNode;
} while ((!element.offsetWidth || !element.offsetHeight) && element !== document.body)
return element;
} Example: https://plnkr.co/edit/HYyDssl2F2rpvwmDYuW6?p=preview |
||
}, | ||
|
||
// @constructor L.Draggable(el: HTMLElement, dragHandle?: HTMLElement, preventOutline?: Boolean, options?: Draggable options) | ||
|
@@ -114,7 +114,7 @@ export var Draggable = Evented.extend({ | |
|
||
var first = e.touches ? e.touches[0] : e; | ||
|
||
this._startPoint = new Point(first.clientX, first.clientY); | ||
this._startPoint = DomEvent.getMousePosition(first, this.options.mapContainer, true); | ||
|
||
DomEvent.on(document, MOVE[e.type], this._onMove, this); | ||
DomEvent.on(document, END[e.type], this._onUp, this); | ||
|
@@ -134,7 +134,7 @@ export var Draggable = Evented.extend({ | |
} | ||
|
||
var first = (e.touches && e.touches.length === 1 ? e.touches[0] : e), | ||
newPoint = new Point(first.clientX, first.clientY), | ||
newPoint = DomEvent.getMousePosition(first, this.options.mapContainer, true), | ||
offset = newPoint.subtract(this._startPoint); | ||
|
||
if (!offset.x && !offset.y) { return; } | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it possible to leave
getMousePosition
less complex? E.g. move scaled point calculation to a separate util function, which will be used bygetMousePosition
and insideDraggable
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think that shall make it more complex. Any calling of function has some overhead. Ant that's mouse event. Any single function call shall make slower response to user.
Now
getMousePosition
looks as only method to get right coordinates of mouse event. It's used now everywhere at Leaflet. I think that's right behavior.Third argument i've added is not simple for understanding and even for description... but it's needed in that situation I set it to true. We can try to avoid it... but i think it's better for now to add it. Ternary operator is very atomic and fast.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what I meant under "complexity".
Right now
getMousePosition
is easy to reason about. Withabs
argument it's much harder to do it.Same with
mapContainer
option inDraggable
. Right nowDraggable
doesn't care about map container at all - and in most cases it shouldn't.Personally, I would rather not add this complexity to Leaflet core, unless there's simpler / more readable solution for that.
It's a corner case and 99% of users do not need this. So I'd stick with current, less complex solution.
From the other hand, I understand that you need this to work and I really appreciate your efforts!
But maybe it's possible to pull it out into a plugin (maybe with some additional work on Leaflet side to make it possible)? If I can help you with that - just let me know :)
That being said, it's just my personal opinion, and maybe other core contributors have other thoughts.
cc @mourner @perliedman @IvanSanchez @ghybs @yohanboniface
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cherniavskii I agree this makes a core function a bit more complex, but pulling this fix out of the core to a plugin sounds a bit weird to me.
Is passing
mapContainer
to allDraggable
s that bad? If the container's attributes are needed to calculate the position ofDraggable
, I don't see any other way than passing the info down there. One option would be to only pass the offset x and y in numbers, but those would need to be updated when the container changes.Would it be possible to name and document the
abs
better?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi,
It seems to me here that the
abs
parameter is unnecessary: the only 2 places where this PR uses it are inDraggable
's_onDown
and_onMove
listeners. The results are then subtracted to compute the move offset (extent).So we have: (pseudo-code)
Since it is an extremely corner case that
mapContainer
changes position during the drag operation, thenmove_rect === start_rect
and we have:Furthermore, the description for
getMousePosition
sounds pretty clear to me that it is relative to the container:The only case where including the start and in-movement offsets in the computation would be interesting is when we expect the map container to be shifted while dragging. In that case, the drag could indeed continue smoothly, even though the mouse / finger no longer holds the same spot… But I think we could expect the user to already feel a discrepancy (when the map container moves), and wonder why he/she is no longer holding the same spot.
Without including this
abs
offset, on the contrary the map "jumps" back to where the mouse / finger was holding, which IMHO makes the user experience less disruptive.Demo: https://plnkr.co/edit/poTcoZRUYKBRxvWnHoZp?p=preview