diff --git a/gradients-v2.js b/gradients-v2.js new file mode 100644 index 0000000..d71e753 --- /dev/null +++ b/gradients-v2.js @@ -0,0 +1,184 @@ +'use strict'; + +/** + * + */ +function Point(x, y, hex) { + if (typeof x !== typeof 1) { + throw new Error("x = " + x + " must be of type 'number'; it is currently of type '" + (typeof x) + "'."); + } + + if (typeof y !== typeof 1) { + throw new Error("y = " + y + " must be of type 'number'; it is currently of type '" + (typeof y) + "'."); + } + + if (x < 0 || y < 0) { + throw new Error("X and Y must be greater than 0."); + } + + this.x = x; + this.y = y; + this.hex = hex; +} + +/** + * + */ +function Triangle(p1, p2, p3) { + if (!(p1 instanceof Point) || !(p2 instanceof Point) || !(p3 instanceof Point)) { + throw new Error("All three arguments must be of type Point."); + } + + this.vertexA = p1; + this.vertexB = p2; + this.vertexC = p3; + + // Midpoints on each edge. + this.midpointAB = this.findMidpoint(this.vertexA, this.vertexB); + this.midpointAC = this.findMidpoint(this.vertexA, this.vertexC); + this.midpointBC = this.findMidpoint(this.vertexB, this.vertexC); + + // Midpoints of segments between midpoints. + this.midpointABAC = this.findMidpoint(this.midpointAB, this.midpointAC); + this.midpointABBC = this.findMidpoint(this.midpointAB, this.midpointBC); + this.midpointACBC = this.findMidpoint(this.midpointAC, this.midpointBC); + + // Paths created from a vertex and the midpoints on its two adjacent edges. + this.subpathA = [this.vertexA, this.midpointAB, this.midpointAC]; + this.subpathB = [this.vertexB, this.midpointAB, this.midpointBC]; + this.subpathC = [this.vertexC, this.midpointAC, this.midpointBC]; +} + +/** + * + */ +Triangle.prototype = { + /** + * + */ + findMidpoint: function(p1, p2) { + var minX = Math.min(p1.x, p2.x); + var maxX = Math.max(p1.x, p2.x); + var minY = Math.min(p1.y, p2.y); + var maxY = Math.max(p1.y, p2.y); + + var midX = minX + ((maxX - minX) / 2); + var midY = minY + ((maxY - minY) / 2); + + return new Point(midX, midY); + }, + + + /** + * + */ + buildPath: function(p1, p2, p3, fill) { + var path = d3.select(document.createElementNS(d3.ns.prefix.svg, "path")) + .attr("d", `M${p1.x},${p1.y} L${p2.x},${p2.y} L${p3.x},${p3.y} Z`) + // .attr("stroke", "#000") + + var hex = /^#[\da-f]{3}$|^#[\da-f]{6}$/i; + + if (fill !== undefined) { + if (fill.match(hex)) { + path.attr("fill", fill).attr("stroke", fill); + } + else { + path.attr("fill", `url(#${fill})`) + // .attr("stroke", `url(#${fill})`); + } + } + + return function() { + return path.node(); + }; + }, + + /** + * + */ + buildGradient: function(p1, p2, id, hex) { + var fill = d3.select(document.createElementNS(d3.ns.prefix.svg, "linearGradient")) + .attr("gradientUnits", "userSpaceOnUse") + .attr("id", id) + .attr("x1", p1.x) + .attr("y1", p1.y) + .attr("x2", p2.x) + .attr("y2", p2.y) + + fill.append("stop") + .attr("offset", "0%") + .attr("stop-color", hex) + + fill.append("stop") + .attr("offset", "100%") + .attr("stop-color", "#fff") + .attr("stop-opacity", "0") + + return function() { + return fill.node(); + }; + }, +}; + +/** + * + */ +(function() { + var svg = d3.select("body").append("svg") + .attr("width", 500) + .attr("height", 500); + + var defs = svg.append("defs"); + + var points = [ + [ + new Point(100, 0, '#f00'), + new Point(200, 200, '#0f0'), + new Point(0, 300, '#00f') + ] + + // [ + // new Point(100, 0, '#f00'), + // new Point(200, 200, '#0f0'), + // new Point(300, 0, '#00f') + // ], + + // [ + // new Point(300, 300, '#f00'), + // new Point(200, 200, '#0f0'), + // new Point(300, 0, '#00f') + // ], + ]; + + var subpathA; + var subpathB; + var subpathC; + var subpathM1; + var subpathM2; + var subpathM3; + + for (var i = 0, len = points.length; i < len; i++) { + var T = new Triangle(points[i][0], points[i][1], points[i][2]); + + subpathA = T.buildPath(T.subpathA[0], T.subpathA[1], T.subpathA[2], points[i][0].hex); + subpathB = T.buildPath(T.subpathB[0], T.subpathB[1], T.subpathB[2], points[i][1].hex); + subpathC = T.buildPath(T.subpathC[0], T.subpathC[1], T.subpathC[2], points[i][2].hex); + + defs.append(T.buildGradient(T.midpointACBC, T.midpointBC, `fill-${i}-0`, points[i][0].hex)); + defs.append(T.buildGradient(T.midpointABBC, T.midpointAC, `fill-${i}-1`, points[i][1].hex)); + defs.append(T.buildGradient(T.midpointABAC, T.midpointAB, `fill-${i}-2`, points[i][2].hex)); + + subpathM1 = T.buildPath(T.midpointAB, T.midpointAC, T.midpointBC, `fill-${i}-0`); + subpathM2 = T.buildPath(T.midpointAB, T.midpointAC, T.midpointBC, `fill-${i}-1`); + subpathM3 = T.buildPath(T.midpointAB, T.midpointAC, T.midpointBC, `fill-${i}-2`); + + svg.append(subpathA); + svg.append(subpathB); + svg.append(subpathC); + + svg.append(subpathM1); + svg.append(subpathM2); + svg.append(subpathM3); + } +}()); diff --git a/index.html b/index.html index f2fc3da..3edf511 100644 --- a/index.html +++ b/index.html @@ -64,8 +64,8 @@ - - + +