【问题标题】:Can't draw on a HTML5 Canvas using Phonegap 2.7无法使用 Phonegap 2.7 在 HTML5 Canvas 上绘图
【发布时间】:2013-05-21 12:18:24
【问题描述】:

我在网上找到了一个简单的抽屉示例。它在 PC 上运行良好。

当我在 Galaxy S4 (4.2.2) 和 Android 2.2 或 4.2.2 上使用 Phonegap 2.7 运行该项目时,它根本没有绘制任何东西。

我做错了什么?

<html lang="en">
<head>
<meta charset="utf-8" />
<title>Desktops and Tablets</title>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" charset="utf-8" src="cordova-2.7.0.js"></script>
<script type="text/javascript">
  $(document).ready(function () {
     initialize();
  });

  // works out the X, Y position of the click inside the canvas from the X, Y position on the page
  function getPosition(mouseEvent, sigCanvas) {
     var x, y;
     if (mouseEvent.pageX != undefined && mouseEvent.pageY != undefined) {
        x = mouseEvent.pageX;
        y = mouseEvent.pageY;
     } else {
        x = mouseEvent.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
        y = mouseEvent.clientY + document.body.scrollTop + document.documentElement.scrollTop;
     }

     return { X: x - sigCanvas.offsetLeft, Y: y - sigCanvas.offsetTop };
  }

  var sigCanvas;
  var context;
  function initialize() {
    sigCanvas = document.getElementById("canvasSignature");
    context = sigCanvas.getContext("2d");
    context.strokeStyle = 'Black';
    context.lineWidth = 1;
    if ('ontouchstart' in document.documentElement) {
        var drawer = {
        isDrawing: false,
        touchstart: function (coors) {
              context.beginPath();
              context.moveTo(coors.x, coors.y);
              this.isDrawing = true;
           },
           touchmove: function (coors) {
              if (this.isDrawing) {
                 context.lineTo(coors.x, coors.y);
                 context.stroke();
              }
           },
           touchend: function (coors) {
              if (this.isDrawing) {
                 this.touchmove(coors);
                 this.isDrawing = false;
              }
           }
        };

        // create a function to pass touch events and coordinates to drawer
        function draw(event) {
            if (event.targetTouches[0] === undefined) {
                context.closePath();
                this.isDrawing = false;
                return;
            }
           // get the touch coordinates.  Using the first touch in case of multi-touch
           var coors = {
              x: event.targetTouches[0].pageX,
              y: event.targetTouches[0].pageY
           };
           // Now we need to get the offset of the canvas location
           var obj = sigCanvas;
           if (obj.offsetParent) {
              // Every time we find a new object, we add its offsetLeft and offsetTop to curleft and curtop.
              do {
                 coors.x -= obj.offsetLeft;
                 coors.y -= obj.offsetTop;
              }
              // The while loop can be "while (obj = obj.offsetParent)" only, which does return null
              // when null is passed back, but that creates a warning in some editors (i.e. VS2010).
              while ((obj = obj.offsetParent) != null);
           }

           // pass the coordinates to the appropriate handler
           drawer[event.type](coors);
        }
        // attach the touchstart, touchmove, touchend event listeners.
        sigCanvas.addEventListener('touchstart', draw, false);
        sigCanvas.addEventListener('touchmove', draw, false);
        sigCanvas.addEventListener('touchend', draw, false);
        // prevent elastic scrolling
        sigCanvas.addEventListener('touchmove', function (event) {
           event.preventDefault();
        }, false); 
     }
     else {
         // start drawing when the mousedown event fires, and attach handlers to
        // draw a line to wherever the mouse moves to
        $("#canvasSignature").mousedown(function (mouseEvent) {
           var position = getPosition(mouseEvent, sigCanvas);

           context.moveTo(position.X, position.Y);
           context.beginPath();
           $(this).mousemove(function (mouseEvent) {
              drawLine(mouseEvent, sigCanvas, context);
           }).mouseup(function (mouseEvent) {
              finishDrawing(mouseEvent, sigCanvas, context);
           }).mouseout(function (mouseEvent) {
              finishDrawing(mouseEvent, sigCanvas, context);
           });
        });

     }
  }

   // draws a line to the x and y coordinates of the mouse event inside
  // the specified element using the specified context
  function drawLine(mouseEvent, sigCanvas, context) {
      var position = getPosition(mouseEvent, sigCanvas);

     context.lineTo(position.X, position.Y);
     context.stroke();
  }

   // draws a line from the last coordiantes in the path to the finishing
  // coordinates and unbind any event handlers which need to be preceded
  // by the mouse down event
  function finishDrawing(mouseEvent, sigCanvas, context) {
     // draw the line to the finishing coordinates
     drawLine(mouseEvent, sigCanvas, context);
      context.closePath();
      // unbind any events which could draw
     $(sigCanvas).unbind("mousemove")
                 .unbind("mouseup")
                 .unbind("mouseout");
  }
