Skip to content

Commit

Permalink
merge pull request qrohlf#7 from tdhsmith/gh-pages
Browse files Browse the repository at this point in the history
  • Loading branch information
qrohlf committed Apr 16, 2014
2 parents 474cb76 + 3abd63c commit 1ec4dcc
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 29 deletions.
167 changes: 139 additions & 28 deletions trianglify.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ function Trianglify(options) {
cellpadding: defaults(options.cellpadding, 0.1*options.cellsize || 15),
noiseIntensity: defaults(options.noiseIntensity, 0.3),
x_gradient: defaults(options.x_gradient, Trianglify.randomColor()),
format: defaults(options.format, "svg"),
}
this.options.y_gradient = options.y_gradient || this.options.x_gradient.map(function(c){return d3.rgb(c).brighter(.5)})
function defaults(opt, def) {
Expand Down Expand Up @@ -42,21 +43,21 @@ Trianglify.Pattern = function(options, width, height) {
this.options = options
this.width = width;
this.height = height;
this.svg = this.generateSVG();
this.polys = this.generatePolygons();

var s = new XMLSerializer();
this.svgString = s.serializeToString(this.svg);
this.base64 = btoa(this.svgString);
this.dataUri = 'data:image/svg+xml;base64,' + this.base64;
this.dataUrl = 'url('+this.dataUri+')';
if (options.format === undefined || options.format === "svg" || options.format === "image/svg+xml") {
this.toVector();
} else {
this.toImage(options.format);
}
}

Trianglify.Pattern.prototype.append = function() {
document.body.appendChild(this.svg);
}

Trianglify.Pattern.gradient_2d = function (x_gradient, y_gradient, width, height) {

return function(x, y) {
var color_x = d3.scale.linear()
.range(x_gradient)
Expand All @@ -68,43 +69,61 @@ Trianglify.Pattern.gradient_2d = function (x_gradient, y_gradient, width, height
}
}

Trianglify.Pattern.prototype.generateSVG = function () {
Trianglify.Pattern.prototype.generatePolygons = function () {
var options = this.options;
cellsX = Math.ceil((this.width+options.bleed*2)/options.cellsize),
cellsY = Math.ceil((this.height+options.bleed*2)/options.cellsize),
color = Trianglify.Pattern.gradient_2d(options.x_gradient, options.y_gradient, this.width, this.height);
cellsY = Math.ceil((this.height+options.bleed*2)/options.cellsize);

var vertices = d3.range(cellsX*cellsY).map(function(d) {
// figure out which cell we are in
var col = d % cellsX;
var row = Math.floor(d / cellsX);
// put a point in that cell
var x = -options.bleed + col*options.cellsize + Math.random() * (options.cellsize - options.cellpadding*2) + options.cellpadding;
var y = -options.bleed + row*options.cellsize + Math.random() * (options.cellsize - options.cellpadding*2) + options.cellpadding;
return [x, y]; // Populate the actual background with points
// figure out which cell we are in
var col = d % cellsX;
var row = Math.floor(d / cellsX);
var x = -options.bleed + col*options.cellsize + Math.random() * (options.cellsize - options.cellpadding*2) + options.cellpadding;
var y = -options.bleed + row*options.cellsize + Math.random() * (options.cellsize - options.cellpadding*2) + options.cellpadding;
// return [x*cellsize, y*cellsize];
return [x, y]; // Populate the actual background with points
});

return d3.geom.delaunay(vertices);
}


Trianglify.Pattern.prototype.buildSVG = function () {
var options = this.options;
color = Trianglify.Pattern.gradient_2d(options.x_gradient, options.y_gradient, this.width, this.height);

var elem = document.createElementNS("http://www.w3.org/2000/svg", "svg");
var svg = d3.select(elem);

svg.attr("width", this.width);
svg.attr("height", this.height);
svg.attr('xmlns', 'http://www.w3.org/2000/svg');
var group = svg.append("g");


if (options.noiseIntensity > 0.01) {
var filter = svg.append("filter").attr("id", "noise");

var noise = filter.append('feTurbulence').attr('type', 'fractalNoise').attr('in', 'fillPaint').attr('fill', '#F00').attr('baseFrequency', 0.7).attr('numOctaves', '10').attr('stitchTiles', 'stitch');
var transfer = filter.append('feComponentTransfer');
transfer.append('feFuncR').attr('type', 'linear').attr('slope', '2').attr('intercept', '-.5');
transfer.append('feFuncG').attr('type', 'linear').attr('slope', '2').attr('intercept', '-.5');
transfer.append('feFuncB').attr('type', 'linear').attr('slope', '2').attr('intercept', '-.5');
filter.append('feColorMatrix').attr('type', 'matrix').attr('values', "0.3333 0.3333 0.3333 0 0 \n 0.3333 0.3333 0.3333 0 0 \n 0.3333 0.3333 0.3333 0 0 \n 0 0 0 1 0")
var filterRect = svg.append("rect").attr("opacity", options.noiseIntensity).attr('width', '100%').attr('height', '100%').attr("filter", "url(#noise)");
var filter = svg.append("filter").attr("id", "noise");

var noise = filter.append('feTurbulence')
.attr('type', 'fractalNoise')
.attr('in', 'fillPaint')
.attr('fill', '#F00')
.attr('baseFrequency', 0.7)
.attr('numOctaves', '10')
.attr('stitchTiles', 'stitch');
var transfer = filter.append('feComponentTransfer');
transfer.append('feFuncR').attr('type', 'linear').attr('slope', '2').attr('intercept', '-.5');
transfer.append('feFuncG').attr('type', 'linear').attr('slope', '2').attr('intercept', '-.5');
transfer.append('feFuncB').attr('type', 'linear').attr('slope', '2').attr('intercept', '-.5');
filter.append('feColorMatrix').attr('type', 'matrix').attr('values', "0.3333 0.3333 0.3333 0 0 \n 0.3333 0.3333 0.3333 0 0 \n 0.3333 0.3333 0.3333 0 0 \n 0 0 0 1 0")
var filterRect = svg.append("rect")
.attr("opacity", options.noiseIntensity)
.attr('width', '100%')
.attr('height', '100%')
.attr("filter", "url(#noise)");
}
var polys = d3.geom.delaunay(vertices);
polys.forEach(function(d) {

this.polys.forEach(function(d) {
var x = (d[0][0] + d[1][0] + d[2][0])/3;
var y = (d[0][1] + d[1][1] + d[2][1])/3;
var c = color(x, y);
Expand All @@ -113,6 +132,98 @@ Trianglify.Pattern.prototype.generateSVG = function () {
return svg.node();
}

Trianglify.Pattern.prototype.drawToCanvas = function(ctx, forceSize, loc) {
if (!(ctx instanceof CanvasRenderingContext2D)) {
console.log("Must provide a 2D canvas rendering context.");
return;
}

var options = this.options;
color = Trianglify.Pattern.gradient_2d(options.x_gradient, options.y_gradient, this.width, this.height);

if (forceSize === true || forceSize === undefined) {
ctx.canvas.width = this.width;
ctx.canvas.height = this.height;
}

if (loc === undefined) {loc = [0,0];}

if (options.noiseIntensity > 0.01) {
console.log("Canvas-based exports do not yet support noiseIntensity; continuing without.");
}

this.polys.forEach(function(d) {
var x = (d[0][0] + d[1][0] + d[2][0])/3;
var y = (d[0][1] + d[1][1] + d[2][1])/3;

ctx.beginPath();
ctx.moveTo(loc[0]+d[0][0],loc[1]+d[0][1]);
ctx.lineTo(loc[0]+d[1][0],loc[1]+d[1][1]);
ctx.lineTo(loc[0]+d[2][0],loc[1]+d[2][1]);
ctx.lineTo(loc[0]+d[0][0],loc[1]+d[0][1]);
ctx.fillStyle = ctx.strokeStyle = color(x, y);
ctx.fill();
ctx.stroke(); // this prevents seams between the polygons
})
}

Trianglify.Pattern.prototype.toVector = function() {
this.svg = this.buildSVG();
var s = new XMLSerializer();
this.svgString = s.serializeToString(this.svg);
this.base64 = btoa(this.svgString);
this.dataUri = 'data:image/svg+xml;base64,' + this.base64;
this.dataUrl = 'url('+this.dataUri+')';
}

Trianglify.Pattern.prototype.toImage = function (format, ctx) {
if (format === undefined) {
format = "";
} else if (format.indexOf("/") < 0) {
format = "image/" + format;
}

if (format !== "image/png" && format !== "image/jpeg" && format !== "") {
console.log("Warning: image types other than PNG or JPEG may have very limited browser support. (Selected: "+format+")");
}

var deleteAfter = false;
if (!(ctx instanceof CanvasRenderingContext2D)) {
if (ctx === undefined) {
ctx = this.appendCanvas();
deleteAfter = true;
} else {
console.log("Must provide a 2D canvas rendering context or leave empty to generate new canvas.");
return;
}
} else {
this.drawToCanvas(ctx);
}

this.dataUri = ctx.canvas.toDataURL(format);
this.dataUrl = 'url('+this.dataUri+')';

if (deleteAfter) {
document.body.removeChild(ctx.canvas);
}
}

Trianglify.Pattern.prototype.append = function() {
document.body.appendChild(this.svg);
}

Trianglify.Pattern.prototype.appendCanvas = function (show) {
var cnv = document.createElement("canvas");
if (!show) {
cnv.style.display = "none";
}

document.body.appendChild(cnv);
var ctx = cnv.getContext("2d");
this.drawToCanvas(ctx);
return ctx;
}

//colorbrewer palettes from http://bl.ocks.org/mbostock/5577023
var colorbrewer = {YlGn: {
3: ["#f7fcb9","#addd8e","#31a354"],
Expand Down
Loading

0 comments on commit 1ec4dcc

Please sign in to comment.