Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chrome transforms text differently over a canvas element. Why?

It seems that Chrome forces hardware-accelerated transforms on text that is on top of a canvas element.

Can anyone help me understand this behavior? Ultimately, I'd like to scale text on top of a canvas element without having the text converted to a texture.

This fiddle shows the issue: http://jsfiddle.net/Gb6h4/1/

Here is the code:

// Get a reference to the canvas and its context
var $canvas = $("canvas");
var ctx = $canvas[0].getContext('2d');

// Make the canvas fullscreen
var width = $(window).width(),
    height = $(window).height();
$canvas.attr({
    width: width,
    height: height
});

// In Chrome, modifying the canvas context in any way
// seems to force a hardware-accelerated transform
// on the text.
// (The text is scaled as a texture, becoming blurrier.)

// Uncomment the line below and compare the difference.
// ctx.fillStyle = "grey";

// Set up a simple zoom animation on our "Hello!" div
var $div = $(".transformed");
var scale = 1;
setInterval(function () {
    scale += 0.005;
    $div.css({
        transform: "translate(0px, 0px) scale("+scale+")"
    });
}, 16);

In the fiddle, by default, the text scales as expected (i.e., a non-accelerated CSS transform). However, after interaction with the canvas context, the text scales differently (as it would in an accelerated transform).

like image 280
akbr Avatar asked Nov 02 '22 08:11

akbr


1 Answers

This is a a side-effect of how CSS transforms work on composited layers in Chrome today.

An accelerated 2D context causes a RenderLayer to get its own compositing layer. Moreover, a layer that has a composited sibling with a lower z-index also gets its own compositing layer.

See http://www.chromium.org/developers/design-documents/gpu-accelerated-compositing-in-chrome

Relevant bug report: https://code.google.com/p/chromium/issues/detail?id=122083.

like image 87
akbr Avatar answered Nov 13 '22 04:11

akbr