1//https://github.com/vlandham/scroll_demo/blob/gh-pages/js/scroller.js 2 3function scroller() { 4 var container = d3.select('#section8'); 5 // event dispatcher 6 var dispatch = d3.dispatch('active', 'progress'); 7 8 // d3 selection of all the 9 // text sections that will 10 // be scrolled through 11 var sections = null; 12 13 // array that will hold the 14 // y coordinate of each section 15 // that is scrolled through 16 var sectionPositions = []; 17 var currentIndex = -1; 18 // y coordinate of 19 var containerStart = 0; 20 21 /** 22 * scroll - constructor function. 23 * Sets up scroller to monitor 24 * scrolling of els selection. 25 * 26 * @param els - d3 selection of 27 * elements that will be scrolled 28 * through by user. 29 */ 30 function scroll(els) { 31 sections = els; 32 33 // when window is scrolled call 34 // position. When it is resized 35 // call resize. 36 d3.select(window) 37 .on('scroll.scroller', position) 38 .on('resize.scroller', resize); 39 40 // manually call resize 41 // initially to setup 42 // scroller. 43 resize(); 44 45 // hack to get position 46 // to be called once for 47 // the scroll position on 48 // load. 49 // @v4 timer no longer stops if you 50 // return true at the end of the callback 51 // function - so here we stop it explicitly. 52 var timer = d3.timer(function () { 53 position(); 54 timer.stop(); 55 }); 56 } 57 58 /** 59 * resize - called initially and 60 * also when page is resized. 61 * Resets the sectionPositions 62 * 63 */ 64 function resize() { 65 // sectionPositions will be each sections 66 // starting position relative to the top 67 // of the first section. 68 sectionPositions = []; 69 var startPos; 70 sections.each(function (d, i) { 71 var top = this.getBoundingClientRect().top; 72 if (i === 0) { 73 startPos = top; 74 } 75 sectionPositions.push(top - startPos); 76 }); 77 containerStart = container.node().getBoundingClientRect().top + window.pageYOffset; 78 } 79 80 /** 81 * position - get current users position. 82 * if user has scrolled to new section, 83 * dispatch active event with new section 84 * index. 85 * 86 */ 87 function position() { 88 var pos = window.pageYOffset - 10 - containerStart; 89 var sectionIndex = d3.bisect(sectionPositions, pos); 90 sectionIndex = Math.min(sections.size() - 1, sectionIndex); 91 92 if (currentIndex !== sectionIndex) { 93 // @v4 you now `.call` the dispatch callback 94 dispatch.call('active', this, sectionIndex); 95 currentIndex = sectionIndex; 96 } 97 98 var prevIndex = Math.max(sectionIndex - 1, 0); 99 var prevTop = sectionPositions[prevIndex]; 100 var progress = (pos - prevTop) / (sectionPositions[sectionIndex] - prevTop); 101 // @v4 you now `.call` the dispatch callback 102 dispatch.call('progress', this, currentIndex, progress); 103 } 104 105 /** 106 * container - get/set the parent element 107 * of the sections. Useful for if the 108 * scrolling doesn't start at the very top 109 * of the page. 110 * 111 * @param value - the new container value 112 */ 113 scroll.container = function (value) { 114 if (arguments.length === 0) { 115 return container; 116 } 117 container = value; 118 return scroll; 119 }; 120 121 // @v4 There is now no d3.rebind, so this implements 122 // a .on method to pass in a callback to the dispatcher. 123 scroll.on = function (action, callback) { 124 dispatch.on(action, callback); 125 }; 126 127 return scroll; 128}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.