7

I've found a simple drawer example online. It works fine on the PC.

When I run it, using Phonegap 2.7, on my Galaxy S4 (4.2.2), with Android 2.2 or 4.2.2, for the project, it just doesn't draw anything at all.

What am I doing wrong ?

<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> 
4

4 回答 4

5

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

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

appView.setLayerType(WebView.LAYER_TYPE_SOFTWARE, null);

但它很慢。它与PhoneGap 无关。三星可能在他们的实施中犯了另一个错误。

于 2013-07-16T06:56:33.143 回答
1

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

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

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

我只是运行:

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

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

然而,我朋友的 Galaxy S3 并没有这样做。

于 2013-08-13T22:48:52.903 回答
0

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

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

https://crosswalk-project.org/

于 2014-11-25T13:59:42.950 回答
0

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

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

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

因此更换<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>

<script type="text/javascript" src="jquery.min.js"></script>

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

这是一个 zip 文件,其中包含我为测试它而创建的 Eclipse 项目和生成的 Android APK。在您的设备上试一试,看看它是否有效。

于 2013-06-08T09:08:09.827 回答