Comparing version 1.2.5 to 2.0.0-rc.1
@@ -1,2 +0,2 @@ | ||
// https://d3js.org/d3-drag/ v1.2.5 Copyright 2019 Mike Bostock | ||
// https://d3js.org/d3-drag/ v2.0.0-rc.1 Copyright 2020 Mike Bostock | ||
(function (global, factory) { | ||
@@ -8,9 +8,9 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-dispatch'), require('d3-selection')) : | ||
function nopropagation() { | ||
d3Selection.event.stopImmediatePropagation(); | ||
function nopropagation(event) { | ||
event.stopImmediatePropagation(); | ||
} | ||
function noevent() { | ||
d3Selection.event.preventDefault(); | ||
d3Selection.event.stopImmediatePropagation(); | ||
function noevent(event) { | ||
event.preventDefault(); | ||
event.stopImmediatePropagation(); | ||
} | ||
@@ -44,19 +44,26 @@ | ||
function constant(x) { | ||
return function() { | ||
return x; | ||
}; | ||
} | ||
var constant = x => () => x; | ||
function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch) { | ||
this.target = target; | ||
this.type = type; | ||
this.subject = subject; | ||
this.identifier = id; | ||
this.active = active; | ||
this.x = x; | ||
this.y = y; | ||
this.dx = dx; | ||
this.dy = dy; | ||
this._ = dispatch; | ||
function DragEvent(type, { | ||
sourceEvent, | ||
subject, | ||
target, | ||
identifier, | ||
active, | ||
x, y, dx, dy, | ||
dispatch | ||
}) { | ||
Object.defineProperties(this, { | ||
type: {value: type, enumerable: true, configurable: true}, | ||
sourceEvent: {value: sourceEvent, enumerable: true, configurable: true}, | ||
subject: {value: subject, enumerable: true, configurable: true}, | ||
target: {value: target, enumerable: true, configurable: true}, | ||
identifier: {value: identifier, enumerable: true, configurable: true}, | ||
active: {value: active, enumerable: true, configurable: true}, | ||
x: {value: x, enumerable: true, configurable: true}, | ||
y: {value: y, enumerable: true, configurable: true}, | ||
dx: {value: dx, enumerable: true, configurable: true}, | ||
dy: {value: dy, enumerable: true, configurable: true}, | ||
_: {value: dispatch} | ||
}); | ||
} | ||
@@ -70,4 +77,4 @@ | ||
// Ignore right-click, since that should open the context menu. | ||
function defaultFilter() { | ||
return !d3Selection.event.ctrlKey && !d3Selection.event.button; | ||
function defaultFilter(event) { | ||
return !event.ctrlKey && !event.button; | ||
} | ||
@@ -79,4 +86,4 @@ | ||
function defaultSubject(d) { | ||
return d == null ? {x: d3Selection.event.x, y: d3Selection.event.y} : d; | ||
function defaultSubject(event, d) { | ||
return d == null ? {x: event.x, y: event.y} : d; | ||
} | ||
@@ -113,41 +120,41 @@ | ||
function mousedowned() { | ||
if (touchending || !filter.apply(this, arguments)) return; | ||
var gesture = beforestart("mouse", container.apply(this, arguments), d3Selection.mouse, this, arguments); | ||
function mousedowned(event, d) { | ||
if (touchending || !filter.call(this, event, d)) return; | ||
var gesture = beforestart(this, container.call(this, event, d), event, d, "mouse"); | ||
if (!gesture) return; | ||
d3Selection.select(d3Selection.event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true); | ||
nodrag(d3Selection.event.view); | ||
nopropagation(); | ||
d3Selection.select(event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true); | ||
nodrag(event.view); | ||
nopropagation(event); | ||
mousemoving = false; | ||
mousedownx = d3Selection.event.clientX; | ||
mousedowny = d3Selection.event.clientY; | ||
gesture("start"); | ||
mousedownx = event.clientX; | ||
mousedowny = event.clientY; | ||
gesture("start", event); | ||
} | ||
function mousemoved() { | ||
noevent(); | ||
function mousemoved(event) { | ||
noevent(event); | ||
if (!mousemoving) { | ||
var dx = d3Selection.event.clientX - mousedownx, dy = d3Selection.event.clientY - mousedowny; | ||
var dx = event.clientX - mousedownx, dy = event.clientY - mousedowny; | ||
mousemoving = dx * dx + dy * dy > clickDistance2; | ||
} | ||
gestures.mouse("drag"); | ||
gestures.mouse("drag", event); | ||
} | ||
function mouseupped() { | ||
d3Selection.select(d3Selection.event.view).on("mousemove.drag mouseup.drag", null); | ||
yesdrag(d3Selection.event.view, mousemoving); | ||
noevent(); | ||
gestures.mouse("end"); | ||
function mouseupped(event) { | ||
d3Selection.select(event.view).on("mousemove.drag mouseup.drag", null); | ||
yesdrag(event.view, mousemoving); | ||
noevent(event); | ||
gestures.mouse("end", event); | ||
} | ||
function touchstarted() { | ||
if (!filter.apply(this, arguments)) return; | ||
var touches = d3Selection.event.changedTouches, | ||
c = container.apply(this, arguments), | ||
function touchstarted(event, d) { | ||
if (!filter.call(this, event, d)) return; | ||
var touches = event.changedTouches, | ||
c = container.call(this, event, d), | ||
n = touches.length, i, gesture; | ||
for (i = 0; i < n; ++i) { | ||
if (gesture = beforestart(touches[i].identifier, c, d3Selection.touch, this, arguments)) { | ||
nopropagation(); | ||
gesture("start"); | ||
if (gesture = beforestart(this, c, event, d, touches[i].identifier, touches[i])) { | ||
nopropagation(event); | ||
gesture("start", event, touches[i]); | ||
} | ||
@@ -157,4 +164,4 @@ } | ||
function touchmoved() { | ||
var touches = d3Selection.event.changedTouches, | ||
function touchmoved(event) { | ||
var touches = event.changedTouches, | ||
n = touches.length, i, gesture; | ||
@@ -164,4 +171,4 @@ | ||
if (gesture = gestures[touches[i].identifier]) { | ||
noevent(); | ||
gesture("drag"); | ||
noevent(event); | ||
gesture("drag", event, touches[i]); | ||
} | ||
@@ -171,4 +178,4 @@ } | ||
function touchended() { | ||
var touches = d3Selection.event.changedTouches, | ||
function touchended(event) { | ||
var touches = event.changedTouches, | ||
n = touches.length, i, gesture; | ||
@@ -180,4 +187,4 @@ | ||
if (gesture = gestures[touches[i].identifier]) { | ||
nopropagation(); | ||
gesture("end"); | ||
nopropagation(event); | ||
gesture("end", event, touches[i]); | ||
} | ||
@@ -187,21 +194,46 @@ } | ||
function beforestart(id, container, point, that, args) { | ||
var p = point(container, id), s, dx, dy, | ||
sublisteners = listeners.copy(); | ||
function beforestart(that, container, event, d, identifier, touch) { | ||
var dispatch = listeners.copy(), | ||
p = d3Selection.pointer(touch || event, container), dx, dy, | ||
s; | ||
if (!d3Selection.customEvent(new DragEvent(drag, "beforestart", s, id, active, p[0], p[1], 0, 0, sublisteners), function() { | ||
if ((d3Selection.event.subject = s = subject.apply(that, args)) == null) return false; | ||
dx = s.x - p[0] || 0; | ||
dy = s.y - p[1] || 0; | ||
return true; | ||
})) return; | ||
if ((s = subject.call(that, new DragEvent("beforestart", { | ||
sourceEvent: event, | ||
target: drag, | ||
identifier, | ||
active, | ||
x: p[0], | ||
y: p[1], | ||
dx: 0, | ||
dy: 0, | ||
dispatch | ||
}), d)) == null) return; | ||
return function gesture(type) { | ||
dx = s.x - p[0] || 0; | ||
dy = s.y - p[1] || 0; | ||
return function gesture(type, event, touch) { | ||
var p0 = p, n; | ||
switch (type) { | ||
case "start": gestures[id] = gesture, n = active++; break; | ||
case "end": delete gestures[id], --active; // nobreak | ||
case "drag": p = point(container, id), n = active; break; | ||
case "start": gestures[identifier] = gesture, n = active++; break; | ||
case "end": delete gestures[identifier], --active; // nobreak | ||
case "drag": p = d3Selection.pointer(touch || event, container), n = active; break; | ||
} | ||
d3Selection.customEvent(new DragEvent(drag, type, s, id, n, p[0] + dx, p[1] + dy, p[0] - p0[0], p[1] - p0[1], sublisteners), sublisteners.apply, sublisteners, [type, that, args]); | ||
dispatch.call( | ||
type, | ||
that, | ||
new DragEvent(type, { | ||
sourceEvent: event, | ||
subject: s, | ||
target: drag, | ||
identifier, | ||
active: n, | ||
x: p[0] + dx, | ||
y: p[1] + dy, | ||
dx: p[0] - p0[0], | ||
dy: p[1] - p0[1], | ||
dispatch | ||
}), | ||
d | ||
); | ||
}; | ||
@@ -208,0 +240,0 @@ } |
@@ -1,2 +0,2 @@ | ||
// https://d3js.org/d3-drag/ v1.2.5 Copyright 2019 Mike Bostock | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("d3-dispatch"),require("d3-selection")):"function"==typeof define&&define.amd?define(["exports","d3-dispatch","d3-selection"],e):e((t=t||self).d3=t.d3||{},t.d3,t.d3)}(this,function(t,e,n){"use strict";function o(){n.event.stopImmediatePropagation()}function i(){n.event.preventDefault(),n.event.stopImmediatePropagation()}function r(t){var e=t.document.documentElement,o=n.select(t).on("dragstart.drag",i,!0);"onselectstart"in e?o.on("selectstart.drag",i,!0):(e.__noselect=e.style.MozUserSelect,e.style.MozUserSelect="none")}function c(t,e){var o=t.document.documentElement,r=n.select(t).on("dragstart.drag",null);e&&(r.on("click.drag",i,!0),setTimeout(function(){r.on("click.drag",null)},0)),"onselectstart"in o?r.on("selectstart.drag",null):(o.style.MozUserSelect=o.__noselect,delete o.__noselect)}function u(t){return function(){return t}}function s(t,e,n,o,i,r,c,u,s,a){this.target=t,this.type=e,this.subject=n,this.identifier=o,this.active=i,this.x=r,this.y=c,this.dx=u,this.dy=s,this._=a}function a(){return!n.event.ctrlKey&&!n.event.button}function l(){return this.parentNode}function d(t){return null==t?{x:n.event.x,y:n.event.y}:t}function f(){return navigator.maxTouchPoints||"ontouchstart"in this}s.prototype.on=function(){var t=this._.on.apply(this._,arguments);return t===this._?this:t},t.drag=function(){var t,h,v,p,g=a,m=l,y=d,b=f,_={},w=e.dispatch("start","drag","end"),x=0,T=0;function j(t){t.on("mousedown.drag",k).filter(b).on("touchstart.drag",P).on("touchmove.drag",q).on("touchend.drag touchcancel.drag",z).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function k(){if(!p&&g.apply(this,arguments)){var e=D("mouse",m.apply(this,arguments),n.mouse,this,arguments);e&&(n.select(n.event.view).on("mousemove.drag",E,!0).on("mouseup.drag",M,!0),r(n.event.view),o(),v=!1,t=n.event.clientX,h=n.event.clientY,e("start"))}}function E(){if(i(),!v){var e=n.event.clientX-t,o=n.event.clientY-h;v=e*e+o*o>T}_.mouse("drag")}function M(){n.select(n.event.view).on("mousemove.drag mouseup.drag",null),c(n.event.view,v),i(),_.mouse("end")}function P(){if(g.apply(this,arguments)){var t,e,i=n.event.changedTouches,r=m.apply(this,arguments),c=i.length;for(t=0;t<c;++t)(e=D(i[t].identifier,r,n.touch,this,arguments))&&(o(),e("start"))}}function q(){var t,e,o=n.event.changedTouches,r=o.length;for(t=0;t<r;++t)(e=_[o[t].identifier])&&(i(),e("drag"))}function z(){var t,e,i=n.event.changedTouches,r=i.length;for(p&&clearTimeout(p),p=setTimeout(function(){p=null},500),t=0;t<r;++t)(e=_[i[t].identifier])&&(o(),e("end"))}function D(t,e,o,i,r){var c,u,a,l=o(e,t),d=w.copy();if(n.customEvent(new s(j,"beforestart",c,t,x,l[0],l[1],0,0,d),function(){return null!=(n.event.subject=c=y.apply(i,r))&&(u=c.x-l[0]||0,a=c.y-l[1]||0,!0)}))return function f(h){var v,p=l;switch(h){case"start":_[t]=f,v=x++;break;case"end":delete _[t],--x;case"drag":l=o(e,t),v=x}n.customEvent(new s(j,h,c,t,v,l[0]+u,l[1]+a,l[0]-p[0],l[1]-p[1],d),d.apply,d,[h,i,r])}}return j.filter=function(t){return arguments.length?(g="function"==typeof t?t:u(!!t),j):g},j.container=function(t){return arguments.length?(m="function"==typeof t?t:u(t),j):m},j.subject=function(t){return arguments.length?(y="function"==typeof t?t:u(t),j):y},j.touchable=function(t){return arguments.length?(b="function"==typeof t?t:u(!!t),j):b},j.on=function(){var t=w.on.apply(w,arguments);return t===w?j:t},j.clickDistance=function(t){return arguments.length?(T=(t=+t)*t,j):Math.sqrt(T)},j},t.dragDisable=r,t.dragEnable=c,Object.defineProperty(t,"__esModule",{value:!0})}); | ||
// https://d3js.org/d3-drag/ v2.0.0-rc.1 Copyright 2020 Mike Bostock | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("d3-dispatch"),require("d3-selection")):"function"==typeof define&&define.amd?define(["exports","d3-dispatch","d3-selection"],t):t((e=e||self).d3=e.d3||{},e.d3,e.d3)}(this,function(e,t,n){"use strict";function o(e){e.stopImmediatePropagation()}function r(e){e.preventDefault(),e.stopImmediatePropagation()}function i(e){var t=e.document.documentElement,o=n.select(e).on("dragstart.drag",r,!0);"onselectstart"in t?o.on("selectstart.drag",r,!0):(t.__noselect=t.style.MozUserSelect,t.style.MozUserSelect="none")}function a(e,t){var o=e.document.documentElement,i=n.select(e).on("dragstart.drag",null);t&&(i.on("click.drag",r,!0),setTimeout(function(){i.on("click.drag",null)},0)),"onselectstart"in o?i.on("selectstart.drag",null):(o.style.MozUserSelect=o.__noselect,delete o.__noselect)}var u=e=>()=>e;function c(e,{sourceEvent:t,subject:n,target:o,identifier:r,active:i,x:a,y:u,dx:c,dy:l,dispatch:s}){Object.defineProperties(this,{type:{value:e,enumerable:!0,configurable:!0},sourceEvent:{value:t,enumerable:!0,configurable:!0},subject:{value:n,enumerable:!0,configurable:!0},target:{value:o,enumerable:!0,configurable:!0},identifier:{value:r,enumerable:!0,configurable:!0},active:{value:i,enumerable:!0,configurable:!0},x:{value:a,enumerable:!0,configurable:!0},y:{value:u,enumerable:!0,configurable:!0},dx:{value:c,enumerable:!0,configurable:!0},dy:{value:l,enumerable:!0,configurable:!0},_:{value:s}})}function l(e){return!e.ctrlKey&&!e.button}function s(){return this.parentNode}function d(e,t){return null==t?{x:e.x,y:e.y}:t}function f(){return navigator.maxTouchPoints||"ontouchstart"in this}c.prototype.on=function(){var e=this._.on.apply(this._,arguments);return e===this._?this:e},e.drag=function(){var e,g,h,v,m=l,p=s,b=d,y=f,x={},_=t.dispatch("start","drag","end"),w=0,j=0;function E(e){e.on("mousedown.drag",T).filter(y).on("touchstart.drag",P).on("touchmove.drag",q).on("touchend.drag touchcancel.drag",z).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function T(t,r){if(!v&&m.call(this,t,r)){var a=D(this,p.call(this,t,r),t,r,"mouse");a&&(n.select(t.view).on("mousemove.drag",k,!0).on("mouseup.drag",M,!0),i(t.view),o(t),h=!1,e=t.clientX,g=t.clientY,a("start",t))}}function k(t){if(r(t),!h){var n=t.clientX-e,o=t.clientY-g;h=n*n+o*o>j}x.mouse("drag",t)}function M(e){n.select(e.view).on("mousemove.drag mouseup.drag",null),a(e.view,h),r(e),x.mouse("end",e)}function P(e,t){if(m.call(this,e,t)){var n,r,i=e.changedTouches,a=p.call(this,e,t),u=i.length;for(n=0;n<u;++n)(r=D(this,a,e,t,i[n].identifier,i[n]))&&(o(e),r("start",e,i[n]))}}function q(e){var t,n,o=e.changedTouches,i=o.length;for(t=0;t<i;++t)(n=x[o[t].identifier])&&(r(e),n("drag",e,o[t]))}function z(e){var t,n,r=e.changedTouches,i=r.length;for(v&&clearTimeout(v),v=setTimeout(function(){v=null},500),t=0;t<i;++t)(n=x[r[t].identifier])&&(o(e),n("end",e,r[t]))}function D(e,t,o,r,i,a){var u,l,s,d=_.copy(),f=n.pointer(a||o,t);if(null!=(s=b.call(e,new c("beforestart",{sourceEvent:o,target:E,identifier:i,active:w,x:f[0],y:f[1],dx:0,dy:0,dispatch:d}),r)))return u=s.x-f[0]||0,l=s.y-f[1]||0,function o(a,g,h){var v,m=f;switch(a){case"start":x[i]=o,v=w++;break;case"end":delete x[i],--w;case"drag":f=n.pointer(h||g,t),v=w}d.call(a,e,new c(a,{sourceEvent:g,subject:s,target:E,identifier:i,active:v,x:f[0]+u,y:f[1]+l,dx:f[0]-m[0],dy:f[1]-m[1],dispatch:d}),r)}}return E.filter=function(e){return arguments.length?(m="function"==typeof e?e:u(!!e),E):m},E.container=function(e){return arguments.length?(p="function"==typeof e?e:u(e),E):p},E.subject=function(e){return arguments.length?(b="function"==typeof e?e:u(e),E):b},E.touchable=function(e){return arguments.length?(y="function"==typeof e?e:u(!!e),E):y},E.on=function(){var e=_.on.apply(_,arguments);return e===_?E:e},E.clickDistance=function(e){return arguments.length?(j=(e=+e)*e,E):Math.sqrt(j)},E},e.dragDisable=i,e.dragEnable=a,Object.defineProperty(e,"__esModule",{value:!0})}); |
{ | ||
"name": "d3-drag", | ||
"version": "1.2.5", | ||
"version": "2.0.0-rc.1", | ||
"publishConfig": { | ||
"tag": "next" | ||
}, | ||
"description": "Drag and drop SVG, HTML or Canvas using mouse or touch input.", | ||
@@ -37,4 +40,4 @@ "keywords": [ | ||
"dependencies": { | ||
"d3-dispatch": "1", | ||
"d3-selection": "1" | ||
"d3-dispatch": ">=2.0.0-rc.1", | ||
"d3-selection": ">=2.0.0-rc.3" | ||
}, | ||
@@ -41,0 +44,0 @@ "sideEffects": false, |
@@ -5,15 +5,15 @@ # d3-drag | ||
[<img alt="Force Dragging III" src="https://raw.githubusercontent.com/d3/d3-drag/master/img/force-graph.png" width="420" height="219">](http://bl.ocks.org/mbostock/ad70335eeef6d167bc36fd3c04378048)[<img alt="Force Dragging II" src="https://raw.githubusercontent.com/d3/d3-drag/master/img/force-collide.png" width="420" height="219">](http://bl.ocks.org/mbostock/2990a882e007f8384b04827617752738) | ||
[<img alt="Force-Directed Graph" src="https://raw.githubusercontent.com/d3/d3-drag/master/img/force-graph.png" width="420" height="219">](https://observablehq.com/@d3/force-directed-graph)[<img alt="Force Dragging II" src="https://raw.githubusercontent.com/d3/d3-drag/master/img/force-collide.png" width="420" height="219">](https://observablehq.com/d/c55a5839a5bb7c73) | ||
You can also use d3-drag to implement custom user interface elements, such as a slider. But the drag behavior isn’t just for moving elements around; there are a variety of ways to respond to a drag gesture. For example, you can use it to lasso elements in a scatterplot, or to paint lines on a canvas: | ||
[<img alt="Line Drawing" src="https://raw.githubusercontent.com/d3/d3-drag/master/img/drawing.png" width="420" height="219">](http://bl.ocks.org/mbostock/f705fc55e6f26df29354) | ||
[<img alt="Line Drawing" src="https://raw.githubusercontent.com/d3/d3-drag/master/img/drawing.png" width="420" height="219">](https://observablehq.com/@d3/draw-me) | ||
The drag behavior can be combined with other behaviors, such as [d3-zoom](https://github.com/d3/d3-zoom) for zooming. | ||
[<img alt="Drag & Zoom II" src="https://raw.githubusercontent.com/d3/d3-drag/master/img/dots.png" width="420" height="219">](http://bl.ocks.org/mbostock/3127661b6f13f9316be745e77fdfb084) | ||
[<img alt="Drag & Zoom II" src="https://raw.githubusercontent.com/d3/d3-drag/master/img/dots.png" width="420" height="219">](https://observablehq.com/@d3/drag-zoom) | ||
The drag behavior is agnostic about the DOM, so you can use it with SVG, HTML or even Canvas! And you can extend it with advanced selection techniques, such as a Voronoi overlay or a closest-target search: | ||
[<img alt="Circle Dragging IV" src="https://raw.githubusercontent.com/d3/d3-drag/master/img/voronoi.png" width="420" height="219">](http://bl.ocks.org/mbostock/ec10387f24c1fad2acac3bc11eb218a5)[<img alt="Circle Dragging II" src="https://raw.githubusercontent.com/d3/d3-drag/master/img/canvas.png" width="420" height="219">](http://bl.ocks.org/mbostock/c206c20294258c18832ff80d8fd395c3) | ||
[<img alt="Circle Dragging IV" src="https://raw.githubusercontent.com/d3/d3-drag/master/img/voronoi.png" width="420" height="219">](https://observablehq.com/@d3/circle-dragging-iii)[<img alt="Circle Dragging II" src="https://raw.githubusercontent.com/d3/d3-drag/master/img/canvas.png" width="420" height="219">](https://observablehq.com/@d3/circle-dragging-ii) | ||
@@ -24,8 +24,8 @@ Best of all, the drag behavior automatically unifies mouse and touch input, and avoids browser idiosyncrasies. When [Pointer Events](https://www.w3.org/TR/pointerevents/) are more widely available, the drag behavior will support those, too. | ||
If you use NPM, `npm install d3-drag`. Otherwise, download the [latest release](https://github.com/d3/d3-drag/releases/latest). You can also load directly from [d3js.org](https://d3js.org), either as a [standalone library](https://d3js.org/d3-drag.v1.min.js) or as part of [D3 4.0](https://github.com/d3/d3). AMD, CommonJS, and vanilla environments are supported. In vanilla, a `d3` global is exported: | ||
If you use NPM, `npm install d3-drag`. Otherwise, download the [latest release](https://github.com/d3/d3-drag/releases/latest). You can also load directly from [d3js.org](https://d3js.org), either as a [standalone library](https://d3js.org/d3-drag.v2.min.js) or as part of [D3](https://github.com/d3/d3). AMD, CommonJS, and vanilla environments are supported. In vanilla, a `d3` global is exported: | ||
```html | ||
<script src="https://d3js.org/d3-dispatch.v1.min.js"></script> | ||
<script src="https://d3js.org/d3-selection.v1.min.js"></script> | ||
<script src="https://d3js.org/d3-drag.v1.min.js"></script> | ||
<script src="https://d3js.org/d3-dispatch.v2.min.js"></script> | ||
<script src="https://d3js.org/d3-selection.v2.min.js"></script> | ||
<script src="https://d3js.org/d3-drag.v2.min.js"></script> | ||
<script> | ||
@@ -38,3 +38,3 @@ | ||
[Try d3-drag in your browser.](https://tonicdev.com/npm/d3-drag) | ||
[Try d3-drag in your browser.](https://observablehq.com/collection/@d3/d3-drag) | ||
@@ -66,7 +66,7 @@ ## API Reference | ||
<a href="#drag" name="drag">#</a> d3.<b>drag</b>() [<>](https://github.com/d3/d3-drag/blob/master/src/drag.js "Source") | ||
<a href="#drag" name="drag">#</a> d3.<b>drag</b>() · [Source](https://github.com/d3/d3-drag/blob/master/src/drag.js), [Examples](https://observablehq.com/collection/@d3/d3-drag) | ||
Creates a new drag behavior. The returned behavior, [*drag*](#_drag), is both an object and a function, and is typically applied to selected elements via [*selection*.call](https://github.com/d3/d3-selection#selection_call). | ||
<a href="#_drag" name="_drag">#</a> <i>drag</i>(<i>selection</i>) [<>](https://github.com/d3/d3-drag/blob/master/src/drag.js#L39 "Source") | ||
<a href="#_drag" name="_drag">#</a> <i>drag</i>(<i>selection</i>) · [Source](https://github.com/d3/d3-drag/blob/master/src/drag.js), [Examples](https://observablehq.com/collection/@d3/d3-drag) | ||
@@ -87,3 +87,3 @@ Applies this drag behavior to the specified [*selection*](https://github.com/d3/d3-selection). This function is typically not invoked directly, and is instead invoked via [*selection*.call](https://github.com/d3/d3-selection#selection_call). For example, to instantiate a drag behavior and apply it to a selection: | ||
<a href="#drag_container" name="drag_container">#</a> <i>drag</i>.<b>container</b>([<i>container</i>]) [<>](https://github.com/d3/d3-drag/blob/master/src/drag.js#L145 "Source") | ||
<a href="#drag_container" name="drag_container">#</a> <i>drag</i>.<b>container</b>([<i>container</i>]) · [Source](https://github.com/d3/d3-drag/blob/master/src/drag.js), [Examples](https://observablehq.com/collection/@d3/d3-drag) | ||
@@ -98,3 +98,3 @@ If *container* is specified, sets the container accessor to the specified object or function and returns the drag behavior. If *container* is not specified, returns the current container accessor, which defaults to: | ||
The *container* of a drag gesture determines the coordinate system of subsequent [drag events](#drag-events), affecting *event*.x and *event*.y. The element returned by the container accessor is subsequently passed to [d3.mouse](https://github.com/d3/d3-selection#mouse) or [d3.touch](https://github.com/d3/d3-selection#touch), as appropriate, to determine the local coordinates of the pointer. | ||
The *container* of a drag gesture determines the coordinate system of subsequent [drag events](#drag-events), affecting *event*.x and *event*.y. The element returned by the container accessor is subsequently passed to [d3.pointer](https://github.com/d3/d3-selection#pointer) to determine the local coordinates of the pointer. | ||
@@ -111,9 +111,10 @@ The default container accessor returns the parent node of the element in the originating selection (see [*drag*](#_drag)) that received the initiating input event. This is often appropriate when dragging SVG or HTML elements, since those elements are typically positioned relative to a parent. For dragging graphical elements with a Canvas, however, you may want to redefine the container as the initiating element itself: | ||
<a href="#drag_filter" name="drag_filter">#</a> <i>drag</i>.<b>filter</b>([<i>filter</i>]) [<>](https://github.com/d3/d3-drag/blob/master/src/drag.js#L141 "Source") | ||
If *filter* is specified, sets the filter to the specified function and returns the drag behavior. If *filter* is not specified, returns the current filter, which defaults to: | ||
<a href="#drag_filter" name="drag_filter">#</a> <i>drag</i>.<b>filter</b>([<i>filter</i>]) · [Source](https://github.com/d3/d3-drag/blob/master/src/drag.js), [Examples](https://observablehq.com/d/c55a5839a5bb7c73) | ||
If *filter* is specified, sets the event filter to the specified function and returns the drag behavior. If *filter* is not specified, returns the current filter, which defaults to: | ||
```js | ||
function filter() { | ||
return !d3.event.ctrlKey && !d3.event.button; | ||
function filter(event) { | ||
return !event.ctrlKey && !event.button; | ||
} | ||
@@ -124,3 +125,3 @@ ``` | ||
<a href="#drag_touchable" name="drag_touchable">#</a> <i>drag</i>.<b>touchable</b>([<i>touchable</i>]) [<>](https://github.com/d3/d3-drag/blob/master/src/drag.js#L153 "Source") | ||
<a href="#drag_touchable" name="drag_touchable">#</a> <i>drag</i>.<b>touchable</b>([<i>touchable</i>]) · [Source](https://github.com/d3/d3-drag/blob/master/src/drag.js), [Examples](https://observablehq.com/d/c55a5839a5bb7c73) | ||
@@ -137,3 +138,3 @@ If *touchable* is specified, sets the touch support detector to the specified function and returns the drag behavior. If *touchable* is not specified, returns the current touch support detector, which defaults to: | ||
<a href="#drag_subject" name="drag_subject">#</a> <i>drag</i>.<b>subject</b>([<i>subject</i>]) [<>](https://github.com/d3/d3-drag/blob/master/src/drag.js#L149 "Source") | ||
<a href="#drag_subject" name="drag_subject">#</a> <i>drag</i>.<b>subject</b>([<i>subject</i>]) · [Source](https://github.com/d3/d3-drag/blob/master/src/drag.js), [Examples](https://observablehq.com/collection/@d3/d3-drag) | ||
@@ -143,4 +144,4 @@ If *subject* is specified, sets the subject accessor to the specified object or function and returns the drag behavior. If *subject* is not specified, returns the current subject accessor, which defaults to: | ||
```js | ||
function subject(d) { | ||
return d == null ? {x: d3.event.x, y: d3.event.y} : d; | ||
function subject(event, d) { | ||
return d == null ? {x: event.x, y: event.y} : d; | ||
} | ||
@@ -154,3 +155,3 @@ ``` | ||
```js | ||
function subject() { | ||
function subject(event) { | ||
var n = circles.length, | ||
@@ -167,4 +168,4 @@ i, | ||
circle = circles[i]; | ||
dx = d3.event.x - circle.x; | ||
dy = d3.event.y - circle.y; | ||
dx = event.x - circle.x; | ||
dy = event.y - circle.y; | ||
d2 = dx * dx + dy * dy; | ||
@@ -178,15 +179,15 @@ if (d2 < s2) subject = circle, s2 = d2; | ||
(If necessary, the above can be accelerated using [*quadtree*.find](https://github.com/d3/d3-quadtree#quadtree_find).) | ||
(If necessary, the above can be accelerated using [*quadtree*.find](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_find), [*simulation*.find](https://github.com/d3/d3-force/blob/master/README.md#simulation_find) or [*delaunay*.find](https://github.com/d3/d3-delaunay/blob/master/README.md#delaunay_find).) | ||
The returned subject should be an object that exposes `x` and `y` properties, so that the relative position of the subject and the pointer can be preserved during the drag gesture. If the subject is null or undefined, no drag gesture is started for this pointer; however, other starting touches may yet start drag gestures. See also [*drag*.filter](#drag_filter). | ||
The subject of a drag gesture may not be changed after the gesture starts. The subject accessor is invoked with the same context and arguments as [*selection*.on](https://github.com/d3/d3-selection#selection_on) listeners: the current datum `d` and index `i`, with the `this` context as the current DOM element. During the evaluation of the subject accessor, [d3.event](https://github.com/d3/d3-selection#event) is a beforestart [drag event](#drag-events). Use *event*.sourceEvent to access the initiating input event and *event*.identifier to access the touch identifier. The *event*.x and *event*.y are relative to the [container](#drag_container), and are computed using [d3.mouse](https://github.com/d3/d3-selection#mouse) or [d3.touch](https://github.com/d3/d3-selection#touch) as appropriate. | ||
The subject of a drag gesture may not be changed after the gesture starts. The subject accessor is invoked with the same context and arguments as [*selection*.on](https://github.com/d3/d3-selection#selection_on) listeners: the current event (`event`) and datum `d`, with the `this` context as the current DOM element. During the evaluation of the subject accessor, `event` is a beforestart [drag event](#drag-events). Use *event*.sourceEvent to access the initiating input event and *event*.identifier to access the touch identifier. The *event*.x and *event*.y are relative to the [container](#drag_container), and are computed using [d3.pointer](https://github.com/d3/d3-selection#pointer). | ||
<a href="#drag_clickDistance" name="drag_clickDistance">#</a> <i>drag</i>.<b>clickDistance</b>([<i>distance</i>]) [<>](https://github.com/d3/d3-drag/blob/master/src/drag.js#L162 "Source") | ||
<a href="#drag_clickDistance" name="drag_clickDistance">#</a> <i>drag</i>.<b>clickDistance</b>([<i>distance</i>]) · [Source](https://github.com/d3/d3-drag/blob/master/src/drag.js) | ||
If *distance* is specified, sets the maximum distance that the mouse can move between mousedown and mouseup that will trigger a subsequent click event. If at any point between mousedown and mouseup the mouse is greater than or equal to *distance* from its position on mousedown, the click event following mouseup will be suppressed. If *distance* is not specified, returns the current distance threshold, which defaults to zero. The distance threshold is measured in client coordinates ([*event*.clientX](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/clientX) and [*event*.clientY](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/clientY)). | ||
<a href="#drag_on" name="drag_on">#</a> <i>drag</i>.<b>on</b>(<i>typenames</i>, [<i>listener</i>]) [<>](https://github.com/d3/d3-drag/blob/master/src/drag.js#L157 "Source") | ||
<a href="#drag_on" name="drag_on">#</a> <i>drag</i>.<b>on</b>(<i>typenames</i>, [<i>listener</i>]) · [Source](https://github.com/d3/d3-drag/blob/master/src/drag.js) | ||
If *listener* is specified, sets the event *listener* for the specified *typenames* and returns the drag behavior. If an event listener was already registered for the same type and name, the existing listener is removed before the new listener is added. If *listener* is null, removes the current event listeners for the specified *typenames*, if any. If *listener* is not specified, returns the first currently-assigned listener matching the specified *typenames*, if any. When a specified event is dispatched, each *listener* will be invoked with the same context and arguments as [*selection*.on](https://github.com/d3/d3-selection#selection_on) listeners: the current datum `d` and index `i`, with the `this` context as the current DOM element. | ||
If *listener* is specified, sets the event *listener* for the specified *typenames* and returns the drag behavior. If an event listener was already registered for the same type and name, the existing listener is removed before the new listener is added. If *listener* is null, removes the current event listeners for the specified *typenames*, if any. If *listener* is not specified, returns the first currently-assigned listener matching the specified *typenames*, if any. When a specified event is dispatched, each *listener* will be invoked with the same context and arguments as [*selection*.on](https://github.com/d3/d3-selection#selection_on) listeners: the current event (`event`) and datum `d`, with the `this` context as the current DOM element. | ||
@@ -203,7 +204,7 @@ The *typenames* is a string containing one or more *typename* separated by whitespace. Each *typename* is a *type*, optionally followed by a period (`.`) and a *name*, such as `drag.foo` and `drag.bar`; the name allows multiple listeners to be registered for the same *type*. The *type* must be one of the following: | ||
<a href="#dragDisable" name="dragDisable">#</a> d3.<b>dragDisable</b>(<i>window</i>) [<>](https://github.com/d3/d3-drag/blob/master/src/nodrag.js#L4 "Source") | ||
<a href="#dragDisable" name="dragDisable">#</a> d3.<b>dragDisable</b>(<i>window</i>) · [Source](https://github.com/d3/d3-drag/blob/master/src/nodrag.js) | ||
Prevents native drag-and-drop and text selection on the specified *window*. As an alternative to preventing the default action of mousedown events (see [#9](https://github.com/d3/d3-drag/issues/9)), this method prevents undesirable default actions following mousedown. In supported browsers, this means capturing dragstart and selectstart events, preventing the associated default actions, and immediately stopping their propagation. In browsers that do not support selection events, the user-select CSS property is set to none on the document element. This method is intended to be called on mousedown, followed by [d3.dragEnable](#dragEnable) on mouseup. | ||
<a href="#dragEnable" name="dragEnable">#</a> d3.<b>dragEnable</b>(<i>window</i>[, <i>noclick</i>]) [<>](https://github.com/d3/d3-drag/blob/master/src/nodrag.js#L15 "Source") | ||
<a href="#dragEnable" name="dragEnable">#</a> d3.<b>dragEnable</b>(<i>window</i>[, <i>noclick</i>]) · [Source](https://github.com/d3/d3-drag/blob/master/src/nodrag.js) | ||
@@ -214,3 +215,3 @@ Allows native drag-and-drop and text selection on the specified *window*; undoes the effect of [d3.dragDisable](#dragDisable). This method is intended to be called on mouseup, preceded by [d3.dragDisable](#dragDisable) on mousedown. If *noclick* is true, this method also temporarily suppresses click events. The suppression of click events expires after a zero-millisecond timeout, such that it only suppress the click event that would immediately follow the current mouseup event, if any. | ||
When a [drag event listener](#drag_on) is invoked, [d3.event](https://github.com/d3/d3-selection#event) is set to the current drag event. The *event* object exposes several fields: | ||
When a [drag event listener](#drag_on) is invoked, it receives the current drag event as its first argument. The *event* object exposes several fields: | ||
@@ -232,3 +233,3 @@ * `target` - the associated [drag behavior](#drag). | ||
<a href="#event_on" name="event_on">#</a> <i>event</i>.<b>on</b>(<i>typenames</i>, [<i>listener</i>]) [<>](https://github.com/d3/d3-drag/blob/master/src/event.js "Source") | ||
<a href="#event_on" name="event_on">#</a> <i>event</i>.<b>on</b>(<i>typenames</i>, [<i>listener</i>]) · [Source](https://github.com/d3/d3-drag/blob/master/src/event.js) | ||
@@ -238,9 +239,9 @@ Equivalent to [*drag*.on](#drag_on), but only applies to the current drag gesture. Before the drag gesture starts, a [copy](https://github.com/d3/d3-dispatch#dispatch_copy) of the current drag [event listeners](#drag_on) is made. This copy is bound to the current drag gesture and modified by *event*.on. This is useful for temporary listeners that only receive events for the current drag gesture. For example, this start event listener registers temporary drag and end event listeners as closures: | ||
```js | ||
function started() { | ||
function started(event) { | ||
var circle = d3.select(this).classed("dragging", true); | ||
d3.event.on("drag", dragged).on("end", ended); | ||
event.on("drag", dragged).on("end", ended); | ||
function dragged(d) { | ||
circle.raise().attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y); | ||
function dragged(event, d) { | ||
circle.raise().attr("cx", d.x = event.x).attr("cy", d.y = event.y); | ||
} | ||
@@ -247,0 +248,0 @@ |
@@ -1,5 +0,1 @@ | ||
export default function(x) { | ||
return function() { | ||
return x; | ||
}; | ||
} | ||
export default x => () => x; |
105
src/drag.js
import {dispatch} from "d3-dispatch"; | ||
import {event, customEvent, select, mouse, touch} from "d3-selection"; | ||
import {select, pointer} from "d3-selection"; | ||
import nodrag, {yesdrag} from "./nodrag.js"; | ||
@@ -9,3 +9,3 @@ import noevent, {nopropagation} from "./noevent.js"; | ||
// Ignore right-click, since that should open the context menu. | ||
function defaultFilter() { | ||
function defaultFilter(event) { | ||
return !event.ctrlKey && !event.button; | ||
@@ -18,3 +18,3 @@ } | ||
function defaultSubject(d) { | ||
function defaultSubject(event, d) { | ||
return d == null ? {x: event.x, y: event.y} : d; | ||
@@ -52,17 +52,17 @@ } | ||
function mousedowned() { | ||
if (touchending || !filter.apply(this, arguments)) return; | ||
var gesture = beforestart("mouse", container.apply(this, arguments), mouse, this, arguments); | ||
function mousedowned(event, d) { | ||
if (touchending || !filter.call(this, event, d)) return; | ||
var gesture = beforestart(this, container.call(this, event, d), event, d, "mouse"); | ||
if (!gesture) return; | ||
select(event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true); | ||
nodrag(event.view); | ||
nopropagation(); | ||
nopropagation(event); | ||
mousemoving = false; | ||
mousedownx = event.clientX; | ||
mousedowny = event.clientY; | ||
gesture("start"); | ||
gesture("start", event); | ||
} | ||
function mousemoved() { | ||
noevent(); | ||
function mousemoved(event) { | ||
noevent(event); | ||
if (!mousemoving) { | ||
@@ -72,22 +72,22 @@ var dx = event.clientX - mousedownx, dy = event.clientY - mousedowny; | ||
} | ||
gestures.mouse("drag"); | ||
gestures.mouse("drag", event); | ||
} | ||
function mouseupped() { | ||
function mouseupped(event) { | ||
select(event.view).on("mousemove.drag mouseup.drag", null); | ||
yesdrag(event.view, mousemoving); | ||
noevent(); | ||
gestures.mouse("end"); | ||
noevent(event); | ||
gestures.mouse("end", event); | ||
} | ||
function touchstarted() { | ||
if (!filter.apply(this, arguments)) return; | ||
function touchstarted(event, d) { | ||
if (!filter.call(this, event, d)) return; | ||
var touches = event.changedTouches, | ||
c = container.apply(this, arguments), | ||
c = container.call(this, event, d), | ||
n = touches.length, i, gesture; | ||
for (i = 0; i < n; ++i) { | ||
if (gesture = beforestart(touches[i].identifier, c, touch, this, arguments)) { | ||
nopropagation(); | ||
gesture("start"); | ||
if (gesture = beforestart(this, c, event, d, touches[i].identifier, touches[i])) { | ||
nopropagation(event); | ||
gesture("start", event, touches[i]); | ||
} | ||
@@ -97,3 +97,3 @@ } | ||
function touchmoved() { | ||
function touchmoved(event) { | ||
var touches = event.changedTouches, | ||
@@ -104,4 +104,4 @@ n = touches.length, i, gesture; | ||
if (gesture = gestures[touches[i].identifier]) { | ||
noevent(); | ||
gesture("drag"); | ||
noevent(event); | ||
gesture("drag", event, touches[i]); | ||
} | ||
@@ -111,3 +111,3 @@ } | ||
function touchended() { | ||
function touchended(event) { | ||
var touches = event.changedTouches, | ||
@@ -120,4 +120,4 @@ n = touches.length, i, gesture; | ||
if (gesture = gestures[touches[i].identifier]) { | ||
nopropagation(); | ||
gesture("end"); | ||
nopropagation(event); | ||
gesture("end", event, touches[i]); | ||
} | ||
@@ -127,21 +127,46 @@ } | ||
function beforestart(id, container, point, that, args) { | ||
var p = point(container, id), s, dx, dy, | ||
sublisteners = listeners.copy(); | ||
function beforestart(that, container, event, d, identifier, touch) { | ||
var dispatch = listeners.copy(), | ||
p = pointer(touch || event, container), dx, dy, | ||
s; | ||
if (!customEvent(new DragEvent(drag, "beforestart", s, id, active, p[0], p[1], 0, 0, sublisteners), function() { | ||
if ((event.subject = s = subject.apply(that, args)) == null) return false; | ||
dx = s.x - p[0] || 0; | ||
dy = s.y - p[1] || 0; | ||
return true; | ||
})) return; | ||
if ((s = subject.call(that, new DragEvent("beforestart", { | ||
sourceEvent: event, | ||
target: drag, | ||
identifier, | ||
active, | ||
x: p[0], | ||
y: p[1], | ||
dx: 0, | ||
dy: 0, | ||
dispatch | ||
}), d)) == null) return; | ||
return function gesture(type) { | ||
dx = s.x - p[0] || 0; | ||
dy = s.y - p[1] || 0; | ||
return function gesture(type, event, touch) { | ||
var p0 = p, n; | ||
switch (type) { | ||
case "start": gestures[id] = gesture, n = active++; break; | ||
case "end": delete gestures[id], --active; // nobreak | ||
case "drag": p = point(container, id), n = active; break; | ||
case "start": gestures[identifier] = gesture, n = active++; break; | ||
case "end": delete gestures[identifier], --active; // nobreak | ||
case "drag": p = pointer(touch || event, container), n = active; break; | ||
} | ||
customEvent(new DragEvent(drag, type, s, id, n, p[0] + dx, p[1] + dy, p[0] - p0[0], p[1] - p0[1], sublisteners), sublisteners.apply, sublisteners, [type, that, args]); | ||
dispatch.call( | ||
type, | ||
that, | ||
new DragEvent(type, { | ||
sourceEvent: event, | ||
subject: s, | ||
target: drag, | ||
identifier, | ||
active: n, | ||
x: p[0] + dx, | ||
y: p[1] + dy, | ||
dx: p[0] - p0[0], | ||
dy: p[1] - p0[1], | ||
dispatch | ||
}), | ||
d | ||
); | ||
}; | ||
@@ -148,0 +173,0 @@ } |
@@ -1,12 +0,23 @@ | ||
export default function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch) { | ||
this.target = target; | ||
this.type = type; | ||
this.subject = subject; | ||
this.identifier = id; | ||
this.active = active; | ||
this.x = x; | ||
this.y = y; | ||
this.dx = dx; | ||
this.dy = dy; | ||
this._ = dispatch; | ||
export default function DragEvent(type, { | ||
sourceEvent, | ||
subject, | ||
target, | ||
identifier, | ||
active, | ||
x, y, dx, dy, | ||
dispatch | ||
}) { | ||
Object.defineProperties(this, { | ||
type: {value: type, enumerable: true, configurable: true}, | ||
sourceEvent: {value: sourceEvent, enumerable: true, configurable: true}, | ||
subject: {value: subject, enumerable: true, configurable: true}, | ||
target: {value: target, enumerable: true, configurable: true}, | ||
identifier: {value: identifier, enumerable: true, configurable: true}, | ||
active: {value: active, enumerable: true, configurable: true}, | ||
x: {value: x, enumerable: true, configurable: true}, | ||
y: {value: y, enumerable: true, configurable: true}, | ||
dx: {value: dx, enumerable: true, configurable: true}, | ||
dy: {value: dy, enumerable: true, configurable: true}, | ||
_: {value: dispatch} | ||
}); | ||
} | ||
@@ -13,0 +24,0 @@ |
@@ -1,10 +0,8 @@ | ||
import {event} from "d3-selection"; | ||
export function nopropagation() { | ||
export function nopropagation(event) { | ||
event.stopImmediatePropagation(); | ||
} | ||
export default function() { | ||
export default function(event) { | ||
event.preventDefault(); | ||
event.stopImmediatePropagation(); | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
42925
476
237
2
1
+ Addedd3-dispatch@3.0.1(transitive)
+ Addedd3-selection@3.0.0(transitive)
- Removedd3-dispatch@1.0.6(transitive)
- Removedd3-selection@1.4.2(transitive)
Updatedd3-dispatch@>=2.0.0-rc.1
Updatedd3-selection@>=2.0.0-rc.3