Search code examples
javascriptkineticjs

Cant' change KineticJS 5.0.1 PixelRatio


Building a canvas with KineticJS 5.0.1 and it looks awful on my Retina screen. I couldn't figure out what was going on because KineticJS jsfiddle's look just fine. Then I realized that jsfiddle uses version 4.3.1. Switched and now everything is beautiful and retina.

Why doesn't v5 handle this automatically anymore? And how can I fix it? I tried to set Kinetic.pixelRatio=2 but that didn't do anything.


Solution

  • It turns out that pixelRatio is hard-coded into kineticJS v5+. This is due to some sort of zooming/scaling issue and also, in part, performance issues. I am going to experiment but in the meantime, this can be easily fixed in the source code for kineticJS. Find this function:

    ;(function() {
        // calculate pixel ratio
        var canvas = Kinetic.Util.createCanvasElement(),
            context = canvas.getContext('2d'),
            // if using a mobile device, calculate the pixel ratio.  Otherwise, just use
            // 1.  For desktop browsers, if the user has zoom enabled, it affects the pixel ratio
            // and causes artifacts on the canvas.  As of 02/26/2014, there doesn't seem to be a way
            // to reliably calculate the browser zoom for modern browsers, which is why we just set
            // the pixel ratio to 1 for desktops
            _pixelRatio = Kinetic.UA.mobile ? (function() {
                var devicePixelRatio = window.devicePixelRatio || 1,
                backingStoreRatio = context.webkitBackingStorePixelRatio
                    || context.mozBackingStorePixelRatio
                    || context.msBackingStorePixelRatio
                    || context.oBackingStorePixelRatio
                    || context.backingStorePixelRatio
                    || 1;
                return devicePixelRatio / backingStoreRatio;
            })() : 1;
    

    And change the 1 on the very last line to window.devicePixelRatio. The performance really isn't so bad but I think what I'm going to try doing, since my use just needs a short animation for many objects when a button is pressed, is to have it animate in KineticJS at pixelRatio 1 and then clear it and redraw the finished product at pixelRatio=whatever is appropriate for the device.