Skip to content

Commit

Permalink
zoom.center() defines a center function for the reference point of th…
Browse files Browse the repository at this point in the history
…e zoom; defaults to d3.pointer

fixes #211
  • Loading branch information
Fil committed Jul 13, 2020
1 parent 87781b6 commit aa8323f
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 6 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,18 @@ function constrain(transform, extent, translateExtent) {

The constraint function must return a [*transform*](#zoom-transforms) given the current *transform*, [viewport extent](#zoom_extent) and [translate extent](#zoom_translateExtent). The default implementation attempts to ensure that the viewport extent does not go outside the translate extent.

<a href="#zoom_center" name="zoom_center">#</a> <i>zoom</i>.<b>center</b>([<i>center</i>]) · [Source](https://github.com/d3/d3-zoom/blob/master/src/zoom.js)

If *center* is specified, sets the center to the specified function and returns the zoom behavior. If *center* is not specified, returns the current center, which defaults to the pointer’s position relative to the current DOM element:

```js
function center(event) {
return d3.pointer(event, this);
}
```

The center is passed the current event (`event`) and datum `d`, with the `this` context as the current DOM element. It must return a position as [*x*, *y*].

<a href="#zoom_filter" name="zoom_filter">#</a> <i>zoom</i>.<b>filter</b>([<i>filter</i>]) · [Source](https://github.com/d3/d3-zoom/blob/master/src/zoom.js)

If *filter* is specified, sets the filter to the specified function and returns the zoom behavior. If *filter* is not specified, returns the current filter, which defaults to:
Expand Down
21 changes: 15 additions & 6 deletions src/zoom.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ function defaultFilter(event) {
return !event.ctrlKey && !event.button;
}

function defaultCenter(event) {
return pointer(event, this);
}

function defaultExtent() {
var e = this;
if (e instanceof SVGElement) {
Expand Down Expand Up @@ -51,6 +55,7 @@ function defaultConstrain(transform, extent, translateExtent) {

export default function() {
var filter = defaultFilter,
center = defaultCenter,
extent = defaultExtent,
constrain = defaultConstrain,
wheelDelta = defaultWheelDelta,
Expand Down Expand Up @@ -236,7 +241,7 @@ export default function() {
var g = gesture(this, args).event(event),
t = this.__zoom,
k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], t.k * Math.pow(2, wheelDelta.apply(this, arguments)))),
p = pointer(event);
p = center.apply(this, arguments);

// If the mouse is in the same location as before, reuse it.
// If there were recent wheel events, reset the wheel idle timeout.
Expand Down Expand Up @@ -271,7 +276,7 @@ export default function() {
if (touchending || !filter.apply(this, arguments)) return;
var g = gesture(this, args, true).event(event),
v = select(event.view).on("mousemove.zoom", mousemoved, true).on("mouseup.zoom", mouseupped, true),
p = pointer(event, currentTarget),
p = center.apply(currentTarget, arguments),
currentTarget = event.currentTarget,
x0 = event.clientX,
y0 = event.clientY;
Expand All @@ -289,7 +294,7 @@ export default function() {
g.moved = dx * dx + dy * dy > clickDistance2;
}
g.event(event)
.zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = pointer(event, currentTarget), g.mouse[1]), g.extent, translateExtent));
.zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = center.apply(currentTarget, arguments), g.mouse[1]), g.extent, translateExtent));
}

function mouseupped(event) {
Expand All @@ -303,7 +308,7 @@ export default function() {
function dblclicked(event, ...args) {
if (!filter.apply(this, arguments)) return;
var t0 = this.__zoom,
p0 = pointer(event.changedTouches ? event.changedTouches[0] : event, this),
p0 = center.call(this, event.changedTouches ? event.changedTouches[0] : event, ...args),
p1 = t0.invert(p0),
k1 = t0.k * (event.shiftKey ? 0.5 : 2),
t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, args), translateExtent);
Expand All @@ -322,7 +327,7 @@ export default function() {

nopropagation(event);
for (i = 0; i < n; ++i) {
t = touches[i], p = pointer(t, this);
t = touches[i], p = center.call(this, t, ...args);
p = [p, this.__zoom.invert(p), t.identifier];
if (!g.touch0) g.touch0 = p, started = true, g.taps = 1 + !!touchstarting;
else if (!g.touch1 && g.touch0[2] !== p[2]) g.touch1 = p, g.taps = 0;
Expand All @@ -347,7 +352,7 @@ export default function() {
if (touchstarting) touchstarting = clearTimeout(touchstarting);
g.taps = 0;
for (i = 0; i < n; ++i) {
t = touches[i], p = pointer(t, this);
t = touches[i], p = center.call(this, t, ...args);
if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p;
else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p;
}
Expand Down Expand Up @@ -404,6 +409,10 @@ export default function() {
return arguments.length ? (touchable = typeof _ === "function" ? _ : constant(!!_), zoom) : touchable;
};

zoom.center = function(_) {
return arguments.length ? (center = typeof _ === "function" ? _ : constant([+_[0], +_[1]]), zoom) : center;
};

zoom.extent = function(_) {
return arguments.length ? (extent = typeof _ === "function" ? _ : constant([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent;
};
Expand Down

0 comments on commit aa8323f

Please sign in to comment.