Skip to content

Instantly share code, notes, and snippets.

@tophtucker
Last active May 12, 2016 03:58
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 tophtucker/0f828c44231f02fa433b to your computer and use it in GitHub Desktop.
Save tophtucker/0f828c44231f02fa433b to your computer and use it in GitHub Desktop.
Slander
<!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>
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;*/
}
// 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);
}
}
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment