最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - If I resize my canvas, my createJS text becames blurry - Stack Overflow

programmeradmin0浏览0评论

I'm using createJS to drawn inside the canvas. I have my canvas set to occupy the browser window maintaining aspect ratio using the resize() function.

This is the code:

    mytext = new createjs.Text("Lorem ipsum dolor sit amet 2","19px Calibri","#073949");
    mytext.x = 450
    mytext.y = 300;
    stage.addChild(mytext);  

    resize = function() {
                var canvas = document.getElementById('canvas');
                var canvasRatio = canvas.height / canvas.width;

                var windowRatio = window.innerHeight / window.innerWidth;
                var width;
                var height;

                if (windowRatio < canvasRatio) {
                    height = window.innerHeight - 35;
                    width = height / canvasRatio;
                } else {
                    width = window.innerWidth;
                    height = width * canvasRatio;
                }

                canvas.style.width = width + 'px';
                canvas.style.height = height + 'px';    
    }()

What happens is that the text gets blurry (decrease of quality) when the canvas resizes.

.png vs .png

How can I solve this issue?

I'm using createJS to drawn inside the canvas. I have my canvas set to occupy the browser window maintaining aspect ratio using the resize() function.

This is the code:

    mytext = new createjs.Text("Lorem ipsum dolor sit amet 2","19px Calibri","#073949");
    mytext.x = 450
    mytext.y = 300;
    stage.addChild(mytext);  

    resize = function() {
                var canvas = document.getElementById('canvas');
                var canvasRatio = canvas.height / canvas.width;

                var windowRatio = window.innerHeight / window.innerWidth;
                var width;
                var height;

                if (windowRatio < canvasRatio) {
                    height = window.innerHeight - 35;
                    width = height / canvasRatio;
                } else {
                    width = window.innerWidth;
                    height = width * canvasRatio;
                }

                canvas.style.width = width + 'px';
                canvas.style.height = height + 'px';    
    }()

What happens is that the text gets blurry (decrease of quality) when the canvas resizes.

https://i.sstatic/Jt43q.png vs https://i.sstatic/ZcGLO.png

How can I solve this issue?

