parent
94c13cf4e0
commit
4575df5e59
2 changed files with 217 additions and 5 deletions
@ -0,0 +1,211 @@ |
||||
'use strict'; |
||||
|
||||
/** |
||||
* |
||||
*/ |
||||
function Mesh() { |
||||
// // Color seed coordinants
|
||||
// this.seeds = [];
|
||||
|
||||
// Length of a side
|
||||
this.side = 10; |
||||
|
||||
// // How far a seed will extend its reach
|
||||
this.seedWeight = 40; |
||||
|
||||
//
|
||||
this.width = 400; |
||||
this.height = 400; |
||||
|
||||
var faces = this.initFaces(this.width, this.height, this.side); |
||||
|
||||
this.addSeed(new Seed(0, 0, '#ff0000', this.seedWeight), faces); |
||||
this.addSeed(new Seed(0, 39, '#0000ff', this.seedWeight), faces); |
||||
this.addSeed(new Seed(39, 0, '#00ff00', this.seedWeight), faces); |
||||
this.addSeed(new Seed(39, 39, '#ffff00', this.seedWeight), faces); |
||||
|
||||
this.calculateFills(faces); |
||||
|
||||
var svg = d3.select("body").append("svg").attr('width', this.width).attr('height', this.height); |
||||
|
||||
svg.selectAll('rect') |
||||
.data(faces) |
||||
.enter() |
||||
.append('rect') |
||||
.attr('id', function(d) { return d.id; }) |
||||
.attr('x', function(d) { return d.x; }) |
||||
.attr('y', function(d) { return d.y; }) |
||||
.attr('width', function(d) { return d.side; }) |
||||
.attr('height', function(d) { return d.side; }) |
||||
.attr('fill', function(d) { return d.fill; }) |
||||
.attr('stroke', 0) |
||||
|
||||
// d3.select(id).attr('fill', seed.fill);
|
||||
// for (var i = 0, len = seeds.length; i < len; i++) {
|
||||
// d3.select(seeds[i].faceId).attr('fill', seeds[i].fill);
|
||||
// }
|
||||
}; |
||||
|
||||
/** |
||||
* |
||||
*/ |
||||
function Face(id, x, y, side) { |
||||
this.id = id; |
||||
this.x = x; |
||||
this.y = y; |
||||
this.side = side; |
||||
this.fill = '#fff'; |
||||
this.colors = []; |
||||
}; |
||||
|
||||
/** |
||||
* |
||||
*/ |
||||
function Seed(x, y, fill, weight) { |
||||
this.x = x; |
||||
this.y = y; |
||||
this.fill = fill; |
||||
this.weight = weight; |
||||
}; |
||||
|
||||
/** |
||||
* |
||||
*/ |
||||
Mesh.prototype = { |
||||
/** |
||||
* Faces must be a one dimensional array to pass to D3. |
||||
*/ |
||||
initFaces: function(width, height, side) { |
||||
var countW = Math.ceil(width / side); |
||||
var countH = Math.ceil(height / side); |
||||
var all = []; |
||||
|
||||
for (var w = 0; w < countW; w++) { |
||||
for (var h = 0; h < countH; h++) { |
||||
all.push(new Face( |
||||
`f-${w}-${h}-${all.length}`, |
||||
w * side, |
||||
h * side, |
||||
side |
||||
)); |
||||
} |
||||
} |
||||
|
||||
return all; |
||||
}, |
||||
|
||||
/** |
||||
* |
||||
*/ |
||||
calculateFills: function(faces) { |
||||
var len = faces.length; |
||||
var hexes; |
||||
|
||||
var populate = function(color) { |
||||
var arr = []; |
||||
for (var k = 0; k < color.weight; k++) { |
||||
arr.push(color.hex); |
||||
} |
||||
return arr; |
||||
}; |
||||
|
||||
for (var i = 0; i < len; i++) { |
||||
var hexes = []; |
||||
|
||||
for (var j = 0; j < faces[i].colors.length; j++) { |
||||
hexes = hexes.concat(populate(faces[i].colors[j])); |
||||
} |
||||
|
||||
while (hexes.length < this.seedWeight) { |
||||
hexes.push('#ccccff'); |
||||
} |
||||
|
||||
faces[i].fill = Compositor.averageHexCollection(hexes); |
||||
} |
||||
}, |
||||
|
||||
/** |
||||
* |
||||
*/ |
||||
addSeed: function(seed, faces) { |
||||
var n = this.seedWeight; |
||||
var len = faces.length; |
||||
var delta, index, weight; |
||||
var countX = this.width / this.side; |
||||
var countY = this.height / this.side; |
||||
|
||||
for (var x = (seed.x - n + 1); x < seed.x + n; x++) { |
||||
if (x < 0 || x >= countX) { |
||||
continue; |
||||
} |
||||
|
||||
for (var y = (seed.y - n + 1); y < seed.y + n; y++) { |
||||
if (y < 0 || y >= countY) { |
||||
continue; |
||||
} |
||||
|
||||
// Diamond shapes around source drop weighting incrementally.
|
||||
delta = Math.abs(seed.x - x) + Math.abs(seed.y - y); |
||||
weight = Math.max(0, n - delta); |
||||
|
||||
index = x * countY + y; |
||||
|
||||
if (weight > 0 && index >= 0 && index < len) { |
||||
faces[index].colors.push({ hex: seed.fill, weight: weight }); |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
}; |
||||
|
||||
/** |
||||
* |
||||
*/ |
||||
var Compositor = { |
||||
/** |
||||
* |
||||
*/ |
||||
averageComponentCollection: function(collection) { |
||||
var len = collection.length; |
||||
var total = 0; |
||||
|
||||
for (var i = 0; i < len; i++) { |
||||
total += parseInt(collection[i], 16); |
||||
} |
||||
|
||||
var avg = Math.round(total / len); |
||||
avg = avg.toString(16); |
||||
avg = ('00' + avg).slice(-2); |
||||
|
||||
return avg; |
||||
}, |
||||
|
||||
/** |
||||
* |
||||
*/ |
||||
averageHexCollection: function(collection) { |
||||
// check hex against regex
|
||||
|
||||
var allR = []; |
||||
var allG = []; |
||||
var allB = []; |
||||
var len = collection.length; |
||||
var tmp, hex; |
||||
|
||||
for (var i = 0; i < len; i++) { |
||||
tmp = collection[i].substr(1); |
||||
|
||||
allR.push(tmp.substr(0, 2)); |
||||
allG.push(tmp.substr(2, 2)); |
||||
allB.push(tmp.substr(4, 2)); |
||||
} |
||||
|
||||
var r = this.averageComponentCollection(allR); |
||||
var g = this.averageComponentCollection(allG); |
||||
var b = this.averageComponentCollection(allB); |
||||
|
||||
return '#' + r + g + b; |
||||
}, |
||||
}; |
||||
|
||||
var mesh = new Mesh(); |
Loading…
Reference in new issue