I am having trouble adding boxes dynamically to an HTML canvas. There should be a random amount of boxes, in random positions, of random colors.
The goal of what I am doing with the boxes is to be able to move them.
Essentially I am really lost.
Here is the html code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Ramdom Boxes</title>
<script src="A2Q1.js"></script>
</head>
<body>
</body>
</html>
Here is the Javascript code:
window.onload = init;
function init() {
//when page is loaded create a bunch of boxes randomly throughout the page
//get the body element of the document
var body = document.getElementsByTagName("body")[0];
//create the canvas tag
var canvas = document.createElement("canvas");
canvas.height = 666;
canvas.width = 1346;
var context = canvas.getContext("2d");
//create the random boxes and append onto the canvas
var randNum = Math.floor(Math.random() * 1000 + 1);
var boxes = [];
for(var i=0;i<randNum;i++){
boxes[i].height = 50;
boxes[i].width = 50;
boxes[i].x = Math.floor(Math.random() * (1346 - boxes[i].width));
boxes[i].y = Math.floor(Math.random() * (666 - boxes[i].height));
boxes[i].colour = '#'+ Math.round(0xffffff * Math.random()).toString(16);
}
for(var i=0;i<boxes.length;i++){
context.fillStyle = colour;
context.fillRect(boxes[i].x, boxes[i].y, , boxes[i].height);
}
//append the canvas onto the body
body.appendChild(canvas);
}
Nothing is showing up on the page, through debugging it seems it is having issues with the properties. I am not sure where to go from here.
You can use masonry jquery plugin to sort boxes.
context.fillStyle = colour;
Did you mean
context.fillStyle = boxes[i].colour;
Related
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
In my transition from the basics of Python (learned on the Coursera RICE course) to the Javascript ones, I'm trying to register even handlers using the same paradigm people here have been helping me successfully converting.
In this example, both the timer and update handlers aren't running :
//Globals
var message = "test message";
var positionX = 50;
var positionY = 50;
width = 500;
height = 500;
var interval = 2000;
//handler for text box
function update(text) {
message = text;
}
//handler for timer
function tick() {
var x = Math.floor(Math.random() * (width - 0) + 0);
var y = Math.floor(Math.random() * (height - 0) + 0);
positionX = x;
positionY = y;
}
//handler to draw on canvas
function draw(canvas) {
ctx.font="20px Georgia";
ctx.fillText(message,positionX,positionY);
}
//create a frame
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
canvas.width = width;
canvas.height = height;
//register event handlers
setInterval(tick, interval);
draw();
//start the frame and animation
<html>
<head>
</head>
<body>
Enter text here :
<input type="text" onblur="update(this.value)">
<canvas id="myCanvas" style="border:1px solid #000000;"></canvas>
<script>
</script>
</body>
</html>
Adding canvas.addEventListener("draw", draw(), false); and canvas.addEventListener("update", update(), false); didn't change anything.
Though, the only time it "worked" was when I added the draw(); call inside the tick(); function but it was keeping the text and duplicating it on screen randomly as the functions should work.
On a general note, do you guys think the current paradigm :
//Global state
//Handler for text box
//Handler for timer
//Handler to draw on canvas
//Create a frame
//Register event handlers
//Start the frame animation
is worth pursuing with JS and Canvas ?
Again, thanks for your time and help.
K.
The draw function should be inside the tick function. If you want to stop the old text you need to clear the canvas before you draw the text again. SetInterval is ok for time over 100ms or so but if you plan to do full frame animation 60fps use requestAnimationFrame
I am personally not a fan of setInterval and use setTimeout instead. Also note that the times given for set interval and timeout are approximations only. Javascript is single threaded and if the timeout or interval occurs while code is running then the events will wait until the current execution is complete.
"use strict";
//Globals
var message = "test message";
var positionX = 50;
var positionY = 50;
// constants
const width = 500;
const height = 500;
const interval = 2000;
if(typeof inputText !== "undefined"){
inputText.value = message;
}
//handler for text box
function update(text) {
message = text;
}
//handler for timer
function tick() {
setTimeout(tick, interval); // create the next timer event
positionX = Math.floor(Math.random() * width);
positionY = Math.floor(Math.random() * (height-20)); // 20 pixels of height to stop it disappearing
draw();
}
//handler to draw on canvas
function draw() {
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
var textWidth = ctx.measureText(message).width;
ctx.fillText(message,Math.min(width - textWidth, positionX), positionY);
}
//create a context
const canvas = document.getElementById('myCanvas');
// set size befor get context as it is a little more efficient
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
// if the same font only need to set it once or after the canvas is resized
ctx.font="20px Georgia";
//start the animation
tick();
<html>
<head>
</head>
<body>
Enter text here :
<input id="inputText" type="text" onblur="update(this.value)">
<canvas id="myCanvas" style="border:1px solid #000000;"></canvas>
<script>
</script>
</body>
</html>
I am trying to make my image follow my mouse. I have used a lecture guide from university to create this code, and it seems identical to all the code I've seen, but I get the error in Chrome developer tools:
Uncaught TypeError: thisCanvas.addEventListener is not a function
Any ideas? I've stared at this for hours now.
<!DOCTYPE html>
<html>
<head>
<title> Gravity Game </title>
<meta charset = "UTF-8">
<link type = "text/css" rel = "stylesheet" href = "style.css">
</head>
<body onLoad="start_game()">
<header>
<h1 id = "title1"> Gravity </h1> <h1 id = "title2"> Game </h1>
</header>
<ul id = "nav">
<li class = "inactive"> About </li>
<li id = "active"> Play Game </li>
</ul>
<canvas id = "myCanvas" width = "1500" height = "500"></canvas>
<script>
var thisCanvas = document.getElementById("myCanvas").style.background = 'white';
var context = myCanvas.getContext("2d");
var worldX = 100;
var worldY = 100;
//Draw a circle
/*context.beginPath();
context.arc(95, 50, 40, 0, 2 * Math.PI);
context.closePath();
context.fill();*/
thisCanvas.addEventListener("mousemove",seen_move,false);
function seen_move(e)
{
var bounding_box = thisCanvas.getBoundingClientRect();
worldX = (e.clientX-bounding_box.left) * (thisCanvas.width/bounding_box.width);
worldY = (e.clientY-bounding_box.top) * (thisCanvas.height/bounding_box.height);
}
function start_game()
{
setInterval(loop_game, 50);
}
function loop_game()
{
thisCanvas.width = thisCanvas.width;
update_world(worldX, worldY);
}
function update_world(x, y)
{
var world_img = new Image();
world_img.src = "images/world.png";
context.drawImage(world_img, x, y);
}
</script>
</body>
</html>
var thisCanvas = document.getElementById("myCanvas").style.background = 'white';
thisCanvas now has the string value white.
thisCanvas.addEventListener() is basically like saying 'white'.addEventListener(). Because there’s no String.prototype.addEventListener this won’t work.
You need to assign document.getElementById("myCanvas") to thisCanvas and then set its background color.
var thisCanvas = document.getElementById("myCanvas").style.background = 'white';
should be
var thisCanvas = document.getElementById("myCanvas")
You are trying to assign your canvas style-changing methods as variable thisCanvas, instead of assigning the canvas element itself
The problem is with:
var thisCanvas = document.getElementById("myCanvas").style.background = 'white';
thisCanvas does not hold a reference to the <canvas> element. Instead, it's bound to 'white' because of a chained assignment.
You probably want something like:
var thisCanvas = document.getElementById("myCanvas");
thisCanvas.style.background = 'white';
I'm having a little trouble with randomly positioning a bunch of random boxes throughout a page.
The goal is to have a randomly amount of boxes show up in random positions and the boxes are to be random colors on a page. The boxes should also be overlapping, making them truly in random positions.
Thus far all I have is one randomly colored box on the page, clearly not randomly positioned. I'm suck of where to go from here with the positioning and creating a bunch of random boxes...
Please note JQuery cannot be used.
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Ramdom Boxes</title>
<script src="A2Q1.js"></script>
</head>
<body>
</body>
</html>
Javascript:
window.onload = init;
function init() {
//when page is loaded create a bunch of boxes randomly throughout the page
//get the body element of the document
var body = document.getElementsByTagName("body")[0];
//create the canvas tag
var canvas = document.createElement("canvas");
canvas.height = 100;
canvas.width = 100;
var context = canvas.getContext("2d");
//create the box and append onto the canvas
var colour = '#'+ Math.round(0xffffff * Math.random()).toString(16);
context.fillStyle = colour;
context.fillRect(25,25,50,50);
//append the canvas onto the body
body.appendChild(canvas);
}
It would be better to resize the canvas as much as window size. In order to draw a bunch of rectangles, use for loop to execute draw rectangle code repeatedly. Set each rectangle's position in window width and height (Math.random() * window.innerWidth, Math.random() * window.innerHeight).
Here is my sample code.
function init() {
var body = document.getElementsByTagName("body")[0];
var canvas = document.createElement("canvas");
canvas.height = window.innerHeight;
canvas.width = window.innerWidth;
var context = canvas.getContext("2d");
// Opacity makes a good appearance when objects are overlapped
context.globalAlpha=0.7;
// Repeat to draw a rectangle 100 times
for(var i=0;i<100;i++){
var color = '#'+ Math.round(0xffffff * Math.random()).toString(16);
context.fillStyle = color;
//Each rectangle is at (0 ~ width of window, 0 ~ height of window)
//Each rectangle's size is (20 ~ 100, 20 ~ 100)
context.fillRect(Math.random()*window.innerWidth, Math.random()*window.innerHeight, Math.random()*80+20, Math.random()*80+20);
}
body.appendChild(canvas);
}
window.onload = init;
For generating the random color you can refer this post
In order to get the x and y random values with respect to the width and height of the entire screen try this.
var maxWidth = 1000;
var maxHeight = 1000;
var randomX = Math.max(0, Math.min((maxWidth - boxWidth), Math.random() * maxWidth));
var randomY = Math.max(0, Math.min((maxHeight - boxHeight), Math.random() * maxHeight));
Set the position for the canvas like this.
box.style.position = "absolute";
box.style.left = randomX;
box.style.top = randomX;
create a table in your page and put that random box randomly to a cell.
for example
<table>
<!--many cell-->
</table>
then you may put your box randomly to a table's cell.
I really only care about Webkit, but in general, is Raphael JS expected to perform well when building thousands of rectangles?
Additionally, I would need to be able to handle events on each of these rectangles (yipes).
I've got a C++ solution which works but I'd rather use RaphaelJS.
Thanks :)
I don't know nothing about RaphaelJS but I can give you a performance hint with this code:
<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8">
<title></title>
<script>
window.onload = function () {
var rectangles = 5000;
for (var i = 0; i < rectangles; i ++) {
var height = 50;
var width = 50;
var canvas = document.createElement ("canvas");
canvas.height = height;
canvas.style.margin = "15px";
canvas.width = width;
canvas.addEventListener ("click", function () {
alert ("You like to MOVE !");
}, false);
var ctx = canvas.getContext ("2d");
ctx.fillStyle = "silver";
ctx.fillRect (0, 0, width, height)
document.body.appendChild (canvas);
}
canvas = document.body.getElementsByTagName ("canvas");
window.setInterval (function () {
for (var i = 0; i < canvas.length; i ++) {
canvas[i].style.margin = (Math.floor (Math.random () * 16)) + "px";
}
}, 100);
}
</script>
</head>
<body></body>
</html>
5000 rectangles moving around with "onclick" event:
If you would like to test out performance of Raphael JS I've posted a quick example of plotting 10,000 points. Tests render and clear times.
http://jsfiddle.net/jaRhY/1049/