diff --git a/gradients-v3.js b/gradients-v3.js new file mode 100644 index 0000000..fc851ca --- /dev/null +++ b/gradients-v3.js @@ -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(); diff --git a/index.html b/index.html index 7c908e2..84395b8 100644 --- a/index.html +++ b/index.html @@ -60,18 +60,20 @@
- - + + - - + +