Reputation: 954
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>
Upvotes: 7
Views: 6772
Reputation: 347
You should consider using Crosswalk. It replaces the default android webview, which is very incosistent (each vendor usually imlements its own) and it's hard to keep your application consistent among all android versions and vendors.
Crosswalk has a Cordova compatible version and in all of my tests the performance increase is noticeable.
https://crosswalk-project.org/
Upvotes: 0
Reputation: 34
My Galaxy S4 "bugs out" when I try to draw any image to the coordinates 0,0.
I only realized this because I drag elements around inside the canvas and whatever color is being drawn to those coordinates covers the whole screen.
When I drag to a point where there is no image covering the 0,0 coordinates in the canvas, my application runs normally. Also never happened in the desktop browser. Very strange.
I just run:
context.clearRect(0,0,1,1);
at the end of my draw function, and it solved it for me. Worth a try at least.
My friend's Galaxy S3 did not do this however.
Upvotes: 1
Reputation: 111
I'm experiencing the same issue on Galaxy S4. HTML Canvas drawing is not showing in webview, but it is working in Safari browser. Galaxy S2, S3 don't have the same issue.
In my case, when I disable Hardware acceleration, canvas works.
appView.setLayerType(WebView.LAYER_TYPE_SOFTWARE, null);
but it is very slow. It has nothing to do with PhoneGap. Probably Samsung made another bug on their implementation.
Upvotes: 5
Reputation: 30366
Are you building with Phonegap Build or Eclipse? If Eclipse, do you have your project set up correctly?
Replace $(document).ready(function () {
with $(document).on("deviceready",function () {
because phonegap uses the deviceready event to signal when it has initialised.
Also save the jQuery JS file inside your project; if the HTTP request fails or your Android device doesn't have a connection, the app will fail to load because it can't load jQuery.
Therefore replace <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
with <script type="text/javascript" src="jquery.min.js"></script>
I tried the code above with these modifications (plus I added some debug) and it works fine on my HTC HD2 running Android 2.2.3 and my Nexus 7 running Android 4.2.2
Here's a zip file containing the Eclipse project I created to test it and resulting Android APK. Give it a try on your devices and see if it works.
Upvotes: 0