HTML5 Canvas:使用/缓存drawImage绘制的元素在缩放和/或移动时被平滑
HTML5 Canvas: Elements drawn with/cached for drawImage are smoothed when scaled and/or moved
我确实知道drawImage
的x
和y
的浮点/整数值的情况。但我需要的是一个平滑的动画,能够缓存我的形状。
- 关于使用备份画布缓存复杂路径的文章
-
drawImage
浮动参数的文章
例如,我想绘制一些复杂的形状(即SVG-tiger,转换为canvas-commands)到画布上,然后用ctx.translate
和ctx.drawImage
平滑地移动 。然后我需要浮点值,因为我得到的是一步一步的移动:
下面是JSFiddle的示例:
- 1:速度快,将
Math.floor
应用于translate
参数(x
和y
等于以秒为单位乘以10
):动画很奇怪(顺序,不流畅)。 - 二:速度慢,
Math.floor
应用于translate
参数(x
和y
等于时间,以秒为单位):动画很奇怪(顺序,不流畅)。 - 三:速度快,不舍入,浮点值(
x
和y
等于以秒为单位的时间乘以10
)。速度很快,所以动画看起来很好。 - 四:慢速,不舍入,浮点值(
x
和y
等于以秒为单位的时间)。速度慢,所以动画看起来脉动。为什么?
最后一个案例让我感到困惑。我错了在我的尝试,有可能使这个缓存技巧工作好吗?
在Firefox中,有一个名为mozImageSmoothingEnabled
的画布属性(见),但在其他浏览器中没有这个帮助。并且它还消除了路径平滑。
代码提取:
var shapeCanvas = null;
var w = 320, h = 240;
var startTime = 0;
function start() {
startTime = Date.now();
var docCanvas = document.getElementById('canvas');
. . .
shapeCanvas = document.createElement('canvas');
. . .
drawShape(shapeCanvas.getContext('2d'));
drawNext(docCanvas.getContext('2d'));
}
function drawNext(ctx) {
var msec = (Date.now() - startTime);
var time = msec / 1000; // seconds passed from start
ctx.clearRect(0, 0, w, h);
ctx.save();
// the lines to change: time | (time * 10) | Math.floor(time * 10)
ctx.translate((time < 500) ? Math.floor(time * 10) : 500,
(time < 500) ? Math.floor(time * 10) : 500);
ctx.drawImage(shapeCanvas, 0, 0);
ctx.restore();
__nextFrame(function() {
drawNext(ctx);
});
}
function drawShape(ctx) {
. . .
}
我在你的第一个链接中写了教程。
Just to clear the air:
shapeCanvas.style.width = w + 'px';
shapeCanvas.style.height = h + 'px';
不值得做。如果它只是一个内存中的画布,那么设置样式就没有意义了,而且你不应该真的想要设置画布的宽度和高度style,它只会混淆事情。
ellisbben在评论中所说的几乎就是正在发生的事情。
我敢打赌,有一些粗俗的方法可以绕过它。一种方法可能是确保它永远不会绘制在整数像素上。另一种可能是在绘制任何东西之前使用ctx.scale(.99,.99)
,这样它总是反锯齿的。这里很难得到一致的解决方案,因为不同浏览器的抗锯齿实现是不同的。
以下是我自己的一些实验:
http://jsfiddle.net/KYZYT/29/
前两个是从画布和PNG中绘制的形状
后两个是同一对,但被.99,.99
缩放
最后一个是真的。它仍然有点模糊,但看起来比使用图像清晰得多。
我的实验没有一个能终止你的脉动,至少在微观层面上没有。我认为,如果你想在半像素空间中动画化像素完美的图像,这就是你必须忍受的东西。
如果你真的觉得你不能只画完美的像素,那么你的(第二)最好的选择可能是找到一种方法,在任何时候都强制抗锯齿。确保您始终转换为非整数或稍微缩放它是不错的选择,但可能还有其他选择。
老实说,你最好不要缓存这些动画路径,直到你绝对需要它们的性能。缓存样式化的按钮和其他静态的东西,但如果你有动画路径,需要缓慢而精确地移动,看起来很好,你最好坚持真正的东西在我的缓存优化,除非你真的 需要它。
有点无耻的插头,但是:我已经在HTML5老虎机游戏中实现了流畅的动画。生成的缓存图像在小画布上绘制一次,然后我使用translate3d()与-moz-transform/-webkit-transform样式的画布移动,镜像和缩放图像。
Pregeneration
- <
- 创建图像/gh>
- 绘制图像内容
- 在DOM中创建画布对象
动画阶段
- 明确帆布
- 将缓存的图像绘制到画布 使用CSS3变换(scale3d和translate3d)来移动画布。
- 在不移动内部文本的情况下缩放元素的效果
- 使用KineticJS变换(移动/缩放/旋转)形状
- 如何在缩放时获取移动浏览器窗口的宽度
- D3.js:缩放时,在2D图形中沿着直线移动圆
- 在Trigger.io移动应用程序中启用缩放
- 缩放移动设备上的图像
- Canvas(fabricjs)阻止网络浏览器在手机上缩放和移动
- jqPlot图形在缩放后向右移动
- 实现水平移动和缩放UI效果-可能的jQuery插件(?)
- 在 jquery 移动版上启用缩放效果
- 移动设备中的 BX滑块缩放
- 标记与标签缩放时移动
- 移动节点时如何停止平移?也限制缩放?D3.
- 移动版Magento中的缩放功能问题
- 在提升缩放中禁用移动设备悬停上的缩放效果
- 如何允许平板电脑缩放,但不允许缩放移动设备
- 三个 JS - 如何缩放移动对象
- 当适合设备的绝对视图在移动设备中向右移动几个像素时,我如何防止双击缩放
- 如何使 window.innerHeight 在缩放时在移动设备上工作
- openlayer3捕获移动结束/缩放结束事件