customScroller = {
const width = window.innerWidth * 1;
const height = window.innerHeight *1;
const div = html`<div></div>`
const divSel = d3.select(div)
.style("overflow-y", "auto")
.style("white-space", "nowrap")
.style('overflow-x', 'hidden')
.style("cursor", "grab")
.style("max-width", `${width}px`)
.style("max-height", `${height}px`)
const svg = divSel.append('svg')
.attr('width', width)
.attr('height', height)
.style('position', 'absolute')
.style('top', '0px')
.style('left', '0px')
.style('pointer-events', 'none')
const circle = svg.append('circle')
.attr('cx', width / 2)
.attr('cy', height / 2)
.attr('r', 50)
.style('fill', '#fff')
const text = svg.append('text')
.attr('transform', `translate(${10}, ${30})`)
.text('Step 0')
.style('font', '20px sans-serif')
const nSteps = 5;
const stepSize = 500;
const scrollHeight = stepSize * nSteps;
const innerDiv = divSel.append('div')
.style("width", `${width}px`)
.style("height", `${scrollHeight}px`)
.style('overflow-y', 'auto')
innerDiv.append('div')
.style("width", `${width}px`)
.style("height", `${scrollHeight}px`)
.style('background', 'linear-gradient(#e66465, #9198e5)')
const step1 = () => {
circle.transition().attr('r', 50).attr('cx', width / 2).style('fill', '#fff')
}
const step2 = () => {
circle.transition().attr('r', 100).style('fill', '#fff').attr('cx', width / 2)
}
const step3 = () => {
circle.transition().style('fill', '#000').attr('cx', width / 2)
}
const step4 = () => {
circle.transition().attr('cx', width * 3 / 4)
}
const stepFunctions = {
0: step1,
1: step2,
2: step3,
3: step4,
4: () => {}
}
let scrollDirection = 'down';
let pos = 0;
let currentStep = 0;
divSel.on('scroll', function(event) {
const newPos = divSel.property("scrollTop")
if(newPos > pos) {
scrollDirection = 'down'
} else {
scrollDirection = 'up'
}
pos = newPos;
if(currentStep != Math.floor(newPos / stepSize)) {
currentStep = Math.floor(newPos / stepSize);
stepFunctions[currentStep]()
}
text.text(`Step ${currentStep} - scrolling ${scrollDirection}`);
});
return div
}