10

我正在旋转 2d 画布,它在桌面上运行良好,但在移动空间中存在一个小问题。这是放大的屏幕截图:

在此处输入图像描述

拇指图像在 500 毫秒的过程中旋转了大约 0.2rad。我认为所有相关代码都在下面内联。如您所见,图像的每个顶角都留下了某种“轨迹”。

var duration = 500;
var start = 0;
var stop = 0.287554326;
var step = (stop - start) / 10;
var steps = (stop - start) / step;
var current = 0;
var delay = duration / steps;
var first = true;
if (navigator.userAgent.match(/iP(hone|[ao]d)|android/i)) step *= 1.5;
var rotate_int = setInterval(function() {
  if (current >= stop) {
    clearInterval(rotate_int);
    callback && callback();
    return;
  }
  ctx.clearRect(0, 0, cvs.width, cvs.height);
  ctx.translate(cvs.width / 2, cvs.height / 2);
  ctx.rotate(step);
  current += step;
  ctx.translate(cvs.width / -2, cvs.height / -2);
  ctx.drawImage(i, 0, 0);
  if (first) {
    first = false;
    thumb.hide();
  }
}, delay);

笔记:

  1. 该代码在桌面上运行良好(Firefox、Chrome、Safari、Opera 甚至 IE 的最新版本)
  2. 我测试了以下设备和浏览器:
    1. iPhone 3GS:Safari、Opera Mini
    2. iPhone 4S:Safari
    3. iPad(第一代):Safari
    4. Android Galaxy S(带姜饼):默认浏览器,Firefox 手机
    5. 摩托罗拉 Droid X(带姜饼):默认浏览器,Firefox 手机
  3. 我还没有找到<canvas>表现出这种行为的桌面浏览器(支持)
  4. 我还没有找到没有表现出这种行为的移动设备
  5. 发布的图像是来自 iPad 的放大屏幕截图
  6. 如果重要的话,<canvas>(旋转时)正在被动画(通过 jQuery)穿过它后面的图像并停止,这在屏幕截图中可见。
  7. 页面上还有第二个<canvas>。它使用相同的竖起大拇指 .png,并使用上面发布的相同代码进行旋转,并且还具有动画以穿过不同的背景图像(但方向相反,即一个“竖起大拇指”向西北移动,一个向东南移动),并且轨迹也出现在相对于画布上下文的相同位置。

我已经把我能想到的所有泥巴都扔到了墙上,希望有什么能导致诊断。有没有其他人见过这样的事情?我可以尝试什么不同的方法?我是否错过了 HTML5 教程网站上某个警告此类行为的大红色警告标签?

==编辑 1==

根据@GGG 的评论,我删除了 UA 嗅探(旨在减少画布重绘的数量和频率,因为如果我使用与桌面相同的设置,移动浏览器都会突突突突)但这只会导致轨迹变得更加明显(例如更厚)。然后,我通过重新放入 UA 嗅探器进行实验,但我并没有将循环减少 50%,而是实际上将它们增加了 500%。同样,这导致痕迹变得更加明显。然而,这种加厚似乎是渐近的——换句话说,通过调整动画速度的参数,我可以使轨迹变粗是有限度的。

==编辑 2==

根据@GGG 的其他评论,我去编辑图像以添加一些透明数据,以尝试找到合适的解决方法。我看到的是图像突出在画布的顶部和左侧边缘(这是“ Photoshop画布的”,而不是“HTML5 的<canvas>”)。当我在顶部和左侧添加相等的透明数据填充时,条纹问题消失了。这是原始 PSD(预先添加额外间距):

在此处输入图像描述

所以我的问题就变成了:即使图像(用不透明的像素)填充了它的整个 [Photoshop] 画布,为什么我的画布上下文不clearRect()表现自己?这不应该抹去画布范围内的任何东西吗?如果是这样,为什么会留下这几个像素?

==编辑 3==

经过一番研究,事实证明Cairo被几个主要的渲染引擎(至少 WebKit 和 Gecko)相当普遍地使用。正如@JonasWielicki 首次建议的那样,Cairo 库——当针对移动执行进行优化时——可能是不是有点过分热心?

4

1 回答 1

3

根据评论,尝试在图像边缘周围添加一些透明像素作为解决方法。

我真的不知道为什么会这样。我认为这与移动设备上对 alpha 通道的奇怪处理有关,但这只是猜测。

我注意到移动浏览器在滚动时似乎放弃或“估计”了 alpha 通道(慢慢地上下滚动,甚至字体看起来更“脆”)。我想知道他们是否分两个阶段渲染事物,将 alpha 通道留给第二阶段,如果有另一个“帧”要在当前“帧”之后立即渲染,则跳过第二阶段,如果这有意义的话。也许这会以某种方式混淆渲染器,使其认为它没有在它拥有的地方绘制东西。

无论如何,这可能确实需要一个错误报告。如果不出意外,我很想听到关于发生了什么的真正解释。

于 2012-05-08T21:00:42.187 回答