How can I load an image onto the HTML5 Canvas using Phonegap - android

Trying to load an image into onto an html5 canvas and then running the html5 on Android using Phonegap. Here is my HTML.
<!DOCTYPE HTML>
<html>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<script type="text/javascript">
var c=document.getElementById("myCanvas");
var cxt=c.getContext("2d");
var img=new Image()
img.src="img_flwr.png"
cxt.drawImage(img,0,0);
</script>
<img src="img_flwr.png"/>
</body>
</html>
I have included the standard img tag to demonstrate the problem.
Under Firefox, this page correctly shows the image rendered on the canvas and in the standard img tag.
When I deploy to Android emulator using Phonegap, only the standard img displays the picture.
Both the html and the .png file are in the assets/www folder of my phonegap project.
How can I get the image to render correctly on the canvas?
EDIT.. Fixed (thanks Avinash).. its all about timing.. you need to wait until the img is loaded before drawing onto the canvas ..vis
var c=document.getElementById("myCanvas");
var cxt=c.getContext("2d");
var img=new Image()
img.src="img_flwr.png";
img.onload = function() {
cxt.drawImage(img,0,0);
};

It might be the delay in loading the image(it's just a Guess of mine, I'm not sure. If it helps I'll be Glad) ...
Try this code(which waits until the page is loaded completely)
<!DOCTYPE HTML>
<html>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<script type="text/javascript">
window.onload = function() {
var c=document.getElementById('myCanvas');
var cxt=c.getContext('2d');
var img=new Image();
img.src='img_flwr.png';
cxt.drawImage(img,0,0);
};
</script>
<img src="img_flwr.png"/>
</body>
</html>
Or you can do after the Image is loaded as follows
var c=document.getElementById('myCanvas');
var cxt=c.getContext('2d');
var img=new Image();
img.onload = function() {
cxt.drawImage(img,0,0);
};
img.src='img_flwr.png';
Please let me know if the problem still persists ...

I haven't had a chance to try this but try to refer to your image as:
file://android_asset/www/img_flwr.png

I tried without the img tags for PhoneGap 1.1.0 Xcode 4.2 and the Image() class onload events fire but the images report zero widths and heights. If the img html tags are added they work. So I am thinking device ready is not a place to do this or this shows an incompatibility with how a js programmer might expect the events and sequencing to work. Having the images floating around off screen open issues with multiple resolutions.
Here is the stub code.
var tileLoaded = true;
var dirtLoaded = true;
function onBodyLoad()
{
document.addEventListener("deviceready", onDeviceReady, false);
}
/* When this function is called, PhoneGap has been initialized and is ready to roll */
/* If you are supporting your own protocol, the var invokeString will contain any arguments to the app launch.
see http://iosdevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html
for more details -jm */
function onDeviceReady()
{
// do your thing!
//navigator.notification.alert("PhoneGap is working");
console.log("device on ready started");
canvas = document.getElementById('myCanvas');
c = canvas.getContext('2d');
canvas.addEventListener('mousedown', handleMouseDown, false);
window.addEventListener('keydown', handleKeyDown, false);
tileMap = [];
tile.src = "img/tile.png";
//tile.onLoad = tileImageLoaded();
dirt.src = "img/dirt.png";
//dirt.onLoad = dirtImageLoaded();
console.log("device on ready ended");
draw();
}
function tileImageLoaded()
{
console.log("tile loaded");
console.log("draw - tile.width:" + tile.width);
console.log("draw - tile.height:" + tile.height);
tileLoaded = true;
draw();
}
function dirtImageLoaded()
{
console.log("dirt loaded");
console.log("draw - dirt.width:" + dirt.width);
console.log("draw - dirt.height:" + dirt.height);
dirtLoaded = true;
draw();
}

Related

HTML5 - Canvas not rendering on first load in Android WebView

I'm developing an HTML5 canvas-based game that's running in a WebView within an existing application. On first running the game, it loads successfully in the background, and all logs suggest it's ready and running. However, nothing is displayed in the WebView. If I load something else into the WebView and then return to my game, it loads successfully as before, and then renders. What could prevent a canvas from displaying on first being run, only to work on subsequent reloads?
For detail:
I get no console errors on loading the game for the first time.
The game loads successfully when running in the iOS version of the application.
The CSS applied to the canvas element doesn't render, suggesting it isn't an issue loading my assets before displaying them.
All the issues I've investigated were caused by trying to render assets before they were displayed, so subsequent reloads were fixed by these now cached images being displayed, but I can't find anything concerning the canvas failing to display at all in Android.
Here's the HTML loaded by the WebView:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
<title>Darts</title>
<meta name="description" content="Darts GamePad Game">
<script src="js/dummy-gamepad-functions.js"></script>
<script src="js/libs/polyfill.js"></script>
<script src="js/gamepad-client.js"></script>
<script src="js/darts-boot.js"></script>
<script src="js/darts-loader.js"></script>
<link rel="stylesheet" href="css/darts.css">
</head>
<body onload=bootGame()>
<div id="darts-game-container"></div>
</body>
</html>
And this is my onload script:
var bootGame = () => {
//create canvas element
let canvas = document.createElement('canvas');
canvas.id = "darts-canvas";
canvas.width = 740;
canvas.height = 400;
let gameContainer = document.getElementById("darts-game-container");
gameContainer.appendChild(canvas);
//scale canvas to view window
let gamepadViewport = document.getElementById("darts-game-container"),
gamepadCanvas = document.getElementById("darts-canvas"),
viewportWidth = window.innerWidth,
canvasWidth = gamepadCanvas.width,
viewportHeight = window.innerHeight,
canvasHeight = gamepadCanvas.height;
let scaleRatio = Math.min(viewportWidth/canvasWidth, viewportHeight/canvasHeight);
if (scaleRatio < 1) {
gamepadViewport.style.transform = `scale(${scaleRatio}, ${scaleRatio})`;
gamepadViewport.style.webkitTransform = `scale(${scaleRatio}, ${scaleRatio})`;
gamepadViewport.style.mozTransform = `scale(${scaleRatio}, ${scaleRatio})`;
gamepadViewport.style.oTransform = `scale(${scaleRatio}, ${scaleRatio})`;
}
//initialise Loader
Darts.Loader = new Loader();
//initialise GamePad API, then initialise core classes when loaded
GamePadClient = new GamePadClient();
GamePadClient.initialise()
.then(() => {
//load all scripts
return Darts.Loader.loadScripts(LIBS_TO_LOAD, COMMON_LIB_PATH, LIB_NAME_SUFFIX)
})
.then(() => {
return Darts.Loader.loadScripts(SCRIPTS_TO_LOAD, COMMON_SCRIPT_PATH, SCRIPT_NAME_SUFFIX)
})
.then(() => {
//initalise core classes
Darts.Controller = new Controller();
Darts.Logic = new Logic();
Darts.Display = new Display();
Darts.GameProps = new GameProps();
Darts.GameState = new GameState();
//loads display elements and scripts, then inits game once complete
Darts.Controller.initGame();
});
}
I've solved it after I narrowed it down to my canvas-resizing method. window.innerWidth and window.innerHeight are not set when window.onload is called, having an initial value of 0. They're only properly set after the window.onresize event is called, so listening for that and then scaling the canvas gives the proper result.

Android web view local storage does not refresh on android 4.3 or less OS

For an android webview application, a dynamic webview page (page A) loads items from local storage correctly when the page A loads for the first time. Then, on Page B another local storage item is added. Then, page A is loaded using window.location.herf= "page A". But, page A does not load the extra local storage item added on Page B. It seems like page A always loads from cache after the 1st time load. This problem happens with any android device or emulator running on any android 4.3 or less operating system.
NOTE:*************
Page A refreshes correctly on an emulator running on android 4.4 or on chrome web.
So... I want a work around for any android OS 4.3 or less.
html.js function that dynamically fills content on page A
function ShowResults(value) {
var overNight = getNetWork(value); /// it the function to get local storage based on value key
document.write('<li><a href="file:///android_asset /SettingEditProgram.html?overnightkey='+value+'">')
document.write('<div class="column">')
document.write('<div class="rectangle"><network>'+ overNight.network + '</network></br>')
document.write('<program>'+ overNight.program +'</program></br>')
document.write('<text>' + overNight.start +'-'+ overNight.end + '</text></br>')
document.write('<text>' + overNight.demo + ', ' + overNight.region + '</text>')
document.write('</div>')
document.write('</div></a></li>')
}
Page A:_________________________
<head>
<meta http-equiv='cache-control' content='no-cache'>
<meta http-equiv='expires' content='-1'>
<meta http-equiv='pragma' content='no-cache'>
<meta http-equiv="refresh" content="4">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.css" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.5.min.js"></script>
<link rel="stylesheet" href="file:///android_asset/style.css" type="text/css" />
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.js"></script>
<script src="html.js"></script>
<script>
$(document).ready(function() {
$.ajaxSetup({ cache: false});
var parameters = $(location).attr('search');
parameter = parameters.replace("?overnightkey=","");
// 'Setting' data-attributes using setAttribute
var newKey = document.getElementById("overnight");
var oldValue = newKey.getAttribute("data-overnight",newKey);
newKey.setAttribute("data-overnight",newKey);
var newKeyvalue ="oldValue="+oldValue+" newValue:"+newKey;
console.log("newKeyvalue");
});
</script>
</head>
<body>
<div data-role="page" id="album-list">
<div id="headerBar">
<img class="goback" src="file:///android_asset/img/ic_goback-web.png">
<img class="appicon" src="file:///android_asset/img/ic_launcher-web.png"><p class="apptitle">Program Setting</p>
<img class="add" src="file:///android_asset/img/ic_add-web.png">
</div>
<div data-role="content">
<ul id="overnight" data-role="listview" data-split-icon="gear" data-split-theme="d" data-overnight="0">
<script>
getIDs().forEach(ShowResults);
</script>
</ul>
</div><!-- /content -->
</div><!-- /page -->
</body>
</html>
page B that set local storage and then re-direct to page A:
$('#savebutton').click(function() {
var keyOverNight = localStorage.getItem("keyOverNightAll");
var keyOverNightArray = new Array();
if (keyOverNight) {
try {
keyOverNightArray = JSON.parse(keyOverNight); // use JSON3 to handle multiple browsers/versions
} catch (e) {
//keyOverNightArray = new Array(); // for parse failure --> return an empty Array
// do nothing
}
}
//Get a new key for setting page based on the local storage
//OvernightKeys
var newKey;
if (keyOverNightArray.length == 0)
{
newKey =1;
}
else
{
newKey= keyOverNightArray[keyOverNightArray.length-1]+1;
}
//Store the overnight key
keyOverNightArray.push(newKey);
localStorage.setItem("keyOverNightAll",JSON.stringify(keyOverNightArray));
//Now store Program values into the newKey
var overnightKey = "overNight"+ newKey.toString();
var jsonOvernight = {"network": NetworkSelected, "program": ProgramSelected, "start": STimeSelected, "end": ETimeSelected, "region": RegionSelected, "demo": DemoSelected }
localStorage.setItem(overnightKey, JSON.stringify(jsonOvernight));
//window.location = "file:///android_asset/SettingHomePage.html";
window.location.href = 'file:///android_asset/SettingHomePage.html?newKey='+newKey;
//window.location.reload(true);
});
Things I tried on Page A
Refreshed every 10 seconds.. It does not read the newest element from local storage.
Set the cache to no content
Set a new data-attribute everytime it comes to this page after adding an item on PageB
tricked page A to load a html.js script with time stamp on it.. eg. html.js?'+timeStamp+'somestring:"
reloads page A. then it runs infinitely.
If I closed the app, and re-run it, it will load the newest localstoarge items again only on the 1st load.
I've tried almost most of the stack over flow help.. Cannot find any answer yet.
check out targetSdkVersion.
I meet same problem. I set targetSdkVesrion to under 16. then sloved.

PhoneGap Conversion - HTML to .apk

I am turning a HTML app into a .apk using https://build.phonegap.com and everything works great appart from my file selector.
<input name="file" type="file" id="file">
I want to be able to select images only (it doesnt matter if it can select more - but its the images I am looking for) from both camera and file system..
In the web version http://carbonyzed.co.uk/websites/assent/1/photos.html this works great from my phone, but when converted to .apk, this functionality is lost, and I can't seem to find anything on here, or online relating to this issue.
At least for me, the input file doesn't work in Phonegap.
You need use the Phonegap API to get picture and select the source where come from, like photolibrary, camera or savedphotoalbum.
See more info about camera.getPicture: http://docs.phonegap.com/en/2.1.0/cordova_camera_camera.md.html#camera.getPicture
and about Camera.PictureSourceType parameter of cameraOptions method: http://docs.phonegap.com/en/2.1.0/cordova_camera_camera.md.html#cameraOptions
Ended up using the Child Browser system like so
In the head
<script src="childbrowser.js"></script>
in the body
<button class="button-big" onClick="window.plugins.childBrowser.showWebPage('URL_TO_GO_HERE',
{ showAddress: false });" style="width: 100%;">UPLOAD PHOTOS</button>
which has a standard fileuploader like
<input name="file" type="file" id="file">
then it let me select from root storage, works in phonegap 2.2 onwards on both iOS and Android OS
To capture an image I used this in the head
<script type="text/javascript" charset="utf-8" src="json2.js"></script>
<script type="text/javascript" charset="utf-8">
// Called when capture operation is finished
//
function captureSuccess(mediaFiles) {
var i, len;
for (i = 0, len = mediaFiles.length; i < len; i += 1) {
uploadFile(mediaFiles[i]);
}
}
// Called if something bad happens.
//
function captureError(error) {
var msg = 'An error occurred during capture: ' + error.code;
navigator.notification.alert(msg, null, 'Uh oh!');
}
// A button will call this function
//
function captureImage() {
// Launch device camera application,
// allowing user to capture up to 2 images
navigator.device.capture.captureImage(captureSuccess, captureError, {limit: 2});
}
// Upload files to server
function uploadFile(mediaFile) {
var ft = new FileTransfer(),
path = mediaFile.fullPath,
name = mediaFile.name;
ft.upload(path,
"http://my.domain.com/upload.php",
function(result) {
console.log('Upload success: ' + result.responseCode);
console.log(result.bytesSent + ' bytes sent');
},
function(error) {
console.log('Error uploading file ' + path + ': ' + error.code);
},
{ fileName: name });
}
</script>
and this in the body
<input type="button" class="button-big" style="width: 100%;" onclick="captureImage();" value="TAKE PHOTO">
copy and past and it works a dream,
Check it out in this image
any questions, just email comment,
or email me... support#carbonyzed.co.uk

