site/node_modules/d3-drag/dist/d3-drag.js

274 lines
8 KiB
JavaScript
Raw Permalink Normal View History

2024-10-14 06:09:33 +00:00
// https://d3js.org/d3-drag/ v3.0.0 Copyright 2010-2021 Mike Bostock
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-dispatch'), require('d3-selection')) :
typeof define === 'function' && define.amd ? define(['exports', 'd3-dispatch', 'd3-selection'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = global.d3 || {}, global.d3, global.d3));
}(this, (function (exports, d3Dispatch, d3Selection) { 'use strict';
// These are typically used in conjunction with noevent to ensure that we can
// preventDefault on the event.
const nonpassive = {passive: false};
const nonpassivecapture = {capture: true, passive: false};
function nopropagation(event) {
event.stopImmediatePropagation();
}
function noevent(event) {
event.preventDefault();
event.stopImmediatePropagation();
}
function nodrag(view) {
var root = view.document.documentElement,
selection = d3Selection.select(view).on("dragstart.drag", noevent, nonpassivecapture);
if ("onselectstart" in root) {
selection.on("selectstart.drag", noevent, nonpassivecapture);
} else {
root.__noselect = root.style.MozUserSelect;
root.style.MozUserSelect = "none";
}
}
function yesdrag(view, noclick) {
var root = view.document.documentElement,
selection = d3Selection.select(view).on("dragstart.drag", null);
if (noclick) {
selection.on("click.drag", noevent, nonpassivecapture);
setTimeout(function() { selection.on("click.drag", null); }, 0);
}
if ("onselectstart" in root) {
selection.on("selectstart.drag", null);
} else {
root.style.MozUserSelect = root.__noselect;
delete root.__noselect;
}
}
var constant = x => () => x;
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}
});
}
DragEvent.prototype.on = function() {
var value = this._.on.apply(this._, arguments);
return value === this._ ? this : value;
};
// Ignore right-click, since that should open the context menu.
function defaultFilter(event) {
return !event.ctrlKey && !event.button;
}
function defaultContainer() {
return this.parentNode;
}
function defaultSubject(event, d) {
return d == null ? {x: event.x, y: event.y} : d;
}
function defaultTouchable() {
return navigator.maxTouchPoints || ("ontouchstart" in this);
}
function drag() {
var filter = defaultFilter,
container = defaultContainer,
subject = defaultSubject,
touchable = defaultTouchable,
gestures = {},
listeners = d3Dispatch.dispatch("start", "drag", "end"),
active = 0,
mousedownx,
mousedowny,
mousemoving,
touchending,
clickDistance2 = 0;
function drag(selection) {
selection
.on("mousedown.drag", mousedowned)
.filter(touchable)
.on("touchstart.drag", touchstarted)
.on("touchmove.drag", touchmoved, nonpassive)
.on("touchend.drag touchcancel.drag", touchended)
.style("touch-action", "none")
.style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
}
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(event.view)
.on("mousemove.drag", mousemoved, nonpassivecapture)
.on("mouseup.drag", mouseupped, nonpassivecapture);
nodrag(event.view);
nopropagation(event);
mousemoving = false;
mousedownx = event.clientX;
mousedowny = event.clientY;
gesture("start", event);
}
function mousemoved(event) {
noevent(event);
if (!mousemoving) {
var dx = event.clientX - mousedownx, dy = event.clientY - mousedowny;
mousemoving = dx * dx + dy * dy > clickDistance2;
}
gestures.mouse("drag", event);
}
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(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(this, c, event, d, touches[i].identifier, touches[i])) {
nopropagation(event);
gesture("start", event, touches[i]);
}
}
}
function touchmoved(event) {
var touches = event.changedTouches,
n = touches.length, i, gesture;
for (i = 0; i < n; ++i) {
if (gesture = gestures[touches[i].identifier]) {
noevent(event);
gesture("drag", event, touches[i]);
}
}
}
function touchended(event) {
var touches = event.changedTouches,
n = touches.length, i, gesture;
if (touchending) clearTimeout(touchending);
touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
for (i = 0; i < n; ++i) {
if (gesture = gestures[touches[i].identifier]) {
nopropagation(event);
gesture("end", event, touches[i]);
}
}
}
function beforestart(that, container, event, d, identifier, touch) {
var dispatch = listeners.copy(),
p = d3Selection.pointer(touch || event, container), dx, dy,
s;
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;
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[identifier] = gesture, n = active++; break;
case "end": delete gestures[identifier], --active; // falls through
case "drag": p = d3Selection.pointer(touch || event, container), n = active; break;
}
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
);
};
}
drag.filter = function(_) {
return arguments.length ? (filter = typeof _ === "function" ? _ : constant(!!_), drag) : filter;
};
drag.container = function(_) {
return arguments.length ? (container = typeof _ === "function" ? _ : constant(_), drag) : container;
};
drag.subject = function(_) {
return arguments.length ? (subject = typeof _ === "function" ? _ : constant(_), drag) : subject;
};
drag.touchable = function(_) {
return arguments.length ? (touchable = typeof _ === "function" ? _ : constant(!!_), drag) : touchable;
};
drag.on = function() {
var value = listeners.on.apply(listeners, arguments);
return value === listeners ? drag : value;
};
drag.clickDistance = function(_) {
return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2);
};
return drag;
}
exports.drag = drag;
exports.dragDisable = nodrag;
exports.dragEnable = yesdrag;
Object.defineProperty(exports, '__esModule', { value: true });
})));