Closed dmosberger closed 5 years ago
Turns out the main problem was that I was getting unexpected ngAfterViewChecked() calls (I'm doing this in Angular) which in turned lead to spurious calls to my resize handler which would then reset the zoom behavior. Oops. Now that I fixed this, panning is working great.
Still no luck with pinching for zooming though.
Oh, just to be clear: now when using the pinch gesture (Shift + drag in the Chrome web developer tools for mobile), I do get zoom events, but d3.event.transform.k is always 1. Only x and y change. For example:
screen.service.ts:207 event.transform Transform {k: 1, x: -88, y: -170} 5 12.9
screen.service.ts:207 event.transform Transform {k: 1, x: -88, y: -170} 5 12.9
screen.service.ts:207 event.transform Transform {k: 1, x: -88, y: -167} 5 12.9
screen.service.ts:207 event.transform Transform {k: 1, x: -88, y: -166} 5 12.9
screen.service.ts:207 event.transform Transform {k: 1, x: -88, y: -165} 5 12.9
Sorry about the monologue. Turns out pinch zoom gesture does work on an actual phone, just not in the Chrome web-developers console.
I can't seem to get d3 zoom to work properly with d3 geo projections. I've converted Ivy Wang's Drag to Rotate the Globe to v4 and combined it with zoom. It works properly with mouse functions as long as I include svg.on("mousedown.zoom", null);
, otherwise d3.zoom mousedown overrides the d3.drag functions. I still can't get it to work with touch. Double tapping zooms on a laptop (Asus, windows 10, google chrome), but on mobile (IOS 11.4) it doesn't. Two finger zooming works on a laptop but on mobile only changes lineweights I've included in my zoom function. Also, rotating the projection doesn't work unless I include
svg.on("mousedown.zoom", null)
.on("touchstart.zoom", null)
.on("touchmove.zoom", null)
.on("touchend.zoom", null);
which disables touch zooming all together. These things seem to work together on Jason Davies site though when you try to zoom on mobile it usually zooms the entire page. I would love to know if I am relatively close to getting this to work, or if it simply won't work combining these zoom and drag functions. Is there a working example of this somewhere? I haven't been able to find anything in v4 with map projections and that works on touch.
Here a code snippet:
var svg = d3
.select("body")
.append("svg")
.attr("id", "world")
.attr("width", width)
.attr("height", height)
.call(d3.zoom().on("zoom", zoomed));
svg.on("mousedown.zoom", null)
.on("touchstart.zoom", null)
.on("touchmove.zoom", null)
.on("touchend.zoom", null);
function zoomed() {
let k = d3.event.transform.k;
d3.selectAll("#world").attr("transform", "scale(" + k + ")");
d3.selectAll(".graticule").attr("stroke-width", 0.5 / k);
d3.selectAll(".pin").attr("stroke-width", 2 / k);
d3.selectAll(".travelPath").attr("stroke-width", 2 / k);
d3.selectAll(".land").attr("stroke-width", 1 / k);
d3.selectAll(".border").attr("stroke-width", 1 / k);
}
And my whole project is on my Codepen. Zoom function start on line 287 and drag on line 344.
If someone faced with shaking, slow pan (dragging) speed and inability to go back after zooming / moving outside of svg:
Try to wrap the svg with div and attach event to the div instead of svg:
d3.select(svgContainer).call(d3.zoom().on("zoom", zoomed));
(In zoomed
function, apply transform to svg just as before)
Closing to inactivity. Possibly related to #162.
I suspect I'm doing something wrong, but after searching far and wide, I don't see the problem.
Background: I'm trying to use d3.zoom (v5.4.0) to pan and zoom a screen area (as in an oscilloscope screen). It's working perfectly fine with the mouse: dragging moves the screen as expected and wheel-action zooms in/out. Beautiful! However, nothing happens on an Android phone (or the Chrome developer's console mobile emulator) when trying to pan with a touch move or zooming with a pinch gesture.
I use a rectangle for receiving the events:
and then add the zoom behavior like this:
The filter() call, never logs any 'touchmove' events. It does get a 'touchstart' event both on pan and pinch gestures, but nothing during touchmove or pinch-move. On the other hand, the touchable() function does seem to get called during the move events.
I tried adding attribute 'touch-action: none' to the zoomRect, thinking that maybe the browser is trying to handle the touchmove events, but that made no difference.