0

对不起我的英语,我来自阿根廷。我正在用 Eclipse 开发一个 HTML5 应用程序。当程序在 IMG 元素上加载图像时,会正确检测到事件touchstarttouchmovetouchend 。但是当我需要旋转图像时,我使用了 CANVAS 和toDataUrl()方法,然后似乎没有检测到触摸事件。我使用的源代码是这样的(考虑所有对象、变量和函数声明良好):

var context = canvas.getContext("2d");

function loadImage(strFile, intDeg) {
  if (intDeg == 90) image.onload = function() { rotateImage(); };
  imagePhoto.src = strFile;
}

function rotateImage() {
  image.onload = function() { moveImage(); };
  canvas.width = image.height;
  canvas.height = image.width;
  context.translate(canvas.width, 0);
  context.rotate(90 * Math.PI / 180);
  context.drawImage(image, 0, 0, canvas.width, canvas.height);
  context.restore();
  image.src = canvas.toDataURL("image/png");
}

image.addEventListener("touchstart", downEvent, true, true);
image.addEventListener("touchmove", moveEvent, true, true);
image.addEventListener("touchend", upEvent, true, true);

谢谢!

4

2 回答 2

0

看起来这是 4.1 之前的 android 中的一个错误:http: //developersday.wordpress.com/2012/08/17/missing-events-touchstartmoveend-and-scroll-on-android-4-0-x-and-较早/

超短版本是触摸事件不能很好地配合滚动。http://code.google.com/p/android/issues/detail?id=19827建议在您的触摸事件处理程序中调用 e.preventDefault() 。

于 2013-11-12T02:00:18.433 回答
0

(我现在认为这个答案完全是错误的。对不起!)

问题是,toDataURL是一个同步的、阻塞的 API 调用。这意味着当它运行时,浏览器不会监听其他任何东西。这是我对正在发生的事情的猜测:

  1. 你打电话loadImage。这将设置onload()处理程序并分配strFile.src
  2. onload火灾和呼叫rotateImage。我们将图像绘制到画布中,然后在toDataURL.
  3. 我们将结果分配toDataURL.src
  4. 我们回到第 2 步。

我们忙于旋转和转换为 base64 和加载,以至于我们从来没有机会处理事件。

三种可能的修复方法,按优先顺序排列:

  1. 将图像旋转到屏幕上可见的画布中。这样你根本不需要image.srcandtoDataURL位。(或者,使用 csstransform: rotate(90deg);并且根本不在 javascript 中进行旋转。这可能是跨浏览器更棘手)
  2. 删除onload末尾的事件处理程序rotateImage,这样您就不会陷入循环。
  3. 使用canvas.toBlobandFileReader.readAsDataURL而不是Canvas.toDataURL,所以一切都很好并且是异步的。请注意,chrome 还没有实现toBlob,所以这可能不是那么有用。
于 2013-10-30T02:39:54.790 回答