Built with blockbuilder.org
forked from tonyhschu's block: Force Field
license: mit |
Built with blockbuilder.org
forked from tonyhschu's block: Force Field
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<style> | |
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
</style> | |
</head> | |
<body> | |
<script> | |
console.clear() | |
// Feel free to change or delete any of the code you see in this editor! | |
var WIDTH = 960 | |
var HEIGHT = 500 | |
var GRID = 20 | |
var mouse = [0, 0] | |
function sigmoid(t) { | |
return 1/(1+Math.pow(Math.E, -t)); | |
} | |
var svg = d3.select("body").append("svg") | |
.attr("style", "background: #333") | |
.attr("width", WIDTH) | |
.attr("height", HEIGHT) | |
.on("mousemove", function() { | |
mouse = d3.mouse(this); | |
paint() | |
}) | |
var vectors = d3.range(48 * 25) | |
.map(function(key) { | |
return { | |
x: key % 48 * GRID, | |
y: Math.floor(key / 48) * GRID, | |
theta: 0, | |
color: 0 | |
} | |
}) | |
var triangles = svg.selectAll("g") | |
.data(vectors).enter() | |
.append('g').each(function(d) { | |
var layer = d3.select(this) | |
layer.append('path') | |
.attr('fill', '#ccc') | |
.attr('d', 'M -4, 0 L 4, 2 L 4, -2 Z') | |
}) | |
var paint = function() { | |
vectors.forEach(function(d) { | |
var dx = d.x - mouse[0] | |
var dy = d.y - mouse[1] | |
var dist = Math.sqrt(dx * dx + dy * dy) | |
var dForce = (sigmoid((dist - 80) / 60) - 0.5) | |
var nt = Math.atan2(dy, dx) + Math.PI / 2 + Math.PI * -dForce | |
var r = Math.round(123 + dForce * 123) | |
var g = Math.round(123 - dForce * 123) | |
d.theta = nt | |
d.color = 'rgb('+ r + ',' + g + ', 0)'; | |
}) | |
triangles | |
.attr("transform", function(d) { | |
return "translate(" + d.x + ", " + d.y + ") rotate(" + (d.theta / Math.PI * 180) + ")"; | |
}) | |
.each(function(d) { | |
var path = d3.select(this).select('path') | |
path.attr('fill', d.color) | |
}) | |
} | |
paint() | |
</script> | |
</body> |