I'm trying to run a simple truck simulator (sorry for the liking of trucks), but when I try, it seems to not work (also no errors). However, when I run the entire code in the edit section of Bill Mill's Canvas Tutorial, it works. In case if you say it's my browser, this doesn't show "Oops...":
<canvas id="canvas" width="420" height="440" style="border: 1px solid #000;">Oops...
JS:
/*Truck Driving Simulator**/
//set up the canvas
var c = document.getElementById("canvas");
var w = 420;
var h = w+20;
var ctx = c.getContext('2d');
var t = tr(250,250,20,40,'blue');
function tr(iX,iY,iR,iColor){
return{
drawmove: function(){
ctx.beginPath();
ctx.arc(iX, iY, iR, 0, Math.PI*2, true);
ctx.fillStyle = iColor;
ctx.fill();
ctx.closePath();
}
}
}
function p(){
t.drawmove();
}
function init(){
setInterval(function(){
p();
}, 60);
}
init();
JSFiddle: https://jsfiddle.net/yey4xdoq/
Also, even though it shows in the fiddle, it doesn't on my PC.
I:
1. Made sure my browser supports the canvas tag
2. Correctly linked my Js
3. Correctly called the canvas
Related
I have a canvas elements in my webpage that is containing some text which I want to edit with text box.For example a text in canvas is "This is a apple" but later I want to change that text like this "Apple is never liked by me" This thing should be done via text box key up event with javascript or jQuery. Please give me some suggestions.
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.font = "20px Georgia";
ctx.fillText("This is a apple", 10, 50);
ctx.font = "30px Verdana";
// Create gradient
var gradient = ctx.createLinearGradient(0, 0, c.width, 0);
gradient.addColorStop("0", "magenta");
gradient.addColorStop("0.5", "blue");
gradient.addColorStop("1.0", "red");
// Fill with gradient
ctx.fillStyle = gradient;
ctx.fillText("Big smile!", 10, 90);
</script>
<input id="sourceText1" type=text>
</body>
</html>
I want to change the text with textbox.
Here's some code that will work with your current example. It is however, terribly flawed - I'd like to make that very clear.
0) I've had to add 4 pixels in order to get the erasing rect to cover the text properly. I'm not sure why this is needed, or how to query/calculate this - I used an image editor. If the size of your text was different, I'd imagine you would need to use a different 'magic-number' than 4.
1) The example will break-down if the background is not white, most particularly if you have a pattern, rather than a solid colour.
2) The whole text is erased and redrawn for each keystroke - we should ideally speaking, only be clearing it if necessary. I.e - if the text gets longer and the new text is the same up until the new character, there's nothing to erase.
3) I'm too tired to further examine my code for flaws.
4) You can almost certainly (actually I'm about 99.9999999% sure) find code that does this kind of task already - code which is far more robust and, is production-ready.
Consider this code nothing more than "a hack that works". If I could post it merely as a comment, I would.
Perhaps a better option would be to simply draw the text again, using white as the colour - though I've a feeling that this wont quite work, due to anti-aliasing, which will leave a faint outline - failing to properly cover the existing text.
If the code is unsuitable for you, simply bring it back along with your receipt for a full refund. :laughs:
That said, here you go:
<!DOCTYPE html>
<html>
<head>
<script>
function byId(id){return document.getElementById(id);}
window.addEventListener('load', onDocLoaded, false);
var textPosX = 10, textPosY = 50;
var defaultText = "This is a apple";
var curText = defaultText;
var defaultFont = "20px Georgia";
function onDocLoaded(evt)
{
// add event listener to the input element, this will fire any time (text) input is received
byId('sourceText1').addEventListener('input', onSourceTextInput, false);
var c = byId("myCanvas");
var ctx = c.getContext("2d");
ctx.font = defaultFont;
ctx.fillText(defaultText, textPosX, textPosY);
ctx.font = "30px Verdana";
// Create gradient
var gradient = ctx.createLinearGradient(0, 0, c.width, 0);
gradient.addColorStop("0", "magenta");
gradient.addColorStop("0.5", "blue");
gradient.addColorStop("1.0", "red");
// Fill with gradient
ctx.fillStyle = gradient;
ctx.fillText("Big smile!", 10, 90);
}
function onSourceTextInput(evt)
{
var can = byId('myCanvas');
var ctx = can.getContext('2d');
var curTextWidth, curTextHeight;
curTextWidth = ctx.measureText(curText).width;
curTextHeight = 20;
var curStyle = ctx.fillStyle;
ctx.fillStyle = "white";
ctx.fillRect(textPosX, (textPosY-curTextHeight)+4, curTextWidth, curTextHeight);
ctx.fillStyle = 'BLACK';
ctx.font = defaultFont;
ctx.fillText( this.value, textPosX, textPosY );
ctx.fillStyle = curStyle;
curText = this.value;
}
</script>
</head>
<body>
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">Your browser does not support the HTML5 canvas tag.</canvas>
<input id="sourceText1" type='text'/>
</body>
</html>
I have a working getContext in my JavaScript code, but for some reason nothing is executed after this method. Here, I added two alerts and only one of them runs:
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas"
width="0"
height="0"
style="border:5px solid #888888; fill: solid #DDDDDD;"
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>
// basic vars
var squareDim = 25;
var screenWidth = 10;
var screenHeight = 20;
// setting up the canvas
var canvas = document.getElementById("myCanvas");
canvas.width = screenWidth * squareDim;
canvas.height = screenHeight * squareDim;
alert(1)
var ctx = c.getContext("2d");
alert(2);
// draw a single square
function putSquare(color, x, y) {
ctx.fillStyle = color;
ctx.fillRect(x * squareDim, y * squareDim, squareDim, squareDim);
}
for (i=0; i<screenHeight; i++) {
putSquare("#FF0000", i, 0);
}
</script>
</body>
Does anyone have an idea where did I screw up?
You're calling c.getContext(...), you have no c variable declared - you need to call this on canvas instead:
var ctx = canvas.getContext('2d');
In future you can debug things like this in your browser's JavaScript console. In your JavaScript console, you'll see that your code here is throwing the following error:
Uncaught ReferenceError: c is not defined
See: How to open the JavaScript console in different browsers?
I've tried everything to solve this problem and nothings working. Posting here is my last resort.
I'm trying to code a simple canvas element and load everything dynamically and nothing is working. I keep getting the error in Google console "Uncaught ReferenceError: ctx is not defined" on game.js:33.
I originally thought it was because common.js is being loaded after the other 2 javascript files so I made a loader file which loads each JS file in the order I want. I did this using $.getScript() and the $.when() function . Unfortunately, this did not work. So the ctx var is being loaded but it's giving me the error for some reason.
I've included the files below. Thanks in advance for any help.
EDIT: I just tried taking all the code out of each individual JS file and putting them in the same one in the order they are meant to be in and it works fine now. But it would be nice to know why it was not working at all. As it's going to get very hectic having all my code in 1 file. Thank you.
index.php
<!doctype>
<html>
<head>
<title>Game - Unknown</title>
<link rel="stylesheet" href="./assets/css/default.css">
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.3.3.min.js"></script>
<!--<script src="./assets/js/loader.js"></script>-->
<script src="./assets/js/common.js"></script>
<script src="./assets/js/graphics.js"></script>
<script src="./assets/js/game.js"></script>
</head>
<body>
<canvas id="viewport"></canvas>
</body>
</html>
common.js
$(document).ready(function(){
// Setup the canvas game context for 2D
var canvas = document.getElementById("viewport");
var ctx = canvas.getContext("2d");
// Update the canvas dimensions to match window size when changed
$(window).resize(function(){canvasResize()}); canvasResize();
function canvasResize(){
var cWidth = window.innerWidth;
var cHeight = window.innerHeight;
canvas.width = cWidth;
canvas.height = cHeight;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, cWidth, cHeight);
}
// Get center of things - Useful for centering images on canvas
function getCenter(dim){ return dim / 2 }
});
graphics.js
$(document).ready(function(){
function gfxTile(x, y, w, h, r, g, b, a)
{
ctx.fillStyle = "rgb(60, 60, 100)";
ctx.beginPath();
//ctx.moveTo(x + h / 2, y + w / 2);
ctx.moveTo(10, 10);
ctx.lineTo(105, 25);
ctx.lineTo(25, 105);
ctx.lineTo(25, 105);
ctx.closePath();
ctx.fill();
}
});
game.js
$(document).ready(function(){
// START TEMPORARY
var mapSizeX = 10;
var mapSizeY = 10;
var mapArray = new Array();
function createMap()
{
for(x = 0; x < mapSizeX; x++)
{
mapArray[x] = [];
for(y = 0; y < mapSizeY; y++)
{
mapArray[x][y] = 0;
}
}
}
// END TEMPORARY
setInterval(mainLoop, 50);
function mainLoop()
{
//gfxTile(10, 10, 40, 40, 50, 50, 50, 100);
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
});
var ctx = canvas.getContext("2d"); created a variable called ctx in the scope of the function you passed into $(document).ready();
When the function inside of game.js executes, there is no ctx variable in its scope, or the parent scope, window.
An easy fix would be changing
var ctx = canvas.getContext("2d");
to
window.ctx = canvas.getContext("2d");
Your ctx variable is already on a reachable namespace, your problem is basically a result of loading files with no order and priority. You can however use a script loader to solve the problem and make sure your variable is already defined before using it.
In this example I'm using the head.js script loader.
<script src="js/head.js"></script>
<script>
head.js(
"http://code.jquery.com/jquery-1.9.1.min.js",
"http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.3.3.min.js",
"js/common.js",
"js/graphics.js",
"js/game.js"
);
You can optimize your code even more using requireJS to expose only the namespaces you want . Check them out.
Just giving canvas a go for the first time with the intention of creating a game. I have an image displaying but oddly the fillStyle method doesn't seem to be working. ( At least the canvas background is still white in google chrome.)
Note that in my code the canvas var is actually the canvas elements 2d context, maybe that's where i'm getting myself confused? i can't see the problem, would appreciate if anyone else could.
LD24.js:
const FPS = 30;
var canvasWidth = 0;
var canvasHeight = 0;
var xPos = 0;
var yPos = 0;
var smiley = new Image();
smiley.src = "http://javascript-tutorials.googlecode.com/files/jsplatformer1-smiley.jpg";
var canvas = null;
window.onload = init; //set init function to be called onload
function init(){
canvasWidth = document.getElementById('canvas').width;
canvasHeight = document.getElementById('canvas').height;
canvas = document.getElementById('canvas').getContext('2d');
setInterval(function(){
update();
draw();
}, 1000/FPS);
}
function update(){
}
function draw()
{
canvas.clearRect(0,0,canvasWidth,canvasHeight);
canvas.fillStyle = "#FFAA33"; //orange fill
canvas.drawImage(smiley, xPos, yPos);
}
LD24.html:
<html>
<head>
<script language="javascript" type="text/javascript" src="LD24.js"></script>
</head>
<body>
<canvas id="canvas" width="800" height="600">
<p> Your browser does not support the canvas element needed to play this game :(</p>
</canvas>
</body>
</html>
3 notes:
fillStyle does not cause your canvas to be filled. It means that when you fill a shape it will be filled with that color. Therefore you need to write canvas.fillRect( xPos, yPos, width, height).
Wait until your image actually loads, otherwise the rendering may be inconsistent or buggy.
Careful of cross-domain images used in your canvas - most browsers will throw a security exception and stop executing your code.
Wait till image loads as well:
var img = new Image();
img.onload = function() {
handleLoadedTexture(img);
};
img.src = "image.png";
function handleLoadedTexture(img) {
//call loop etc that uses image
};
Or maybe you were just missing
canvas.fill();
after
canvas.drawImage(smiley, xPos, yPos);
The Image is flickering as I continuously push the button. The problem might be in ctx.clearRect(0,0,100,500) . How can I resolve the problem?
I am trying to animate in HTML 5 canvas.
I need a moving object in canvas and when I push the button, the other moving object follow the previous without flickering.
function draw(x,y){
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.save();
ctx.clearRect(0,0,100,500); // This may be the problem
var img=document.getElementById("Image");
ctx.drawImage(img,50,y);
ctx.restore();
y -= 10;
var loopTimer = setTimeout('draw('+x+','+y+')',50);
}
HTML 5
<button onclick="draw(0,500)">Draw</button>
<canvas id="canvas" width="600" height="500">
</canvas>
It looks like the problem may be because you aren't clearing the entire canvas. Try this:
function draw(x,y){
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.save();
ctx.clearRect(0,0, canvas.width, canvas.height);
var img=document.getElementById("Image");
ctx.drawImage(img,50,y);
ctx.restore();
y -= 10;
var loopTimer = setTimeout('draw('+x+','+y+')',50);
}
Demo
The image flicker when you press the button more than once, which means you start the setTimeout() more than once. Add a variable to check if it's already been pressed.