无法使用Phonegap 2.7在HTML5 Canvas上绘图

时间:2013-05-26 13:24:20

标签: android html5 cordova html5-canvas drawing

我在网上找到了一个简单的抽屉示例。它在PC上工作正常。

当我使用Phonegap 2.7,在我的Galaxy S4(4.2.2)上,使用Android 2.2或4.2.2,对于项目来说,它根本不会绘制任何东西。

我做错了什么?

<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 个答案:

答案 0 :(得分:5)

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

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

appView.setLayerType(WebView.LAYER_TYPE_SOFTWARE, null);

但速度很慢。 它与PhoneGap无关。 也许三星在实施方面又犯了一个错误。

答案 1 :(得分:1)

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

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

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

我跑了:

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

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

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

答案 2 :(得分: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上运行良好

Here's a zip file包含我创建的Eclipse项目,用于测试它并生成Android APK。试一试您的设备并查看它是否有效。

答案 3 :(得分:0)

你应该考虑使用Crosswalk。它取代了默认的android webview,它非常不存在(每个供应商通常都会自行添加),并且很难让你的应用程序在所有Android版本和供应商中保持一致。

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

https://crosswalk-project.org/