More mouseover aliasing.
rasterizeText
from Andrew Mollica. Canvas is super fast!
More mouseover aliasing.
rasterizeText
from Andrew Mollica. Canvas is super fast!
<!DOCTYPE html> | |
<meta charset='utf-8'> | |
<body style='background: #fff;'> | |
<canvas width='960' height='300'></canvas> | |
</body> | |
<script src='//d3js.org/d3.v4.min.js'></script> | |
<script> | |
var width = 960 | |
var height = 300 | |
var canvas = d3.select('canvas').node() | |
var ctx = canvas.getContext('2d'); | |
var pixels | |
function renderSize(s, fontSize){ | |
pixels = rasterizeText('Words', {spacing: s, fontSize: fontSize + 'px', height: height}) | |
ctx.clearRect(0, 0, width, height); | |
ctx.beginPath() | |
pixels.forEach(function(d){ | |
ctx.rect(d[0], d[1], s - s/10, s - s/10) | |
// draw circles instead | |
// ctx.moveTo(d[0] + s, d[1]); | |
// ctx.arc(d[0], d[1], s, 0, 2 * Math.PI); | |
}) | |
ctx.fill() | |
} | |
d3.select('body').on('mousemove', function(){ | |
var pos = d3.mouse(this) | |
var s = d3.scaleLinear().domain([0, width]).range([2, 20])(pos[0]) | |
var fontSize = d3.scaleLinear().domain([0, height]).range([50, 800])(pos[1]) | |
renderSize(s, fontSize) | |
}) | |
function rasterizeText(text, options) { | |
var o = options || {}; | |
var fontSize = o.fontSize || "300px", | |
fontWeight = o.fontWeight || "600", | |
fontFamily = o.fontFamily || "sans-serif", | |
textAlign = o.center || "center", | |
textBaseline = o.textBaseline || "middle", | |
spacing = o.spacing || 10, | |
width = o.width || 960, | |
height = o.height || 500, | |
x = o.x || (width / 2), | |
y = o.y || (height / 2); | |
var canvas = document.createElement("canvas"); | |
canvas.width = width; | |
canvas.height = height; | |
var context = canvas.getContext("2d"); | |
context.font = [fontWeight, fontSize, fontFamily].join(" "); | |
context.textAlign = textAlign; | |
context.textBaseline = textBaseline; | |
var dx = context.measureText(text).width, | |
dy = +fontSize.replace("px", ""), | |
bBox = [[x - dx / 2, y - dy / 2], [x + dx / 2, y + dy / 2]]; | |
bBox[0][0] = Math.max(0, bBox[0][0]) | |
bBox[0][1] = Math.max(0, bBox[0][1]) | |
bBox[1][0] = Math.min(width, bBox[1][0]) | |
bBox[1][1] = Math.min(height, bBox[1][1]) | |
context.fillText(text, x, y); | |
var imageData = context.getImageData(0, 0, width, height); | |
var pixels = []; | |
for (var x = bBox[0][0]; x < bBox[1][0]; x += spacing) { | |
for (var y = bBox[0][1]; y < bBox[1][1]; y += spacing) { | |
var pixel = getPixel(imageData, x, y); | |
if (pixel[3] != 0) pixels.push([x, y]); | |
} | |
} | |
return pixels; | |
} | |
function getPixel(imageData, x, y) { | |
var i = 4 * (parseInt(x) + parseInt(y) * imageData.width); | |
var d = imageData.data; | |
return [ d[i], d[i+1], d[i+2], d[i+3] ]; | |
} | |
d3.select(self.frameElement).style('height', height + 'px'); | |
</script> |