Skip to content

Instantly share code, notes, and snippets.

@dannyko
Last active August 29, 2015 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dannyko/45b56550308f89849101 to your computer and use it in GitHub Desktop.
Save dannyko/45b56550308f89849101 to your computer and use it in GitHub Desktop.
svg-path-scroll-demo

simple svg path scroll demo

Scrolling will interpolate between two paths

<!DOCTYPE html>
<html>
<head>
<style>
body {
min-width: 640px;
height: 100% ;
padding: 0;
border: 0;
margin: 0;
overflow-y: scroll;
}
div {
border:0;
padding:0;
display: block;
}
.svgDiv {
position: fixed ;
left: 0;
top: 0;
width: 100% ;
height: 100% ;
}
</style>
</head>
<body>
<script>
/*
* setup the SVG visualization:
*/
var svgns = "http://www.w3.org/2000/svg" ;
var svgContainer = document.createElement('div') ; // this is the div that contains all of the content divs
svgContainer.setAttribute('class', 'svgDiv') ; // set the ID of this div so that the CSS rules will apply
var svg = document.createElementNS(svgns, 'svg') ;
svg.setAttribute('width', '100%') ;
svg.setAttribute('height', '100%') ;
svg.setAttribute('viewBox', '0 0 1 1') ;
var p = "M 0.1,0.1 L 0.1,0.2 L 0.2,0.2 L 0.2,0.1 0.1,0.1" ; // a square
var q = "M 0.1,0 L 0.1,0.4 L 0.3,0.4 L 0.3,0 0.1,0" ; // a rectangle
var path = document.createElementNS(svgns, 'path') ;
path.setAttribute('fill', 'none') ;
path.setAttribute('stroke', 'black') ;
path.setAttribute('stroke-width', '.01px') ;
path.setAttribute('d', p) ; // initialize path data
svg.appendChild(path) ;
svgContainer.appendChild(svg) ;
document.body.appendChild(svgContainer) ; // add the div to the page via the DOM
/*
* update the interactive visualization on scroll:
*/
document.body.addEventListener(
'wheel',
wheel_callback,
false
) ;
var precision = 0.001 ;
var tween = path_tween(path, q, precision) ;
var Nstep = 101 ;
var kstep = 0 ;
function wheel_response(delta) {
kstep += delta ;
kstep = Math.max(kstep, 0) ;
kstep = Math.min(kstep, Nstep) ;
var t = kstep / Nstep ;
path.setAttribute('d', tween(t)) ;
// console.log('delta', delta, 't', t) ;
} ;
function wheel_callback(event) {
var delta = 0 ;
if (!event) event = window.event ;
if (event.wheelDelta) {
delta = event.wheelDelta / 120 ;
} else if (event.detail) {
delta = -event.detail / 3 ;
}
if (delta)
wheel_response(delta) ;
if (event.preventDefault)
event.preventDefault() ;
event.returnValue = false ;
} ;
/*
* helper functions:
*/
function path_tween(path, q, precision) {
var p = path.cloneNode(),
n0 = path.getTotalLength(),
n1 = (p.setAttribute("d", q), p).getTotalLength() ;
// Uniform sampling of distance based on specified precision.
var distances = [0],
i = 0,
dt = precision / Math.max(n0, n1) ;
while ( (i += dt) < 1 )
distances.push(i) ;
distances.push(1) ;
// Compute point-interpolators at each distance.
var points = distances.map(
function(t) {
var p0 = path.getPointAtLength(t * n0),
p1 = p.getPointAtLength(t * n1) ;
return interpolate([p0.x, p0.y], [p1.x, p1.y]) ;
}
) ;
return function(t) {
return t < 1 ?
"M" + points.map(
function(p) { return p(t) ; }
).join("L")
: q ;
} ;
} ;
function interpolate(a, b) {
var xinterp, yinterp ;
return function(t) {
xinterp = a[0] * (1 - t) + b[0] * t ;
yinterp = a[1] * (1 - t) + b[1] * t ;
return [xinterp, yinterp] ;
}
} ;
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment