var width = 500, height = 70, font = '18px serif' function getRetinaRatio() { var devicePixelRatio = window.devicePixelRatio || 1 var c = document.createElement('canvas').getContext('2d') var backingStoreRatio = [ c.webkitBackingStorePixelRatio, c.mozBackingStorePixelRatio, c.msBackingStorePixelRatio, c.oBackingStorePixelRatio, c.backingStorePixelRatio, 1 ].reduce(function(a, b) { return a || b }) return devicePixelRatio / backingStoreRatio } var ratio = getRetinaRatio() var scaledWidth = width * ratio var scaledHeight = height * ratio var blurredCanvas = d3.select('body').append('canvas') .attr('width', scaledWidth / 2) .attr('height', scaledHeight / 2) .style('width', width + 'px') .style('height', height + 'px') var goodCanvas = d3.select('body').append('canvas') .attr('width', scaledWidth) .attr('height', scaledHeight) .style('width', width + 'px') .style('height', height + 'px') var blurredContext = blurredCanvas.node().getContext('2d') blurredContext.scale(ratio / 2, ratio / 2) blurredContext.font = font blurredContext.fillText("Half of native scale. Blurred image.", 10, 20) blurredContext.fillText("This happens when you forget about retina screens.", 10, 45) var goodContext = goodCanvas.node().getContext('2d') goodContext.scale(ratio, ratio) goodContext.font = font goodContext.fillText("Native scale. Exact pixel match.", 10, 20) goodContext.fillText("Show some respect to users, scale your canvas!", 10, 45)