Created
March 6, 2012 09:31
-
-
Save lerouxb/1985295 to your computer and use it in GitHub Desktop.
Dynamically create a canvas to be used as an image placeholder.
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
<!doctype html> | |
<html> | |
<head> | |
<title>placehold.js</title> | |
<script> | |
/* | |
Dynamically create a canvas to be used as an image placeholder. | |
If you really want an <img>, you can use: | |
var dataURL = canvas.toDataURL("image/png"); | |
and then use the dataURL as the src="" of an image. | |
minWidth is for fluid layout support. The idea is that if your layout's | |
dimensions change, then you can re-render all the placeholder images to show | |
the width range for the columns they are going to be used in. | |
You then use it with some fluid <img> CSS so that the browser scales it | |
automatically. | |
*/ | |
var makePlaceholderCanvas = function(options) { | |
// the canvas width | |
options.maxWidth = options.maxWidth || 600; | |
// the canvas height | |
if (!options.maxHeight) { | |
// if the height wasn't set explicitly, we calculate it | |
// go with a third of the width... | |
options.maxHeight = options.maxWidth/3; | |
// ...but specify a minimum just in case | |
options.minHeight = options.minHeight || 60; | |
// and make sure we have an integer | |
options.maxHeight = Math.round( | |
Math.max(options.minHeight, options.maxHeight)); | |
} | |
// minimum text size (or where we start) | |
options.minFontSize = options.minFontSize || 10; | |
// this should cover osx/ios and the MS "standard web fonts" | |
options.fontName = options.fontName || 'helvetica neue, arial black'; | |
// try 'bold' or 'normal' | |
options.fontWeight = options.fontWeight || 'bold'; | |
// the canvas background colour | |
// rgb(238, 238, 238) == #eeeeee | |
options.background = options.background || "rgb(238,238,238)"; | |
// the text colour | |
// rgb(51, 51, 51) == #333333 | |
options.foreground = options.foreground || "rgb(51,51,51)"; | |
// maximum text dimensions to leave room for some padding | |
// (just default to half of the available width and height) | |
options.maxTextWidth = options.maxTextWidth || options.maxWidth/2; | |
options.maxTextHeight = options.maxTextHeight || options.maxHeight/2; | |
// font size increase between tries (see the while loop below) | |
options.increment = options.increment || 1; | |
// the text to display | |
if (!options.text) { | |
options.text = options.maxWidth+'px'; | |
if (options.minWidth) { | |
// if minWidth is specified, include that | |
options.text = options.minWidth+'-'+options.text; | |
} | |
} | |
var | |
canvas = document.createElement('canvas'), | |
ctx = canvas.getContext("2d"), | |
width = canvas.width = options.maxWidth, | |
height = canvas.height = options.maxHeight, | |
size = options.minFontSize, | |
maxTextWidth = options.maxTextWidth, | |
maxTextHeight = options.maxTextHeight, | |
trySize, | |
textWidth; | |
// try and make the text as big as possible while fitting | |
while (true) { | |
trySize = size + options.increment; | |
ctx.font = options.fontWeight+' '+trySize+'px '+options.fontName; | |
textWidth = ctx.measureText(options.text).width; | |
if (trySize > maxTextHeight || textWidth > maxTextWidth) { | |
break; | |
} else { | |
size = trySize; | |
} | |
} | |
ctx.font = options.fontWeight+' '+size+'px '+options.fontName; | |
ctx.fillStyle = options.background; | |
ctx.fillRect(0, 0, width, height); | |
ctx.fillStyle = options.foreground; | |
ctx.textAlign = 'center'; | |
ctx.textBaseline = 'middle'; | |
ctx.fillText(options.text, width/2, height/2, width); | |
return canvas; | |
}; | |
window.onload = function() { | |
// test! | |
var canvas = makePlaceholderCanvas({ | |
maxWidth: 500, | |
minWidth: 200 | |
}); | |
document.body.appendChild(canvas); | |
}; | |
</script> | |
<style> | |
body { | |
background-color: #ffffff; | |
padding: 10px; | |
} | |
</style> | |
</head> | |
<body> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment