Testing the graph-scroll library. Checking more complex possibilities.
function graphScroll() {
var windowHeight,
dispatch = d3.dispatch("scroll", "active"),
sections = d3.select('null'),
i = NaN,
sectionPos = [],
n,
graph = d3.select('null'),
isFixed = null,
isBelow = null,
container = d3.select('body'),
containerStart = 0,
belowStart,
eventId = Math.random()
function reposition(){
var i1 = 0
sectionPos.forEach(function(d, i){
if (d < pageYOffset - containerStart + 200) i1 = i
})
i1 = Math.min(n - 1, i1)
if (i != i1){
sections.classed('graph-scroll-active', function(d, i){ return i === i1 })
dispatch.active(i1)
i = i1
}
var isBelow1 = pageYOffset > belowStart
if (isBelow != isBelow1){
isBelow = isBelow1
graph.classed('graph-scroll-below', isBelow)
}
var isFixed1 = !isBelow && pageYOffset > containerStart
if (isFixed != isFixed1){
isFixed = isFixed1
graph.classed('graph-scroll-fixed', isFixed)
}
var pos = pageYOffset - 10 - containerStart;
var prevTop = sectionPos[i];
var nextTop = (i+1<sectionPos.length?sectionPos[i+1]:(belowStart-containerStart)) - 200 ;
var progress = (pos - prevTop) / (nextTop - prevTop);
if(progress>=0 && progress <=1)
dispatch.scroll(i, progress);
}
function resize(){
sectionPos = []
var startPos
sections.each(function(d, i){
if (!i) startPos = this.getBoundingClientRect().top
sectionPos.push(this.getBoundingClientRect().top - startPos) })
var containerBB = container.node().getBoundingClientRect()
var graphBB = graph.node().getBoundingClientRect()
containerStart = containerBB.top + pageYOffset
belowStart = containerBB.bottom - graphBB.height + pageYOffset
}
function keydown() {
if (!isFixed) return
var delta
switch (d3.event.keyCode) {
case 39: // right arrow
if (d3.event.metaKey) return
case 40: // down arrow
case 34: // page down
delta = d3.event.metaKey ? Infinity : 1 ;break
case 37: // left arrow
if (d3.event.metaKey) return
case 38: // up arrow
case 33: // page up
delta = d3.event.metaKey ? -Infinity : -1 ;break
case 32: // space
delta = d3.event.shiftKey ? -1 : 1
;break
default: return
}
var i1 = Math.max(0, Math.min(i + delta, n - 1))
d3.select(document.documentElement)
.interrupt()
.transition()
.duration(500)
.tween("scroll", function() {
var i = d3.interpolateNumber(pageYOffset, sectionPos[i1] + containerStart)
return function(t) { scrollTo(0, i(t)) }
})
d3.event.preventDefault()
}
var rv ={}
rv.container = function(_x){
if (!_x) return container
container = _x
return rv
}
rv.graph = function(_x){
if (!_x) return graph
graph = _x
return rv
}
rv.eventId = function(_x){
if (!_x) return eventId
eventId = _x
return rv
}
rv.sections = function (_x){
if (!_x) return sections
sections = _x
n = sections.size()
d3.select(window)
.on('scroll.gscroll' + eventId, reposition)
.on('resize.gscroll' + eventId, resize)
.on('keydown.gscroll' + eventId, keydown)
resize()
d3.timer(function() {
reposition()
return true
})
return rv
}
d3.rebind(rv, dispatch, "on")
return rv
}
[{"day":3, "hour":18, "lat":6.1, "lon":153.3, "class": 2},{"day":3, "hour":21, "lat":6.1, "lon":152.8, "class": 2},{"day":4, "hour":0, "lat":6.1, "lon":152.2, "class": 3},{"day":4, "hour":3, "lat":6.2, "lon":151.2, "class": 3},{"day":4, "hour":6, "lat":6.2, "lon":150.4, "class": 3},{"day":4, "hour":9, "lat":6.2, "lon":149.5, "class": 3},{"day":4, "hour":12, "lat":6.3, "lon":148.6, "class": 3},{"day":4, "hour":15, "lat":6.3, "lon":148.4, "class": 3},{"day":4, "hour":18, "lat":6.5, "lon":147.6, "class": 3},{"day":4, "hour":21, "lat":6.5, "lon":147.0, "class": 3},{"day":5, "hour":0, "lat":6.5, "lon":145.9, "class": 4},{"day":5, "hour":3, "lat":6.5, "lon":145.2, "class": 4},{"day":5, "hour":6, "lat":6.5, "lon":144.6, "class": 4},{"day":5, "hour":9, "lat":6.5, "lon":144.0, "class": 4},{"day":5, "hour":12, "lat":6.9, "lon":143.1, "class": 4},{"day":5, "hour":15, "lat":7.0, "lon":142.1, "class": 4},{"day":5, "hour":18, "lat":7.1, "lon":141.3, "class": 5},{"day":5, "hour":21, "lat":7.3, "lon":140.5, "class": 5},{"day":6, "hour":0, "lat":7.3, "lon":139.7, "class": 5},{"day":6, "hour":3, "lat":7.5, "lon":138.9, "class": 5},{"day":6, "hour":6, "lat":7.6, "lon":138.0, "class": 5},{"day":6, "hour":9, "lat":7.7, "lon":137.2, "class": 5},{"day":6, "hour":12, "lat":7.9, "lon":136.2, "class": 5},{"day":6, "hour":15, "lat":8.1, "lon":135.3, "class": 5},{"day":6, "hour":18, "lat":8.2, "lon":134.4, "class": 5},{"day":6, "hour":21, "lat":8.4, "lon":133.6, "class": 5},{"day":7, "hour":0, "lat":8.7, "lon":132.8, "class": 5},{"day":7, "hour":3, "lat":9.0, "lon":131.9, "class": 5},{"day":7, "hour":6, "lat":9.3, "lon":131.1, "class": 5},{"day":7, "hour":9, "lat":9.8, "lon":130.2, "class": 5},{"day":7, "hour":12, "lat":10.2, "lon":129.1, "class": 5},{"day":7, "hour":15, "lat":10.4, "lon":128.0, "class": 5},{"day":7, "hour":18, "lat":10.6, "lon":126.9, "class": 5},{"day":7, "hour":21, "lat":10.8, "lon":125.9, "class": 5},{"day":8, "hour":0, "lat":11.0, "lon":124.8, "class": 5},{"day":8, "hour":3, "lat":11.2, "lon":123.7, "class": 5},{"day":8, "hour":6, "lat":11.4, "lon":122.6, "class": 5},{"day":8, "hour":9, "lat":11.5, "lon":121.6, "class": 5},{"day":8, "hour":12, "lat":11.8, "lon":120.7, "class": 5},{"day":8, "hour":15, "lat":12.3, "lon":119.4, "class": 5},{"day":8, "hour":18, "lat":12.4, "lon":118.2, "class": 5},{"day":8, "hour":21, "lat":12.5, "lon":117.3, "class": 5},{"day":9, "hour":0, "lat":12.3, "lon":116.6, "class": 5},{"day":9, "hour":3, "lat":12.9, "lon":115.6, "class": 5},{"day":9, "hour":9, "lat":13.9, "lon":113.9, "class": 5},{"day":9, "hour":12, "lat":14.4, "lon":113.1, "class": 5},{"day":9, "hour":15, "lat":15.0, "lon":112.2, "class": 5},{"day":9, "hour":18, "lat":15.4, "lon":111.4, "class": 5},{"day":9, "hour":21, "lat":15.9, "lon":111.1, "class": 5},{"day":10, "hour":0, "lat":16.5, "lon":110.3, "class": 5},{"day":10, "hour":3, "lat":17.0, "lon":109.7, "class": 5},{"day":10, "hour":6, "lat":17.8, "lon":109.0, "class": 5},{"day":10, "hour":9, "lat":18.5, "lon":108.4, "class": 5},{"day":10, "hour":12, "lat":19.4, "lon":108.1, "class": 5},{"day":10, "hour":15, "lat":19.8, "lon":107.9, "class": 5},{"day":10, "hour":18, "lat":20.3, "lon":107.5, "class": 4},{"day":10, "hour":21, "lat":20.8, "lon":107.1, "class": 4},{"day":11, "hour":0, "lat":21.3, "lon":107.2, "class": 4},{"day":11, "hour":3, "lat":22.0, "lon":107.2, "class": 4},{"day":11, "hour":6, "lat":22.3, "lon":107.4, "class": 3},{"day":11, "hour":9, "lat":22.6, "lon":107.6, "class": 3},{"day":11, "hour":12, "lat":23.0, "lon":107.0, "class": 2}]