【问题标题】:If I resize my canvas, my createJS text becames blurry如果我调整画布大小,我的 createJS 文本会变得模糊
【发布时间】:2015-12-25 14:14:19
【问题描述】:

我正在使用 createJS 在画布内进行绘制。我使用 resize() 函数将画布设置为占据浏览器窗口并保持纵横比。

这是代码:

    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';    
    }()

当画布调整大小时,文本会变得模糊(质量下降)。

http://i.imgur.com/RQOSajs.png 对比 http://i.imgur.com/Xwhf5c5.png

我该如何解决这个问题?

【问题讨论】:

  • 您能否存储原始画布widthheight 的大小,然后根据调整大小计算新比例,然后按新的宽度和高度正确重绘所有元素?例如。原始宽度 = 400 原始高度 = 400,调整大小后宽度现在是 800,高度现在是 600。像这样运行绘图函数。 `mytext.x = 400 * (canvas.width / originalWidth);然后对高度和字体大小做同样的事情
  • 我试图避免这种解决方案,因为我已经构建了许多包含大量文本和图像的游戏,我需要为每个游戏构建一个调整大小的函数,并弥补坐标的变化。但如果这是唯一的解决方案,我将不得不应用它。

标签: javascript html canvas easeljs createjs


【解决方案1】:

就缩放画布而言,@Adam 的回答是正确的。您确实想要使用 CSS 进行缩放,因为它会拉伸您的画布而不是更改其像素尺寸。改为使用 JavaScript 设置画布的宽度和高度。

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

正如您在评论中所说,这只会更改画布大小,不会重新定位或缩放您的内容。您必须手动执行此操作。这相当简单。通常,我建议将“调整大小”侦听器放在 HTML 文件中的 JavaScript 中,而不是放在框架脚本中。


首先,根据窗口大小和内容大小确定比例。您可以使用exportRoot.nominalBounds.widthexportRoot.nominalBounds.height,这是第一帧的边界。如果您想扩展其他内容,请改用其nominalBounds

请注意,nominalBounds 会附加到从 Flash/Animate 导出的所有 MovieClips。如果你启用了多帧边界,并且想要使用它们,你将不得不修改你的方法。

主要思想是使用原始的、未缩放的内容大小。

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;

然后,您可以根据需要将其居中。

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

以下是使用简单形状作为缩放内容的响应式画布的快速示例: http://jsfiddle.net/lannymcnie/4yy08pax/

使用 Flash/Animate CC 导出执行此操作已经出现了几次,因此它在我的未来 EaselJS 演示列表中,包括 createjs.comEaselJS GitHub

我希望这会有所帮助。

【讨论】:

  • 我使用了您的 exportRoot 方法,但它仅缩放 Flash CC 中放置在屏幕上的对象,我使用 stage.addChild() 添加的所有对象都无法缩放。跨度>
  • 是的,您必须缩放和定位您想要受影响的任何对象。如果您只针对 exportRoot,它只会缩放 exportRoot。我的建议是将所有孩子放在舞台上的容器中,并对其进行缩放/定位。
  • 现在我有一个新问题。使用活动补间调整大小会搞砸。
【解决方案2】:

由于您使用的是 CreateJS,您可以简单地调整画布的大小,并缩放整个舞台,以新的大小重绘所有内容:

// 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.

【讨论】:

    【解决方案3】:

    看看我的 jsfiddle:https://jsfiddle.net/CanvasCode/ecr7o551/1/

    基本上,您只需存储原始画布大小,然后使用它来计算新的位置和大小

    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();
    

    【讨论】:

    • 我将使用您的答案作为解决方案。在我的情况下实施起来会非常复杂,但我认为这是我唯一的选择。
    • 是的,如果你必须在构建过程中或最后实现它,它可能会导致一些问题,但是现在你知道并且知道是成功的一半:)
    【解决方案4】:

    HTML5 画布元素适用于两种不同的尺寸

    • 屏幕上的视觉大小,通过 CSS 控制,就像您使用 canvas.style.width/height 设置一样
    • 绘图的像素缓冲区大小,通过画布元素上的数字宽度和高度像素属性进行控制。

    浏览器会拉伸缓冲区以适应屏幕大小,因此如果这两个值不是 1:1 的比例,文本会显得模糊。

    尝试将以下几行添加到您的代码中

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

    【讨论】:

    • 但文本不会随画布缩放。
    • 你能发布自包含的例子,jsfiddle等,所以我可以更好地看看......
    • 它认为它在 Jsfiddle 中不起作用,因为我使用 Adob​​e Flash 构建 HTML5 文件,并且它使用 createJS 和movieclip 库。但整个代码在这里:pastebin.com/xbYUi3ew
    【解决方案5】:

    我创建了一个函数来在调整画布大小后调整屏幕上所有元素的大小。它保存原始宽度为 900 px 的元素的初始坐标和比例,然后根据相对于原始宽度比的当前宽度比更改它们。文字不再模糊/质量差。

        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
                    }   */
                }
    

    【讨论】:

    • 与其缩放所有元素,不如将它们放入容器中并对其进行缩放。如果您使用的是 Flash CC 导出,您应该能够只定位它创建的 exportRoot
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-03
    • 1970-01-01
    • 2012-08-02
    • 2018-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多