</script>
</head>
<body>
<h1>Canvas test</h1>
<div id="canvasDiv">
   <canvas id="canvasSignature" width="500px" height="500px" style="border:2px solid #000000;"></canvas>
</div>
</body>
</html> 

【问题讨论】:

    标签: android html cordova html5-canvas drawing


    【解决方案1】:

    我在 Galaxy S4 上遇到了同样的问题。 HTML Canvas 绘图未显示在 webview 中,但它在 Safari 浏览器中工作。 Galaxy S2、S3 没有同样的问题。

    就我而言, 当我禁用硬件加速时,画布可以工作。

    appView.setLayerType(WebView.LAYER_TYPE_SOFTWARE, null);
    

    但是速度很慢。 它与PhoneGap 无关。 三星可能在他们的实现上又犯了一个错误。

    【讨论】:

    • 禁用硬件加速会使事情“工作”,但它不是一个很好的画布生产解决方案。遗憾的是,我没有更好的建议。
    【解决方案2】:

    当我尝试将任何图像绘制到坐标 0,0 时,我的 Galaxy S4“出错”。

    我之所以意识到这一点,是因为我在画布内拖动元素,并且绘制到这些坐标的任何颜色都会覆盖整个屏幕。

    当我拖动到画布中没有图像覆盖 0,0 坐标的点时,我的应用程序运行正常。在桌面浏览器中也从未发生过。很奇怪。

    我只是跑:

    context.clearRect(0,0,1,1);
    

    在我的绘图功能结束时,它为我解决了这个问题。至少值得一试。

    但是,我朋友的 Galaxy S3 并没有这样做。

    【讨论】:

      【解决方案3】:

      您是使用 Phonegap Build 还是 Eclipse 进行构建?如果是 Eclipse,您的项目设置是否正确?

      $(document).ready(function () { 替换为$(document).on("deviceready",function () { 因为 phonegap 在初始化时使用 deviceready 事件发出信号。

      还将 jQuery JS 文件保存在您的项目中;如果 HTTP 请求失败或您的 Android 设备没有连接,应用程序将无法加载,因为它无法加载 jQuery。

      因此替换&lt;script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"&gt;&lt;/script&gt;

      &lt;script type="text/javascript" src="jquery.min.js"&gt;&lt;/script&gt;

      我用这些修改尝试了上面的代码(加上我添加了一些调试),它在运行 Android 2.2.3 的 HTC HD2 和运行 Android 4.2.2 的 Nexus 7 上运行良好

      Here's a zip file 包含我为测试它而创建的 Eclipse 项目和生成的 Android APK。在您的设备上试一试,看看它是否有效。

      【讨论】:

      • 感谢您的评论,..(您发布的链接现在已损坏)我做了您写的所有内容,但它不能解决问题,画布会打开,但是当我触摸它时(使用我的 Galaxy S4 4.2.2)- 没有任何反应..
      • 链接仍然为我工作,再试一次:http://ge.tt/9kqdrmi/v/0
      • 是的,现在它可以工作了,但是,你的项目“原样”也不起作用。我猜这是 Galaxy S4 的问题?
      • 也许只是 S4,但同样的操作系统在如此高的级别上表现如此不同,这似乎很奇怪。对我来说,它适用于运行 4.2.2 和 Android 4.2.2 模拟器的 Nexus 7。也许在 4.2.2 模拟器和另一台物理 Android 设备(如果你有的话)中尝试一下,以确认问题出在 S4 上,而不是你的 Eclipse 安装或其他...
      • Phonegap 2.8.1 没有修复。非常感谢您尝试提供帮助。我希望有人有一个解决方案,他可以在这里发布。如果我找到了修复,我会在这里发布。
      【解决方案4】:

      您应该考虑使用人行横道。它取代了默认的 android webview,后者非常不一致(每个供应商通常会实施自己的),并且很难让您的应用程序在所有 android 版本和供应商之间保持一致。

      Crosswalk 有一个 Cordova 兼容版本,在我的所有测试中,性能提升都很明显。

      https://crosswalk-project.org/

      【讨论】:

        猜你喜欢
        • 2011-01-23
        • 1970-01-01
        • 2021-11-15
        • 2014-05-17
        • 1970-01-01
        • 2014-11-07
        • 2011-08-28
        • 2015-11-10
        • 1970-01-01
        相关资源
        最近更新 更多