phoneGap database creation example

I am trying to create a database using phonegap's api:
In order to do this I have used the following html:
<!DOCTYPE HTML>
<html>
<head>
<title>Cordova</title>
<script type="text/javascript" charset="utf-8" src="cordova-2.0.0.js"></script>
<script type="text/javascript" charset="utf-8">
// Wait for Cordova to load
//
document.addEventListener("deviceready", onDeviceReady, false);
// Cordova is ready
//
function onDeviceReady() {
var db = window.openDatabase("test", "1.0", "Test DB", 1000000);
alert("database created");
}
</script>
</head>
<body>
<form name="input" action="html_form_action.asp" method="get">
<input type="submit" value="Create Db" />
</form>
</body>
</html>
The buttone doesnt do anyting. The idea is that when the app starts I'm supposed to get confirmation that a database has been created. However this is not happening. Please help...
**Hi check whether Deviceready fires or not then try this **
function onDeviceReady() {
alert("onDeviceReady");
try {
if (!window.openDatabase) {
alert('Browser does not Support this');
} else {
var shortName = 'DbName';
var version = '1.0';
var displayName = 'DBName';
var maxSize = 100000; // in bytes
openDatabase(shortName, version, displayName, maxSize);
alert('DB created');
}
} catch(e) {
if (e == 2) {
// Version mismatch..
console.log("Invalid database version.");
} else {
console.log("Unknown error "+ e +".");
}
return;
}
}
I think there is problem in your js location path . I run your code and i didn't get any error.
Please check your path of your cordova.js . I think you put that js in js folder of assets/www/js
I dont think 'alert()' works inside a webview as-is. Try console.log() instead to output a message (if you are using eclipse), or some other method - perhaps changing the content of a div - to show you the results.

