Draft of text animation used on http://www.bloomberg.com/features/2016-benjamin-wey/. Samples points along path & offsets alternating points along mouse-directed axis. Timer-driven here; scroll-speed–driven there.
Last active
May 12, 2016 03:58
-
-
Save tophtucker/0f828c44231f02fa433b to your computer and use it in GitHub Desktop.
Slander
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> | |
</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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
html, body { | |
width: 100%; | |
height: 100%; | |
margin: 0; | |
padding: 0em; | |
} | |
svg { | |
width: 100%; | |
height: 100%; | |
overflow: visible; | |
} | |
path.spine { | |
fill: none; | |
stroke: black; | |
stroke-width: 10; | |
/*opacity: 0;*/ | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// cf http://bl.ocks.org/mbostock/3916621 | |
var spinePaths = [ | |
'M135.3,80.2c0,0-6.7-34-40-34s-41.3,16-42,34c-0.7,18,21,25,45,29s41.3,12.3,41.3,36.7s-24.3,33.1-43.2,33.1s-48.8-10.4-48.8-41.7', | |
'M164,46.2v129.7h78.3', | |
'M356.3,178.9L304.5,48.2l-51.8,129', | |
'M270.9,130.7h66.3', | |
'M467.4,48.2v127.7l-92-127.7v130.7', | |
'M498.4,48.2v127.7h48.2c0,0,48.2,2.6,48.2-63.3s-48.2-64.4-48.2-64.4H498.4z', | |
'M703.3,48.2h-84v127.7h84', | |
'M619.3,111h78.2', | |
'M727.5,115.3l51.8-0.2c0,0,33.1,0.1,33.1-33.1s-32.2-33.8-32.2-33.8h-52.7v130.7', | |
'M780,115.1l36.5,63.8' | |
]; | |
var mouse = [0,0]; | |
var svg = d3.select('body').append('svg') | |
.on('mousemove', function() { mouse = d3.mouse(this); }); | |
var spines = svg.selectAll('path.spine') | |
.data(spinePaths) | |
.enter() | |
.append('path.spine') | |
.attr('d', ƒ()) | |
.each(function(d) { | |
var pathSamples = samplePath(this,7,10); // for spiky | |
// var pathSamples = samplePath(this,25,20); // for blobby | |
var datum = { | |
'spine': this, | |
'samples': pathSamples | |
} | |
svg.append('path.spiky') | |
.datum(datum); | |
}); | |
var spikys = svg.selectAll('path.spiky'); | |
var spineShrink = d3.scale.linear() | |
.domain([ 0, 1e3, 2e3, 4e3 ]) | |
.range([ 10, 10, 2, 0 ]) | |
.clamp(true); | |
var spikeGrow = d3.scale.linear() | |
.domain([ 1e3, 2e3, 7e3, 8e3 ]) | |
.range([ 0, 30, 60, 300 ]) | |
.clamp(true); | |
var squareWave = makeSquareWave(2, 2e-4, 15); | |
// // spiky | |
d3.timer(function(t) { | |
spines.style('stroke-width', spineShrink(t)); | |
spikys.attr('d', function(d) { | |
// w/ square wave oscillation: spikeGrow(t) + (.3 * spikeGrow(t) * (squareWave(t)+2)) | |
return getSpikyPath(d.samples, mouse, spikeGrow(t) ); | |
}); | |
}); | |
// blobby | |
// d3.timer(function(t) { | |
// spines.style('stroke-width', 0); | |
// spikys.attr('d', function(d) { | |
// return getBlobbyPath(d.samples, mouse, squareWave(t)); | |
// }); | |
// }); | |
function samplePath(path, precision, jiggle) { | |
var sampleJiggle = jiggle || 0; | |
var samplePrecision = precision || 5; | |
var totalLength = path.getTotalLength(); | |
var samples = totalLength / samplePrecision; | |
var distances = d3.range(samples).map(function(d) { | |
var randomJiggleOffset = (sampleJiggle / totalLength) * (Math.random()-0.5); | |
return (d===0) ? 0 : Math.max(Math.min((d / samples) + randomJiggleOffset, 1),0); | |
}); | |
distances.push(1); | |
return distances.map(function(d,i) { | |
var pt = path.getPointAtLength(d * totalLength); | |
return [pt.x, pt.y]; | |
}); | |
} | |
function getSpikyPath(spinePoints, origin, magnitude) { | |
var axisOrigin = origin || [0,0]; | |
var axisMagnitude = magnitude || 0; | |
var offsetPoints = spinePoints.slice(0).map(function(pt,i) { | |
// an additional degree of irregularity! amplitudinal irregularity, just based on sample index | |
var amplitudinalJiggle = 2; // the lower, the bigger | |
var mag = axisMagnitude + (axisMagnitude/amplitudinalJiggle) * Math.sin(i); | |
var axis = [axisOrigin[0] - pt[0], axisOrigin[1] - pt[1]]; | |
var axisNorm = distance([0,0], axis); | |
var normalizedAxis = axis.map(function(d,i) { return (d / axisNorm) * mag; }); | |
var direction = (i % 2 == 0) ? 1 : -1; | |
return [pt[0] + direction * normalizedAxis[0], pt[1] + direction * normalizedAxis[1]]; | |
}) | |
var points = spinePoints.concat(offsetPoints.reverse()); | |
return "M" + points.join("L"); | |
} | |
function getBlobbyPath(spinePoints, origin, magnitude) { | |
var axisOrigin = origin || [0,0]; | |
var axisMagnitude = magnitude || 0; | |
var line = d3.svg.line().interpolate('basis'); | |
var offsetPoints = spinePoints.slice(0).map(function(pt,i) { | |
var axis = [axisOrigin[0] - pt[0], axisOrigin[1] - pt[1]]; | |
var axisNorm = distance([0,0], axis); | |
var normalizedAxis = axis.map(function(d,i) { return (d / axisNorm) * magnitude; }); | |
var direction = (i % 2 == 0) ? 1 : -1; | |
return [ | |
pt[0] + normalizedAxis[0] + direction * normalizedAxis[0], | |
pt[1] + normalizedAxis[1] + direction * normalizedAxis[1] | |
]; | |
}) | |
var offsetPoints2 = spinePoints.slice(0).map(function(pt,i) { | |
var axis = [axisOrigin[0] - pt[0], axisOrigin[1] - pt[1]]; | |
var axisNorm = distance([0,0], axis); | |
var normalizedAxis = axis.map(function(d,i) { return (d / axisNorm) * magnitude; }); | |
var direction = (i % 2 == 0) ? -1 : 1; | |
return [ | |
pt[0] - normalizedAxis[0] - direction * normalizedAxis[0], | |
pt[1] - normalizedAxis[1] - direction * normalizedAxis[1] | |
]; | |
}) | |
var points = offsetPoints.concat(offsetPoints2.reverse()); | |
return line(points) +'Z'; | |
} | |
function distance(a,b) { | |
var x = b[0] - a[0]; | |
var y = b[1] - a[1]; | |
return Math.sqrt(Math.pow(x,2) + Math.pow(y,2)); | |
} | |
// https://en.wikipedia.org/wiki/Square_wave | |
function makeSquareWave(numberOfTerms, frequency, amplitude) { | |
return function(t) { | |
var terms = d3.range(numberOfTerms).map(function(i) { | |
var k = i + 1; //1-indexed | |
return Math.sin( 2 * Math.PI * (2 * k - 1) * frequency * t ) / (2 * k - 1) | |
}) | |
return amplitude * 4/Math.PI * d3.sum(terms); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |
<svg width="254px" height="373px" viewBox="0 0 254 373" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"> | |
<title>Untitled</title> | |
<description>Created with Sketch (http://www.bohemiancoding.com/sketch)</description> | |
<defs></defs> | |
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage"> | |
<path d="M192.957031,13.3476562 C118.351563,-6.1484375 67.6874998,-6.71875008 40.1914063,49 C12.6953125,104.71875 -29.3437414,149.187496 35.2304688,176.628906 C99.8046875,204.070314 162.765625,170.722656 162.765625,170.722656 C162.765625,170.722656 218.917967,124.47656 240.84375,169.636719 C262.769533,214.796877 256.210937,302.421875 218.652344,323.265625 C181.093752,344.109377 139.624997,408.289063 31.1054688,344.457031" id="Path-1" stroke="#979797" sketch:type="MSShapeGroup"></path> | |
</g> | |
</svg> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment