Uncaught ReferenceError: ctx is not defined - javascript

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.

Related

How do I fix my html/javascript code to animate a sprite sheet?

I attempted to animate a sprite sheet using html and javascript to no avail. Here is my sprite sheet
Below is lines 36-59 of my code. I'm not getting any errors so I don't really know what's wrong. How do I fix/improve my code?
This is for a project I'm doing. I've tried using different methods I've found online but none really worked either. I've tried shifting the image as well.
<html>
<head>
<title>Tree Animation</title>
</head>
<body>
<canvas id='canvas'></canvas>
<script>
var canWidth = 400;
var canHeight = 100;
//position where the frame will be drawn
var x = 0;
var y = 0;
var srcX;
var srcY;
var sheetWidth = 230;
var sheetHeight = 79;
var frameCount = 5;
var width = sheetWidth/frameCount;
var height;
var currentFrame = 0;
var tree = new Image();
tree.src = "tree sprite.jpg"
var canvas = document.getElementById('canvas');
canvas.width = canWidth;
canvas.height = canHeight;
var ctx = canvas.getContext('2d');
function updateFrame(){
currentFrame = ++currentFrame%frameCount
srcX = currentFrame*width;
srcY = 0;
ctx.clearRect(x, y, width, height);
}
function draw(){
updateFrame();
}
setInterval(function(){
draw();
}, 100);
</script>
</body>
</html>
I expect the output to be an animation of a tree growing, but instead I'm getting a blank page.
you should provide more code or a snippet, there are several variables didn't show up in your code
and it's hard to debug your code if u use setInterval, you should make sure your code can work first.
maybe you can try step by step:
draw the whole img on the canvas first. if it works, go next
invoke your draw() function manually, check if the img drawed
invoke more, such assetTimout(draw, 1000), check the result
ok, and i think you can console.log these variables in draw

functions.js:1 Uncaught SyntaxError: Unexpected token {

var labels = {{ labels|tojson|safe }};
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
var drawLabels = function(id, xMin, xMax, yMin, yMax) {
ctx.strokeStyle = "red";
ctx.fillStyle = "red";
ctx.rect(xMin, yMin, xMax - xMin, yMax - yMin);
ctx.lineWidth="3";
ctx.stroke();
ctx.font = "10px Arial";
ctx.fillText("id: " + id, xMin,yMin);
};
function redraw() {
ctx.canvas.width = image.width;
ctx.canvas.height = image.height;
c.width = image.width;
c.height = image.height;
ctx.drawImage(image, 0, 0);
for (i = 0; i < labels.length; i++){
drawLabels(labels[i].id, labels[i].xMin, labels[i].xMax, labels[i].yMin, labels[i].yMax);
}
}
This is part of my javascript code, i had them both combined in a javascript/html code but a requirement was to separate the .js part. It worked perfectly at first but it stopped when i split the content and i get that error on my javascript file called functions.js kindly note it's just a part of my javascript code as sharing more than a 150 lines code without being explicitly asked to is probably a bad idea, but the error is apparently in line 1 as the title suggests.
It looks like labels is supposed to be an array (look at the for loop in redraw())
var labels = [labels, tojson, safe];
should work just fine.
Keep (move back) line 1 in the original python file
include your functions.js before the end of the <body> tag (to make sure that var labels=.... will come before functions.js in the generated HTML)
When you factored out functions.js, that file is not being processed by python anymore, so this part {{ labels|tojson|safe }} will not get substituted.
That is why you need to move line 1 back into python.

Canvas not working -- however no errors

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

js getContext stops further code from executing

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?

jQuery- Please explain to me Closure, variable context

Ok so I don't understand why Firefox is saying that the $("#canvas")[0].getContext('2d'); is undefined. I put it out of the function so that all of the function can access it but here the ctx is still undefined.
(function($) {
// Undefined
var ctx = $('#canvas')[0].getContext("2d");
var x = 150;
var y = 150;
var dx = 2;
var dy = 4;
$(function() {
setInterval(draw, 10);
})
function draw() {
ctx.clearRect(0,0,300,300);
ctx.beginPath();
ctx.arc(x,y,10,0,Math.PI*2,true);
ctx.closePath();
ctx.fill();
x+=dx;
y+=dy;
}
})(jQuery);
However when I transferred the location of ctx to the unnamed function, the ctx is not undefined:
(function($) {
var ctx;
var x = 150;
var y = 150;
var dx = 2;
var dy = 4;
$(function() {
//Not Undefined
ctx = $("#canvas")[0].getContext('2d');
setInterval(draw, 10);
})
function draw() {
ctx.clearRect(0,0,300,300);
ctx.beginPath();
ctx.arc(x,y,10,0,Math.PI*2,true);
ctx.closePath();
ctx.fill();
x+=dx;
y+=dy;
}
})(jQuery);
Whats wrong with the first code? I mean var ctx is declared on the top. So that would make it a global variable. Hmm the error that I got was $("#canvas")[0] is undefined. Means that it can't access the #canvas.. Why??
I think you've mistaken the problem. It is not that you have misunderstood your variable context but probably that you are running the javascript before your canvas tag has been declared.
The following code demonstrates the problem. It will display the message "canvasOne is undefined!" because we are trying to access canvasOne before it is declared (Note the placement of the <canvas> tags).
I've created a hosted demo here: http://jsbin.com/afuju (Editable via http://jsbin.com/afuju/edit)
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
</head>
<body>
<script>
/*
The following line of code is run as soon as the browser sees it.
Since the "canvasOne" tag is not declared yet, the variable will be undefined.
*/
var canvasOne = $('#canvasOne')[0];
$(function() {
// The following code is run after the whole document has finished loading.
if (canvasOne === undefined) {
alert('canvasOne is undefined!');
}
else {
canvasOne.getContext("2d").fillRect(5, 5, 15, 15);
}
});
</script>
<canvas id="canvasOne"></canvas>
<canvas id="canvasTwo"></canvas>
<script>
/*
The following line of code is run as soon as the browser sees it.
But since the "canvasTwo" tag *is* declared above, the variable will *not* be undefined.
*/
var canvasTwo = $('#canvasTwo')[0];
$(function() {
// The following code is run after the whole document has finished loading.
if (canvasTwo === undefined) {
alert('canvasTwo is undefined!');
}
else {
canvasTwo.getContext("2d").fillRect(5, 5, 15, 15);
}
});
</script>
<script>
$(function() {
/*
The following code is run after the whole document has finished loading.
Hence, the variable will *not* be undefined even though the "canvasThree" tag appears after the code.
*/
var canvasThree = $('#canvasThree')[0];
if (canvasThree === undefined) {
alert('canvasThree is undefined!');
}
else {
canvasThree.getContext("2d").fillRect(5, 5, 15, 15);
}
});
</script>
<canvas id="canvasThree"></canvas>
</body>
</html>
This is because in your first call you're actually creating a Function object which will be processed only after the DOM has loaded, in another context.
That anonymous function will be called when all the elements in the page have already loaded, so the caller will be a jQuery core function and its context is completely different from the one you're coding here.
I'd suggest wrapping everything inside the $() call, so this should work:
(function($) {
$(function() {
var ctx = $("#canvas")[0].getContext('2d');
var x = 150;
var y = 150;
var dx = 2;
var dy = 4;
setInterval(draw, 10);
function draw() {
ctx.clearRect(0,0,300,300);
ctx.beginPath();
ctx.arc(x,y,10,0,Math.PI*2,true);
ctx.closePath();
ctx.fill();
x+=dx;
y+=dy;
}
});
})(jQuery);

Categories

Resources