Funktion
Funktion

Reputation: 559

EaselJS object positions change when scaling canvas

I'm scaling my canvas using the following resize function:

function resize() {
    var w, h;
    var size = [1920, 1080];
    ratio = size[0] / size[1];
    if (window.innerWidth / window.innerHeight >= ratio) {
        w = window.innerHeight * ratio;
        h = window.innerHeight;
    } else {
        w = window.innerWidth;
        h = window.innerWidth / ratio;
    }
    $('canvas').width(w);
    $('canvas').height(h);

    var scale = w/1920;
    stage.scaleX = stage.scaleY = scale;

}
window.onresize = resize;

With HTML and CSS

<canvas width="1920" height="1080"></canvas>
<style>
   canvas {
       width: 1920px;
       height: 1080px;
       position: absolute;
       top: 50%;
       left: 50%;
       transform: translate(-50%,-50%);
   }
</style>

This works perfectly for the stage itself, but the content scaling and positions seem to shift and are not working.

So if I later have:

some_container.y = 1000;

That renders in the middle on a biggish canvas, but as I resize it moves closer to the top and, seemingly at least, isn't in proportion either.

So I guess I somehow have to apply the same ratio to the positions, but I just can't seem to get the formula right. Any help would be appreciated.

This example (https://codepen.io/funktion/pen/JwwwBx) seems to scale and move correctly.

On trial and error, I've discovered that the problem lies with the ticker...

createjs.Ticker.addEventListener("tick", tick);

function tick(event) {
    if (!event.paused) {
        stage.update();
    }
}

BUT...I DO need the ticker for animation. Any thoughts would be greatly appreciated.

Upvotes: 0

Views: 855

Answers (1)

Lanny
Lanny

Reputation: 11294

A few notes:

  1. Scaling the stage is not super-advisable. There are some reported issues with mouse interaction. Better to put stuff in a container and scale that
  2. If you do scale a container (or the stage), the coordinates will scale too. So something at [50,50] in a container scaled 2x would still say they were at [50,50], but would visually be at [100,100].
  3. Scaling a canvas using CSS is not advisable. It transforms the pixels. It is better to set the width and height of the canvas to the size you want. Sometimes we set the canvas to 2x or 0.5x the number of pixels, and then counter-scale it with CSS to basically "zoom" it. Its a good way to either have less pixels (less fidelity, faster), or more (high-resolution), but that would be the only time I would use CSS.

I updated your codepen with the following resize code, and it worked well (I think)

Before (CSS scaling)

$('canvas').width(w);
$('canvas').height(h);

After (JS scaling)

stage.canvas.width = w;
stage.canvas.height = h;
stage.update(); // Must update because a resize clears the stage.

I also got rid of the CSS width/height on the canvas. Here is an updated pen: https://codepen.io/lannymcnie/pen/vvPLWb

I hope that makes sense.

Upvotes: 1

Related Questions