Share Improve this question asked Sep 28, 2015 at 10:54 CondwardCondward 1353 silver badges13 bronze badges 2
  • Could you store the size of the original canvas width and height then depending on the resize calculate the new scales then redraw all elements correctly by the new width and height? For example. original Width = 400 original height = 400, after resize width is now 800 and height is now 600. Run the draw function like so. `mytext.x = 400 * (canvas.width / originalWidth); then do the same for height and font size – Canvas Commented Sep 28, 2015 at 11:22
  • I was trying to avoid that solution because I already built lots of games with tons of text and images and I would need to build a resize function for each game and also make up for the change of coordinates. But if that's the only solution I will have to apply it. – Condward Commented Sep 28, 2015 at 11:32
Add a ment  | 

5 Answers 5

Reset to default 3

Since you are using CreateJS, you can simply resize the canvas, and scale the entire stage to redraw everything at the new size:

// just showing width to simplify the example:
var newWidth = 800;
var scale = newWidth/myCanvas.width;
myCanvas.width = newWidth;
myStage.scaleX = myStage.scaleY = scale;
myStage.update(); // draw at the new size.

@Adam's answer is correct as far as scaling the canvas goes. You do NOT want to scale with CSS, as it will stretch your canvas instead of changing its pixel dimensions. Set the width and height of the canvas using JavaScript instead.

stage.canvas.width = window.innerWidth;
stage.canvas.height = window.innerHeight;

As you stated in your ment, this will only change the canvas size, and not reposition or scale your content. You will have to do this manually. This is fairly simple. Generally, I remend putting your "resize" listener in the JavaScript in your HTML file, rather than on a frame script.


First, determine the scale, based on the size of the window and the size of your content. You can use the exportRoot.nominalBounds.width and exportRoot.nominalBounds.height which is the bounds of the first frame. If you want to scale something else, use its nominalBounds instead.

Note that nominalBounds is appended to all MovieClips exported from Flash/Animate. If you enable multi-frame bounds, and want to use those, you will have to modify your approach.

The main idea is to use the original, unscaled size of your contents.

var bounds = exportRoot.nominalBounds;
// Uses the larger of the width or height. This will "fill" the viewport.
// Change to Math.min to "fit" instead.
var scale = Math.max(window.innerWidth / bounds.width, window.innerHeight / bounds.height);
exportRoot.scaleX = exportRoot.scaleY = scale;

You can then center it if you want.

exportRoot.x = *window.innerWidth - bounds.width*scale)/2;
exportRoot.y = *window.innerHeight - bounds.height*scale)/2;

Here is a quick sample of a responsive canvas using a simple shape as the scaling contents: http://jsfiddle/lannymcnie/4yy08pax/

Doing this with Flash/Animate CC export has e up a few times, so it is on my list of future EaselJS demos to include on createjs., and in the EaselJS GitHub.

I hope this helps.

Take a look at my jsfiddle : https://jsfiddle/CanvasCode/ecr7o551/1/

Basically you just store the original canvas size and then use that to work out new positions and sizes

html

<canvas id="canvas" width="400" height="400">
    Canvas was unable to start up.
</canvas>

<button onclick="resize()">Click me</button>

javascript

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');

var originalWidth = canvas.width;
var originalHeight = canvas.height;

render = function()
{
    context.fillStyle = "#DDD";
    context.fillRect(0,0, originalWidth * (canvas.width / originalWidth), originalHeight * (canvas.height / originalHeight));

    context.fillStyle = "#000";
    var fontSize = 48 * (canvas.width / originalWidth);
    context.font = fontSize+"px serif";
    context.fillText("Hello world", 100 * (canvas.width / originalWidth), 200 * (canvas.height / originalHeight));   
}

resize = function()
{
    canvas.width = 800;
    canvas.height = 600;
    render();
}

render();

The HTML5 canvas element works with two different sizes

  • Visual size on screen, controlled via CSS, like you're setting with canvas.style.width/height
  • Size of pixel buffer for the drawing, controlled via numeric width and height pixel attributes on the canvas element.

The browser will stretch the buffer to fit the size on screen, so if the two values are not 1:1 ratio text will look blurry.

Try adding the following lines to your code

canvas.width = width;
canvas.height = height;   

I created a function to resize all the elements on the screen after resizing the canvas. It saves the initial coordinates and scales for the elements with the original width of 900 px and then it changes them according to the current width ratio relative to the original width ratio. The text isn't blurry/bad quality anymore.

    resize = function() {
            var canvas = document.getElementById('canvas');
            var canvasRatio = canvas.height / canvas.width;

            var windowRatio = window.innerHeight / window.innerWidth;
            var width;
            var height;

            if (windowRatio < canvasRatio) {
                height = window.innerHeight;
                width = height / canvasRatio;
            } else {
                width = window.innerWidth;
                height = width * canvasRatio;
            }

            canvas.width = width;
            canvas.height = height;
            reziseElements();

        };


    reziseElements = function()
            {
                var canvrat = canvas.width / 900;

                 //Simplified
                stage.scaleX = stage.scaleY = canvrat;

                //Old Version
                /*for (i=0; i<stage.numChildren ;i++)
                {
                    currentChild = stage.getChildAt(i);

                    if (typeof currentChild.oscaleX == 'undefined')
                    {
                        currentChild.oscaleX = currentChild.scaleX;
                        currentChild.ox = currentChild.x;
                        currentChild.oy = currentChild.y;
                    }
                }   


                for (i=0; i<stage.numChildren ;i++)
                {
                    currentChild = stage.getChildAt(i);
                    currentChild.scaleX = currentChild.scaleY = currentChild.oscaleX * canvrat      
                    currentChild.x = currentChild.ox * canvrat
                    currentChild.y = currentChild.oy * canvrat
                }   */
            }
发布评论

评论列表(0)

  1. 暂无评论