如果我调整画布大小,我的 createJS 文本会变得模糊
Posted
技术标签:
【中文标题】如果我调整画布大小,我的 createJS 文本会变得模糊【英文标题】:If I resize my canvas, my createJS text becames blurry 【发布时间】: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
我该如何解决这个问题?
【问题讨论】:
您能否存储原始画布width
和height
的大小,然后根据调整大小计算新比例,然后按新的宽度和高度正确重绘所有元素?例如。原始宽度 = 400 原始高度 = 400,调整大小后宽度现在是 800,高度现在是 600。像这样运行绘图函数。 `mytext.x = 400 * (canvas.width / originalWidth);然后对高度和字体大小做同样的事情
我试图避免这种解决方案,因为我已经构建了许多包含大量文本和图像的游戏,我需要为每个游戏构建一个调整大小的函数,并弥补坐标的变化。但如果这是唯一的解决方案,我将不得不应用它。
【参考方案1】:
就缩放画布而言,@Adam 的回答是正确的。您确实不想要使用 CSS 进行缩放,因为它会拉伸您的画布而不是更改其像素尺寸。改为使用 javascript 设置画布的宽度和高度。
stage.canvas.width = window.innerWidth;
stage.canvas.height = window.innerHeight;
正如您在评论中所说,这只会更改画布大小,不会重新定位或缩放您的内容。您必须手动执行此操作。这相当简单。通常,我建议将“调整大小”侦听器放在 html 文件中的 JavaScript 中,而不是放在框架脚本中。
首先,根据窗口大小和内容大小确定比例。您可以使用exportRoot.nominalBounds.width
和exportRoot.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.com 和 EaselJS 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" >
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 中不起作用,因为我使用 Adobe 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
。以上是关于如果我调整画布大小,我的 createJS 文本会变得模糊的主要内容,如果未能解决你的问题,请参考以下文章
在 UITableview 内的自动调整大小的标签上设置非常长的文本会破坏 NSLayoutConstraint