You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

211 lines
5.0 KiB

'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();