Playing local sound in phonegap

I have a .wav file in my www folder. I am using jQuery with the following code. The alerts go off but the sound does not play. Am I doing something wrong?
<script type="text/javascript" charset="utf-8" src="phonegap-0.9.2.js"></script>
<script type="text/javascript" charset="utf-8" src="jquery.js"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function () {
window.alert("READY!");
document.addEventListener("deviceready", onDeviceReady, true);
function onDeviceReady(){
window.alert("OK#!");
var snd = new Media("test.wav");
snd.play();
}
});
</script>
The sound just does not play.
You can use window.location.pathname to get the path of your application in any PhoneGap app. That way you don't have to hardcode it for Android. It will look something like this on iPhone:
/var/mobile/Applications/{GUID}/{appname}.app/www/index.html
And this on Android:
/android_asset/www/index.html
Strip off the /index.html, prepend file://, and append your file test.wav.
Demo: http://jsfiddle.net/ThinkingStiff/r7eay/
Code:
function getPhoneGapPath() {
var path = window.location.pathname;
path = path.substr( path, path.length - 10 );
return 'file://' + path;
};
var snd = new Media( getPhoneGapPath() + 'test.wav' );
Try giving an absolute local path. E.g.
new Media("/android_asset/www/test.wav");
That should work on Android. Hopefully they'll fix this in PhoneGap, as it's something of a bug in the cross-device support.
I have another version of getPhonegapPath, it detect's when you'r using Android:
function getPhoneGapPath() {
var path = window.location.pathname;
path = path.substr( path, path.length - 10 );
var devicePlatform = device.platform;
if(devicePlatform=="Android"){
path = 'file://'+path;
}
return path;
};

Categories

Resources