-
-
Save addyosmani/53b1e5c89d109f19b71d to your computer and use it in GitHub Desktop.
π.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(window, document) { | |
'use strict'; | |
// π.js, because passy. | |
// Adapted from console images by Adrian Cooney | |
/** | |
* Since the console.log doesn't respond to the `display` style, | |
* setting a width and height has no effect. In fact, the only styles | |
* I've found it responds to is font-size, background-image and color. | |
* To combat the image repeating, we have to get a create a font bounding | |
* box so to speak with the unicode box characters. EDIT: See Readme.md | |
* | |
* @param {int} width The height of the box | |
* @param {int} height The width of the box | |
* @return {object} {string, css} | |
*/ | |
function getBox(width, height) { | |
return { | |
string: "+", | |
style: "font-size: 1px; padding: " + Math.floor(height / 2) + "px " + Math.floor(width / 2) + "px; line-height: " + height + "px;" | |
} | |
} | |
/** | |
* Draw's meme text on a context. | |
* | |
* @param {CanvasRenderingContext2D} ctx The canvas context | |
* @param {string} type "upper"|"lower" | |
* @param {string} text The text to draw | |
* @param {int} width The width of the image | |
* @param {int} y The y value to draw at | |
* @return {null} | |
*/ | |
function drawMemeText(ctx, type, text, width, y) { | |
text = text.toUpperCase(); | |
//Determine the font size | |
if (text.length < 24) { | |
var val = Math.max(0, text.length - 12), | |
size = 70 + (val * -3); | |
drawText(ctx, size, text, width / 2, y); | |
} else if (text.length < 29) { | |
drawText(ctx, 40, text, width / 2, y); | |
} else { | |
var strs = wrap(text, 27); | |
strs.forEach(function(str, i) { | |
drawText(ctx, 40, str, width / 2, (type == "lower") ? (y - ((strs.length - 1) * 40)) + (i * 40) : y + (i * 40)); | |
}); | |
} | |
} | |
/** | |
* Draws text in impact font with stroke on context | |
* | |
* @param {CanvasRenderingContext2D} ctx The canvas context | |
* @param {int} size Font size | |
* @param {string} text The string to write | |
* @param {int} x X Position | |
* @param {int} y Y position | |
* @return {null} | |
*/ | |
function drawText(ctx, size, text, x, y) { | |
//Set the text styles | |
ctx.font = "bold " + size + "px Impact"; | |
ctx.fillStyle = "#fff"; | |
ctx.textAlign = "center"; | |
ctx.textBaseline = "middle"; | |
ctx.lineWidth = 7; | |
ctx.strokeStyle = "#000"; | |
ctx.strokeText(text, x, y); | |
ctx.fillText(text, x, y); | |
} | |
/** | |
* Wrap a line of text at an index | |
* | |
* @param {string} text The text | |
* @param {int} num The index to wrap at | |
* @return {array} Array of text | |
*/ | |
function wrap(text, num) { | |
var output = [], | |
split = text.split(" "); | |
var str = []; | |
for (var i = 0, cache = split.length; i < cache; i++) { | |
if ((str + split[i]).length < num) str.push(split[i]) | |
else { | |
output.push(str.join(" ")); | |
str.length = 0; | |
str.push(split[i]); | |
} | |
} | |
//Push the final line | |
output.push(str.join(" ")); | |
return output; | |
} | |
/** | |
* Add a meme to the console! | |
* | |
* @param {string} upper The upper text | |
* @param {string} lower The lower text | |
* @param {string} image The meme type (see `console.meme` for all supported) or image url (Make sure it's CORS enabled) | |
* @param {int} width The width of the meme | |
* @param {int} height The height of the meme | |
* @return {null} | |
*/ | |
console.meme = function(upper, lower, image, width, height) { | |
if (!upper) console.error("Yo, you forgot the text for the upper part of the meme. The bit at the top. Yeah, that bit."); | |
if (!lower) console.error("You forgot the text for the bottom of the meme, stupid."); | |
if (!image) console.error("Dude, you forgot the meme type or url for the background image (CORS enabled, *hint* imgur *hint*). To see a list of supported memes, hit `console.meme()`"); | |
if (!upper && !lower && !image) return console.log("> " + Object.keys(memes).join("\n> ")); | |
var canvas = document.createElement("canvas"), | |
ctx = canvas.getContext("2d"), | |
width = width || 500, | |
height = width || 500, | |
//I tweaked it at these dimensions, | |
//So everything scales from here | |
_w = 500, | |
_h = 500; | |
var img = new Image(); | |
img.setAttribute('crossOrigin', 'anonymous'); | |
img.onload = function() { | |
canvas.width = width; | |
canvas.height = height; | |
var text = upper.toUpperCase(); | |
ctx.scale(width / 500, height / 500); | |
//Draw the background | |
ctx.drawImage(this, 0, 0, _w, _h); | |
drawMemeText(ctx, "upper", upper, _w, 50); //upper | |
drawMemeText(ctx, "lower", lower, _w, _h - 50); //upper | |
console.image(canvas.toDataURL()); | |
}; | |
if (memes[image]) var url = memes[image]; | |
else var url = image; | |
img.src = url; //"http://www.corsproxy.com/" + url.replace(/https?:\/\//, ""); | |
}; | |
/** | |
* Display an image in the console. | |
* @param {string} url The url of the image. | |
* @param {int} scale Scale factor on the image | |
* @return {null} | |
*/ | |
console.image = function(url, scale) { | |
scale = scale || 1; | |
var img = new Image(); | |
img.onload = function() { | |
var dim = getBox(this.width * scale, this.height * scale); | |
console.log("%c" + dim.string, dim.style + "background: url(" + url + "); background-size: " + (this.width * scale) + "px " + (this.height * scale) + "px; color: transparent;"); | |
}; | |
img.src = url; | |
}; | |
console.image('http://gifstumblr.com/images/pi-=-pie_1318.jpg'); | |
})(this, document); |
hemanth
commented
Feb 11, 2015
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment