Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/Fil/d3-inertia
Dragging stuff with inertia
https://github.com/Fil/d3-inertia
d3 d3-drag d3-geo earth globe quaternion rotation
Last synced: 5 days ago
JSON representation
Dragging stuff with inertia
- Host: GitHub
- URL: https://github.com/Fil/d3-inertia
- Owner: Fil
- License: other
- Created: 2017-11-06T14:05:12.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2023-07-18T20:28:09.000Z (over 1 year ago)
- Last Synced: 2024-07-04T23:53:59.793Z (4 months ago)
- Topics: d3, d3-drag, d3-geo, earth, globe, quaternion, rotation
- Language: JavaScript
- Homepage:
- Size: 5.93 MB
- Stars: 61
- Watchers: 6
- Forks: 5
- Open Issues: 11
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
- awesome-d3 - d3-inertia - An extension to d3-drag that continues the mouse movement with some inertia (Maps)
- awesome-d3 - d3-inertia - An extension to d3-drag that continues the mouse movement with some inertia (Maps)
- awesome-frontend-gis - d3-inertia - An extension to d3-drag that continues the mouse movement with some inertia. (👨‍💻 JavaScript Libraries / Mapping)
- awesome-d3 - d3-inertia - An extension to d3-drag that continues the mouse movement with some inertia (Maps)
README
# Inertia
An extension to [d3-drag](https://github.com/d3/d3-drag) that continues the mouse movement with some inertia (by default, 5 seconds).
The `inertia` object exposes a `position` and a `velocity`, that correspond to the mouse coordinates relative to the target of the `d3.drag` method. During the drag gesture, the position just follows the mouse, and the velocity accumulates the movement. When the drag gesture ends, the `render()` method is called repeatedly with a tweening argument `t` that goes from 0 to 1. It is up to you to know what to do with these vectors.
The most simple case is: `currentPosition = last position + t * velocity`.
This [example](https://bl.ocks.org/Fil/a034e32156b7b25ee9054c1bc50dc0ca) demonstrates a more creative use of the parameters. As you can see, `d3.inertia` can be used on its own, but you will need to manage quite a few parameters.
(TODO: a helping function for common use cases).
# Dragging the globe
[](https://bl.ocks.org/Fil/f48de8e9207799017093a169031adb02/)
*[Canvas example + code](https://bl.ocks.org/Fil/f48de8e9207799017093a169031adb02/)*The naĂŻve method to rotate a globe uses `mouse.x` and `mouse.y` as proxies for longitude and latitude. It works when the rotation is small, but try to put the globe "upside-down" and suddenly moving the mouse to the left rotates the globe to the right, and vice versa.
The correct solution is to track the spherical coordinates of the point that is under the mouse, and apply a rotation to the globe that will move the initial point to the current mouse position. Computing that rotation involves quaternions.
This method, introduced by [Jason Davies](https://www.jasondavies.com/maps/rotate/) and Mike Bostock, is called [versor dragging](https://bl.ocks.org/mbostock/7ea1dde508cec6d2d95306f92642bc42).
**d3-inertia** packages this method.
Include the scripts in your page with
``````
Then, define a `render()` function that redraws the globe, and call:
```
var inertia = d3.geoInertiaDrag(canvas, function() { render(); }, [projection], [opt]);
```[](https://visionscarto.net/empreintes-d-eclipses)
*[SVG example](https://visionscarto.net/empreintes-d-eclipses) + [code](https://bl.ocks.org/Fil/63366253a5d2f00640c15b096c29a38c)**canvas* is the target container (it can also be *svg*)
*projection* is an object with two methods:
- *projection.rotate([r])* gets and sets the rotation.
- *projection.invert([x,y])* transforms screen coordinates into spherical coordinates *lambda, phi*; most [projections](https://github.com/d3/d3-geo-projection) have an exact invert, but for the few which do not, this doesn't have to be very accurate to give an “almost correct” movement.
If a projection is defined globally, and not specified in the function call, the plugin will use it.
*opt* is an array of options, which can include:
- *start*, *move*, *end*: callback functions on the corresponding events (*end* is invoked only if conditions for inertia are met)
- *stop*, *finish*: extra callback functions invoked if the conditions for inertia are not met and after it finishes respectively
- *time*: reference time for the inertia (in ms, default 5000)
- *hold*: threshold time beteen the final *move* and *end* events after which inertia will be cancelled (in ms, default 100)
# Credits
Thanks to [Jason Davies](https://www.jasondavies.com/), [Mike Bostock](https://bl.ocks.org/mbostock/) and [Widi Harsojo](https://github.com/earthjs/earthjs).
The quaternion & versor functions are taken from the [versor](https://github.com/Fil/versor) package.