|
<!doctype html> |
|
<head> |
|
<title>chromaphi</title> |
|
<style> |
|
body { |
|
width: 960px; |
|
height: 500px; |
|
text-align: center; |
|
} |
|
svg { |
|
display: block; |
|
width: 100%; |
|
height: 100%; |
|
} |
|
button { margin: 24px 0 12px 12px; } |
|
</style> |
|
<script src='http://d3js.org/d3.v3.min.js'></script> |
|
</head> |
|
|
|
<body> |
|
<script type='text/javascript'> |
|
|
|
/* VARS */ |
|
|
|
var _ = {}; |
|
|
|
_.n = 34; |
|
_.width = 160 / _.n; |
|
_.innerRadius = 60; |
|
_.outerRadius = 180; |
|
_.hMin = 0, _.hMax = 360; |
|
_.cMin = 15, _.cMax = 100; |
|
_.lMin = 15, _.lMax = 100; |
|
|
|
_.arc = |
|
d3.svg.arc() |
|
.startAngle(function(d) { return _.d2r( d.h - _.width / 2 ); }) |
|
.endAngle(function(d) { return _.d2r( d.h + _.width / 2 ); }) |
|
.innerRadius(function() { return _.innerRadius; }) |
|
.outerRadius(function() { return _.outerRadius; }); |
|
|
|
_.steps = [4, 6, 9, 14, 22, 35, 56, 90, 145, 224]; |
|
|
|
|
|
/* DOM */ |
|
|
|
var $body = d3.select('body'); |
|
|
|
var $input = |
|
$body |
|
.append('input') |
|
.attr('type', 'range') |
|
.attr('min', 2) |
|
.attr('max', 89) |
|
.attr('step', 1) |
|
.attr('value', _.n) |
|
.style('vertical-align', 'middle') |
|
.on('change', function() { _.update(this.value); }); |
|
|
|
var $button = |
|
$body |
|
.append('button') |
|
.on( 'click', function() { return _.draw(); }); |
|
|
|
var $g = |
|
$body |
|
.append('svg').attr('class', 'svg') |
|
.append('g') |
|
.attr( 'transform', 'translate(480, 200)' ); |
|
|
|
|
|
/* CONTROL */ |
|
|
|
_.init = |
|
function() { |
|
_.h = Math.random() * (_.hMax - _.hMin) + _.hMin; |
|
_.c = Math.random() * (_.cMax - _.cMin) + _.cMin; |
|
_.l = Math.random() * (_.lMax - _.lMin) + _.lMin; |
|
}; |
|
|
|
_.add = |
|
function(i) { |
|
_.h = _.nacc('h'); |
|
_.c = _.nacc('c'); |
|
_.l = _.nacc('l'); |
|
var step = _.steps.indexOf(i); |
|
if (step !== -1) { |
|
_.c = _.nacc('c'); |
|
_.l = _.nacc('l'); |
|
_.l = _.nacc('l'); |
|
if ( _.steps.indexOf(step + 1) !== -1 ) { |
|
_.c = _.nacc('c'); |
|
_.l = _.nacc('l'); |
|
_.l = _.nacc('l'); |
|
} |
|
} |
|
var $hcl = d3.hcl( _.h, _.c, _.l ).toString(); |
|
$g.selectAll('path:not(.ray)') |
|
.data( [{ h: _.h, c: _.c, l: _.l}] ).enter() |
|
.append('path').attr('class', 'ray') |
|
.attr('d', _.arc) |
|
.style('fill', function() { return $hcl; }) |
|
.append('title') |
|
.text( $hcl ); |
|
}; |
|
|
|
_.draw = |
|
function(i) { |
|
clearTimeout(_.timeout); |
|
i = i || 1; |
|
if (i === 1) { |
|
_.init(); |
|
d3.selectAll('.ray').remove(); |
|
} |
|
$button.style( 'color', d3.hcl(0, 0, 100 - i / _.n * 80).toString() ); |
|
_.timeout = setTimeout( function() { |
|
_.add(i); |
|
if (i++ < _.n) { |
|
_.draw(i); |
|
} |
|
}, 50); |
|
}; |
|
|
|
_.update = |
|
function(n) { |
|
_.n = n || _.n || 34; |
|
_.width = 160 / _.n; |
|
$button.text('generate ' + _.n + ' colors'); |
|
}; |
|
|
|
_.update(); |
|
_.init(); |
|
_.draw(); |
|
|
|
/* TOOLBELT */ |
|
|
|
_.fib = |
|
function(val, min, max) { |
|
var range = max - min; |
|
return ( ( (val - min) + (range * 1.618) ) % range ) + min; |
|
}; |
|
|
|
_.nacc = |
|
function(n) { |
|
return _.fib( _[n], _[n + 'Min'], _[n + 'Max'] ); |
|
}; |
|
|
|
_.d2r = |
|
function(d) { |
|
return d * Math.PI / 180; |
|
}; |
|
|
|
</script> |
|
</body> |