Trying to draw the contrast between a stressed and relaxed mind in d3.
Last active
May 16, 2017 05:55
-
-
Save EmilienDupont/56f9b40b3284f49d88ad4be0cb622f5d to your computer and use it in GitHub Desktop.
Mind
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> | |
<meta charset='utf-8'> | |
<style> | |
body { | |
background: #222 | |
} | |
</style> | |
<body> | |
<script src="https://d3js.org/d3.v3.min.js"></script> | |
<script src="https://d3js.org/d3-color.v1.min.js"></script> | |
<script src="https://d3js.org/d3-interpolate.v1.min.js"></script> | |
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script> | |
<script> | |
var width = 960, | |
height = 500, | |
then = 0, // intial time step | |
base_velocity = 0.001, // rotation speed | |
theta_time = 0; // angle as a function of time | |
// Set up colors | |
var colors = [], | |
num_colors = 7; | |
for (var i = 0; i < num_colors; i++) { | |
colors.push(d3.interpolateGnBu(i / num_colors)) | |
} | |
var svg = d3.select('body') | |
.append('svg') | |
.attr('width', width) | |
.attr('height', height); | |
var center = {'x': width/2, 'y': height/2}; | |
/* Helper functions */ | |
function get_random_item(items) { | |
return items[Math.floor(Math.random() * items.length)]; | |
} | |
function angles_to_x_y(radius, theta, phi) { | |
// Get x, y coordinates of ellipse | |
var point = ellipse_coords(radius, theta); | |
// Tilt ellipse | |
var tilted_point = rotate(point, phi) | |
// Shift ellipse to center | |
return translate(tilted_point, center); | |
} | |
function ellipse_coords(radius, theta) { | |
return {'x': radius.x * Math.cos(theta), | |
'y': radius.y * Math.sin(theta)}; | |
} | |
function rotate(point, phi) { | |
return {'x': point.x * Math.cos(phi) - point.y * Math.sin(phi), | |
'y': point.x * Math.sin(phi) + point.y * Math.cos(phi)}; | |
} | |
function translate(point, shift) { | |
return {'x': point.x + shift.x, | |
'y': point.y + shift.y}; | |
} | |
function depth_proj(theta) { | |
return 1 + 0.5 * Math.sin(theta); | |
} | |
function get_particle() { | |
// could be interesting to make e.g. smaller particles faster and travelling | |
// at a larger radius | |
var tilt = Math.PI * (0.5 - Math.random()); | |
traj_rx = 1 / (Math.abs(tilt) + 1) * width / 3. * Math.random(); | |
traj_ry = tilt / Math.PI * height / 8. * Math.random(); | |
var particle = {'size' : 3 * Math.random() + 3, | |
'theta_init' : 2 * Math.PI * Math.random(), | |
'phi' : tilt, | |
'traj_radius' : {'x': traj_rx, 'y': traj_ry}, | |
'velocity' : 2 * Math.random() + 2, | |
'color' : get_random_item(colors)}; | |
return particle | |
} | |
function get_particles(num_particles) { | |
var particles = []; | |
for (i = 0; i < num_particles; i++) { | |
particles.push(get_particle()) | |
} | |
return particles; | |
} | |
/* Set up particles */ | |
var particles_data = get_particles(400); | |
var particles = svg.selectAll('.particle') | |
.data(particles_data) | |
.enter() | |
.append('circle') | |
.style('mix-blend-mode', 'screen') | |
.attr('class', 'particle') | |
.attr('cx', function(d) { return angles_to_x_y(d.traj_radius, d.theta_init, d.phi).x; }) | |
.attr('cy', function(d) { return angles_to_x_y(d.traj_radius, d.theta_init, d.phi).y; }) | |
.attr('r', function(d) { return d.size * depth_proj(d.theta_init); }) | |
.attr('fill', function(d) { return d.color; }); | |
function redraw(theta) { | |
particles.attr('cx', function(d) { return angles_to_x_y(d.traj_radius, d.theta_init + d.velocity * theta, d.phi).x; }) | |
.attr('cy', function(d) { return angles_to_x_y(d.traj_radius, d.theta_init + d.velocity * theta, d.phi).y; }) | |
.attr('r', function(d) { return d.size * depth_proj(d.theta_init + d.velocity * theta); }); | |
} | |
d3.timer(function(elapsed) { | |
// Periodically slow down and speed up rotation | |
if (elapsed % 15000 > 5000) { | |
base_velocity = 0.0001; | |
} else { | |
base_velocity = 0.001; | |
} | |
theta_time = theta_time + base_velocity * (elapsed - then); | |
redraw(theta_time); | |
then = elapsed; | |
}) | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment