Kruga
Kruga

Reputation: 791

Canvas not clearing at original position in Android

I'm working with phonegap and trying to make simple app for Android, where a ball rolls around based on the accelerometer. I'm using a canvas that takes up the whole screen and drawing a circle for the ball.

Everything works fine, except that the canvas is not getting cleared properly between each frame. It clears everything except the ball at the original position. So there are always 2 balls, one moving around, and one stationary in the middle.

Here is my render function

function render(){
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.beginPath();
    ctx.arc(posX, posY, size, 0, 2*Math.PI, false);
    ctx.fillStyle = 'red';
    ctx.fill();
    ctx.lineWidth = 2;
    ctx.strokeStyle = 'black';
    ctx.stroke();
}

I've tried using canvas.width = canvas.width, but this simply moves the fake ball to the real balls current position. It also gives really poor performance if I do this every frame.

This problem doesn't happen when I use a browser (Chrome) and move the ball with the console.

The really weird thing is that it doesn't always happen. Sometimes in rare cases, when i start the app or use canvas.width, the fake ball disappears.

Edit: Tested with different devices, and the problem is only on my Samsung Galaxy Note (Android 4.1.2), while it works fine on my HTC Desire HD (Android 2.3.5) and iPhone 5 (iOS 7.1)

Full code

document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady(){
    navigator.accelerometer.watchAcceleration(onSuccess, onError, { frequency: 100 });
}
function onSuccess(acc){
    accX = -acc.x;
    accY = acc.y;
}
function onError(message){
    alert('Failed because: ' + message);
}

var size = 40;
var speed = 80;
var posX;
var posY;
var speedX;
var speedY;
var accX;
var accY;

var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = screen.width / window.devicePixelRatio;
canvas.height = screen.height / window.devicePixelRatio;
document.body.appendChild(canvas);

reset();
var then = Date.now();
setInterval(main, 1);

function reset(){
    posX = canvas.width/2;
    posY = canvas.height/2;
    speedX = 0;
    speedY = 0;
    accX = 0;
    accY = 0;
}

function update(mod){
    speedX += accX*mod;
    speedY += accY*mod;

    posX += speedX*mod*speed;
    posY += speedY*mod*speed;

    if((posX < 0-size) || (posX > canvas.width+size) || (posY < 0-size) || (posY > canvas.height+size))
        reset();
}

function render(){
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.beginPath();
    ctx.arc(posX, posY, size, 0, 2*Math.PI, false);
    ctx.fillStyle = 'red';
    ctx.fill();
    ctx.lineWidth = 2;
    ctx.strokeStyle = 'black';
    ctx.stroke();
}

function main(){
    var now = Date.now();
    var delta = now - then;
    update(delta/1000);
    render();
    then = now;
}

Upvotes: 0

Views: 222

Answers (1)

Yiyuan Lee
Yiyuan Lee

Reputation: 679

Instead of clearing the canvas, I tried filling it with white.

context.fillStyle = "#FFFFFF";
context.fillRect(0, 0, canvas.width, canvas.height);

I tested it on a LG P880, CyanogenMod 10.1, with its stock Android browser, and the original canvas disappeared afterwards.

Upvotes: 1

Related Questions