Reputation: 11
I have created a working zoom behavior in d3 v4 to examine a node graph, but am trying to implement two methods that are invoked by zooming. When the user scrolls up with the mouse wheel to zoom in, I want that to invoke the method undo()
and when the user scrolls down with the mouse wheel to zoom out, I want that to invoke the method coarse()
. I am struggling to figure out how to run two different methods depending on if the user scrolls up or down to zoom. Below is how I wrote my basic zoom behavior. Any help would be great, thanks!
var zoom = d3.zoom()
.scaleExtent([1, 2000])
.on('zoom', zoomFn);
function zoomFn() {
d3.select('#div2').select('svg').select('g')
.attr('transform', 'translate(' + d3.event.transform.x + ',' + d3.event.transform.y + ') scale(' + d3.event.transform.k +')')
}
d3.select('#div2').select('svg').select('rect').call(zoom)
Upvotes: 1
Views: 832
Reputation: 265
There are a couple ways you could go about implementing this. For a more event listener based approach I'd do the following:
var lastKnownPos = window.scrollY();
window.addEventListener('scroll', function(e) {
if (lastKnownPos > window.scrollY()) {
//user is scrolling up, current position < last position
undo();
} else if () {
//user is scrolling down, current position > last position
coarse();
}
lastKnownPos = window.scrollY();
}
Essentially, the above snippet compares the previous stored value of the distance from the top of the page (given by window.scrollY()
), to the current position on the page whenever the user scrolls. The difference in the values tells the snippet in which direction the user is scrolling.
A couple of notes:
-You should probably wrap this snippet in a block of code that it only triggers when the document is ready (so you don't make changes to the document before it is loaded, causing problems).
-If the user continuously scrolls, this function will be continuously called. If this is not a desired behavior, and you only want undo()
and coarse()
to be called once, you can set a boolean that gets checked before executing. Set the boolean to false
once one of the functions is called, and is only set to true again after a timer (like setTimeout()
) passes a desired period of time. You can read about some timing functions here: Javascript: Call a function after specific time period.
Alternatively, if you don't want to/ can't use event listeners, you could use an entirely timer based approach. This would be a little harder to get to feel as smooth while also not slowing down your code. If you want me to elaborate on this please say so!
Upvotes: 1