TODO: redo just using d3.interpolateZoom, duh.
| <!DOCTYPE html> | |
| <html> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |
| <title></title> | |
| <link rel="stylesheet" type="text/css" href="main.css"/> | |
| <body> | |
| <div class="container"> | |
| <img src="photo.jpg"> | |
| </div> | |
| </body> | |
| <script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script> | |
| <script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js" charset="utf-8"></script> | |
| <script src="//cdn.rawgit.com/gka/d3-jetpack/master/d3-jetpack.js" charset="utf-8"></script> | |
| <script src="main.js" charset="utf-8"></script> | |
| </html> |
| var container = d3.select('.container') | |
| .style('width', innerWidth + 'px') | |
| .style('height', innerHeight + 'px') | |
| .node(); | |
| var image = document.querySelector("img"); | |
| var start = { | |
| zoom: [.7, .7], | |
| center: [.5, .5] | |
| } | |
| var end = { | |
| zoom: [4, 4], | |
| center: [.33, .33] | |
| } | |
| var zoomerTween = zoomerTweener(start, end); | |
| var scrollScale = d3.scale.linear() | |
| .domain([0,1000]) | |
| .clamp(true); | |
| window.addEventListener('scroll', handleScroll); | |
| handleScroll(); | |
| function handleScroll() { | |
| var t = scrollScale(scrollY); | |
| var coords = zoomerTween(t); | |
| d3.select(image) | |
| .style('left', coords.x + 'px') | |
| .style('top', coords.y + 'px') | |
| .style('width', coords.width + 'px') | |
| .style('height', coords.height + 'px'); | |
| } | |
| function zoomerTweener(start, end) { | |
| var zoomLerp = lerp(start.zoom, end.zoom); | |
| var centerLerp = lerp(start.center, end.center); | |
| return function(t) { | |
| var zoom = zoomLerp(t*t); | |
| var center = centerLerp(t); | |
| return zoomer(zoom, center); | |
| } | |
| } | |
| function zoomer(zoom, center) { | |
| var x = d3.scale.linear() | |
| .domain([center[0] * image.naturalWidth, center[0] * image.naturalWidth + 1]) | |
| .range([container.offsetWidth/2, container.offsetWidth/2 + zoom[0]]) | |
| var y = d3.scale.linear() | |
| .domain([center[1] * image.naturalHeight, center[1] * image.naturalHeight + 1]) | |
| .range([container.offsetHeight/2, container.offsetHeight/2 + zoom[1]]); | |
| return { | |
| x: x(0), | |
| y: y(0), | |
| width: image.naturalWidth * zoom[0], | |
| height: image.naturalHeight * zoom[1] | |
| } | |
| } | |
| function lerp(array0,array1) { | |
| var scales = d3.range(array0.length).map(function(n) { | |
| return d3.scale.linear() | |
| .range([array0[n], array1[n]]); | |
| }); | |
| return function(t) { | |
| return scales.map(function(d,i) { | |
| return d(t); | |
| }) | |
| } | |
| } | |
| // https://gist.github.com/Rich-Harris/5894545 | |
| // UM NOT CURRENTLY BEING USED LOL but would be nice to ditch d3 | |
| var linearScale = function ( domain, range ) { | |
| var d0 = domain[0], r0 = range[0], multiplier = ( range[1] - r0 ) / ( domain[1] - d0 ); | |
| // special case | |
| if ( r0 === range[1] ) { | |
| return function () { | |
| return r0; | |
| }; | |
| } | |
| return function ( num ) { | |
| return r0 + ( multiplier * ( num - d0 ) ); | |
| }; | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
