I am trying to draw a ball in my html using javascript. The javascript is referenced by the HTML file since it is an external script. However, I only get a blank page in return. Can someone help please? Thanks!
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device=width,initial-scale=1.0">
<script type = "text/javascript" src="projectscripts.js"></script>
</head>
<body onload="ball.draw()">
<canvas id="canvas" width = "3000" height = "3000"></canvas>
</body>
</html>
In my javascript file:
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var raf;
var ball = {
x: 600,
y: 300,
radius: 25,
color: 'blue',
draw: function() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, true);
ctx.closePath();
ctx.fillStyle = this.color;
ctx.fill();
}
};
Move the <script type = "text/javascript" src="projectscripts.js"></script> just before </body>.
The error comes, because the script is executed before the body is rendered, and because of that the variable canvas is null and everything that is using it "blows".
I recommend to always have the devtools open, so you can debug and see errors.
Related
`Hello! I have a problem with uploading an image to a canvas element in JS. I saved the image to some folder in my project, then I tried to upload it with the classic function, but then I faced that there is no errors, but my image is not displayed. Help me, please. All code and screenshots are further:
Code:
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Game of Drones</title>
<link rel="stylesheet" href="S:\Coding\JS\UAVGame\CSS\style.css">
</head>
<body>
<canvas id="field" width="800px" height="600px"></canvas>
<script src="S:\Coding\JS\UAVGame\JS\main.js"></script>
</body>
</html>`
CSS:
#field {
position: absolute;
left: 22%;
border: 9px grey double;
width: 800px;
height: 600px;
background: rgb(8, 2, 63);
}
JS:
let field = document.querySelector("#field");
let ctx = field.getContext("2d");
let UAV = new Image();
UAV.src = "S:/Coding/JS/UAVGame/OTHER/IMAGES/UAVBASED.png";
class Star {
constructor(xCoord, yCoord, radius) {
this.x = xCoord;
this.y = yCoord;
this.R = radius;
}
draw() {
ctx.fillStyle = "grey";
ctx.beginPath();
ctx.arc(this.x, this.y, this.R, 0, 2 * Math.PI);
ctx.fill();
ctx.closePath();
}
}
let stars = [];
function drawScene() {
ctx.drawImage(UAV, 250, 250);
}
drawScene();
Screen of project structure
I don't know even what I have to try, because I use classic functions with a classic bundle of parameters, so I assume, that there is some magic, which makes me face that problem.`
Try calling drawScene on image onload event like below
UAV.onload = function(){
drawScene();
}
Also verify the path of image. I would suggest using absolute path like
UAV.src = "../OTHER/IMAGES/download.png";
I'm trying to load the image on canvas but it's not working:(
I checked functions and variables much time but I couldn't find any errors.
Help me to find the reasons why it can't be loaded.
When I run it on the tomcat server, only the canvas with aliceblue color is shown.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Print image and text</title>
<script>
function drawPicture(ctx) {
var img = new Image();
img.addEventListener('load', function() {
ctx.drawImage(img, 20, 20, 100, 100);
ctx.font = "50px forte";
ctx.strokeStyle="blue";
ctx.fillStyle = "violet";
ctx.strokeText("Spongebob", 20, 100);
ctx.fillText("Spongebob", 20, 100);
}, false);
img.src = "spongebob.png";
}
</script>
</head>
<body>
<h3>Print image and text</h3>
<hr>
<canvas id="myCanvas" width="300" height="130"
style="background-color:aliceblue"></canvas>
<script>
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
drawPicture(context);
</script>
</body>
</html>
Your code is fine, here is an example with a different image...
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="300" height="130"></canvas>
<script>
function drawPicture(ctx) {
var img = new Image();
img.addEventListener('load', function() {
ctx.drawImage(img, 20, 20, 100, 100);
ctx.font = "50px forte";
ctx.strokeStyle = "blue";
ctx.fillStyle = "violet";
ctx.strokeText("Spongebob", 20, 100);
ctx.fillText("Spongebob", 20, 100);
}, false);
img.src = "http://i.stack.imgur.com/UFBxY.png";
}
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
drawPicture(context);
</script>
</body>
</html>
Only thing could be that the image you are trying to load does not exist...
As #Kaiido mentioned in the comments you need to debug this, check in your browser developer tools see if the image is loading correctly.
You should see something like:
instead of image.addEventListener, try doing image.onload?
You can instead of using the load event in the image, try adding the image directly on the canvas.
function drawPicture(ctx) {
var img = new Image();
img.src = "spongebob.png";
ctx.drawImage(img, 20, 20, 100, 100);
ctx.font = "50px forte";
ctx.strokeStyle="blue";
ctx.fillStyle = "violet";
ctx.strokeText("Spongebob", 20, 100);
ctx.fillText("Spongebob", 20, 100);
}
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
drawPicture(context);
<h3>Print image and text</h3>
<hr>
<canvas id="myCanvas" width="300" height="130"
style="background-color:aliceblue"></canvas>
I have a simple canvas in which I'm drawing a rectangle using Rough.js library. The issue I'm having is Rough js randomizing the draw pattern so each time the rectangle method is called, it seems to shake/jitter inside requestAnimationFrame. I'm not too familiar with the library I'm wondering if anyone here has any experience to either set some constants to force the rectangle to be drawn the exact same way or disable randomisation altogether.
<html>
<head>
<script type='text/javascript' src="https://unpkg.com/roughjs#4.3.1/bundled/rough.js"></script>
</head>
<body>
<canvas id="canvas" width="480" height="640"></canvas>
</body>
<script>
window.addEventListener('DOMContentLoaded',event=>{
let canvas = document.getElementById("canvas");
let ctx = canvas.getContext('2d');
let r = rough.canvas(canvas);
function draw(tick){
requestAnimationFrame(draw);
ctx.clearRect(0,0,480,640);
r.rectangle(50, 50, 80, 80, {
fill: 'rgba(255,0,200,0.2)',
fillStyle: 'solid' // solid fill
});
}
requestAnimationFrame(draw);
});
</script>
</html>
When you run the snippet you can see the jittering/shaking. That's what I wish to disable.
You'll want to use the RoughGenerator to create a rectangle instruction once and reuse it:
const canvas = document.querySelector("canvas")
const ctx = canvas.getContext("2d");
const r = rough.canvas(canvas);
// First we set up a rectangle
const rect = r.generator.rectangle(50, 50, 80, 80, {
fill: 'rgba(255,0,200,0.2)',
fillStyle: 'solid' // solid fill
});
(function draw(tick) {
requestAnimationFrame(draw);
ctx.clearRect(0, 0, 480, 640);
// Then we draw it as many times as we want
r.draw(rect);
})();
<script src="https://unpkg.com/roughjs#4.3.1/bundled/rough.js"></script>
<canvas></canvas>
I'm trying to make a javascript game but nothing is showing up on my html canvas after I imported a js file(car.js), everything was showing up before I imported car.js. I currently have a folder called cargame and it includes 3 files, car.js, firstgame.html and index.js. I'm providing the contents of the files below.
firstgame.html
<!DOCTYPE html>
<html>
<head>
<title>Web Page Design</title>
<style>
#gamescreen{
border: 1px solid black;
}
#bgcolor{
background-color: #b4b4b4;
}
</style>
</head>
<body id="bgcolor">
<div align = "center" style="margin-top: 5%"><canvas id = "gamescreen" width = "500px" height = "600px"></canvas></div>
<script src="index.js"></script>
</body>
</html>
index.js
import car from "./car";
let canvas = document.getElementById("gamescreen");
let ctx = canvas.getContext('2d');
const GAME_WIDTH = 500;
const GAME_HEIGHT = 600;
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, canvas.width/3, canvas.height)
ctx.fillRect((canvas.width/3 + canvas.width/3), 0, canvas.width/3, canvas.height)
ctx.fillStyle = '#2a2a2a';
ctx.fillRect(canvas.width/3, 0, canvas.width/3, canvas.height)
ctx.clearRect(0,0,500,600)
let Car = new car(GAME_WIDTH, GAME_HEIGHT);
Car.draw(ctx);
car.js
export default class car{
constructor(gamewidth, gameheight){
this.width = 100;
this.height = 100;
this.position = {
x : gamewidth/2 - this.width/2,
y : gameheight - this.height - 10,
};
}
draw(ctx){
ctx.fillStyle = '#ff6969';
ctx.fillRect(this.position.x, this.position.y, this.width, this.height);
}
}
I'm getting the following errors in my logs
firstgame.html:1 Access to script at 'file:///C:/MY%20DATA/java%20projects/cargame/index.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
error 2
firstgame.html:19 GET file:///C:/MY%20DATA/java%20projects/cargame/index.js net::ERR_FAILED
you need to add type="module" to the script tag
<script type="module" src='index.js'></script>
and the fix the import
import car from "./car.js";
you need to put your project inside any local server such as XAMP,MAMP,WAMP and add '.js' to the car import in index.js file, run your local server and it will work.
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.