Adding objects into array - javascript

Could someone tell me what's wrong with this code ? I am trying to fill canvas with squares as objects but as the loop is done and i am trying to draw that square on canvas nothing happens...
var canvas = document.getElementById('c');
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(35, 180, 218)";
var rectHeight = 5;
var rectWidth = 5;
var cells = [];
for (var i = 0; i <= canvas.width/rectWidth; i++) {
for (var x = 0; x <= canvas.height/rectHeight; x++) {
cells[i] = {
posX : i*rectWidth,
posY : x*rectHeight,
draw : function() {
ctx.fillRect(posX, posY, rectWidth, rectHeight);
},
clear : function() {
ctx.clearRect(posX, posY, rectWidth, rectHeight);
}
};
}
}
cells[2].draw;

var canvas = document.getElementById('c');
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#FF0000";
var rectHeight = 15;
var rectWidth = 15;
var cells = [];
for (var i = 0; i <= canvas.width/rectWidth; i++) {
for (var x = 0; x <= canvas.height/rectHeight; x++) {
cells[i] = {
posX : i*rectWidth,
posY : x*rectHeight,
draw : function() {
ctx.fillRect(this.posX, this.posY, rectWidth, rectHeight);
},
clear : function() {
ctx.clearRect(positionX, positionY, rectWidth, rectHeight);
}
};
}
}
cells[2].draw();
<canvas id="c" width="500" height="400"></canvas>

Thanks for the help #Xufox #SimranjitSingh and #Andreas..
Code now works like this:
var canvas = document.getElementById('c');
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(35, 180, 218)";
var rectHeight = 5;
var rectWidth = 5;
var cells = [];
for (var i = 0; i <= canvas.width/rectWidth; i++) {
for (var x = 0; x <= canvas.height/rectHeight; x++) {
cells[i*x] = {
posX : i*rectWidth,
posY : x*rectHeight,
draw : function() {
ctx.fillRect(this.posX, this.posY, rectWidth, rectHeight);
},
clear : function() {
ctx.clearRect(this.posX, this.posY, rectWidth, rectHeight);
}
};
}
}
cells[2].draw();

Related

How can I make a canvas element responsive when resizing the screen?

I have Matrix canvas on my site and there is problem with responsiveness when I change the width of the viewport the canvas doesn't update to fit.
https://codepen.io/ems-sin/pen/zYjpree
HTML
<canvas id="bglitch" ></canvas>
CSS
*{
margin:0;
background-color:#010b13;
overflow: hidden;
}
#bglitch{
opacity: 0.5;
z-index: -10;
top: 0;
right:0;
}
Javascript
var bglitch = document.getElementById("bglitch");
var ctx = bglitch.getContext("2d");
bglitch.height = window.innerHeight;
bglitch.width = window.innerWidth;
var matrix = "アィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶヷヸヹヺ・ーヽ";
matrix = matrix.split("");
var font_size = 24;
var columns = bglitch.width/font_size;
var drops = [];
for(var x = 0; x < columns; x++)
drops[x] = 1;
function draw()
{
ctx.fillStyle = "rgba(0, 0, 0, 0.04)";
ctx.fillRect(0, 0, bglitch.width, bglitch.height);
ctx.fillStyle = "#f4427d";
ctx.font = font_size + "px arial";
for(var i = 0; i < drops.length; i++){
var text = matrix[Math.floor(Math.random()*matrix.length)];
ctx.fillText(text, i*font_size, drops[i]*font_size);
if(drops[i]*font_size > bglitch.height && Math.random() > 0.975)
drops[i] = 0;
drops[i]++;
}
}
setInterval(draw, 35);
You need to make your code into a function which gets called on the resize event so that the dimensions are updated.
This snippet also clears the current timing interval (if there is one) before starting another one.
<style>
<canvas id="bglitch"></canvas>
</style>
<canvas id="bglitch"></canvas>
<script>
var bglitch = document.getElementById("bglitch");
var ctx = bglitch.getContext("2d");
let timer = '';
function init() {
bglitch.height = window.innerHeight;
bglitch.width = window.innerWidth;
var matrix = "アィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶヷヸヹヺ・ーヽ";
matrix = matrix.split("");
var font_size = 24;
var columns = bglitch.width / font_size;
var drops = [];
for (var x = 0; x < columns; x++)
drops[x] = 1;
function draw() {
ctx.fillStyle = "rgba(0, 0, 0, 0.04)";
ctx.fillRect(0, 0, bglitch.width, bglitch.height);
ctx.fillStyle = "#f4427d";
ctx.font = font_size + "px arial";
for (var i = 0; i < drops.length; i++) {
var text = matrix[Math.floor(Math.random() * matrix.length)];
ctx.fillText(text, i * font_size, drops[i] * font_size);
if (drops[i] * font_size > bglitch.height && Math.random() > 0.975)
drops[i] = 0;
drops[i]++;
}
}
clearInterval(timer);
timer = setInterval(draw, 35);
}
window.onresize = init;
window.onload = init;
</script>
You need to add resize event listener and recalculate columns accordingly.
Add this at the end of your javascript
window.addEventListener('resize', () => {
bglitch.height = window.innerHeight;
bglitch.width = window.innerWidth;
var columns = bglitch.width/font_size;
for(var x = 0; x < columns; x++) drops[x] = 1;
})
Full working resize
var bglitch = document.getElementById("bglitch");
var ctx = bglitch.getContext("2d");
bglitch.height = window.innerHeight;
bglitch.width = window.innerWidth;
var matrix = "アィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶヷヸヹヺ・ーヽ";
matrix = matrix.split("");
var font_size = 24;
var columns = bglitch.width/font_size;
var drops = [];
for(var x = 0; x < columns; x++)
drops[x] = 1;
function draw()
{
ctx.fillStyle = "rgba(0, 0, 0, 0.04)";
ctx.fillRect(0, 0, bglitch.width, bglitch.height);
ctx.fillStyle = "#f4427d";
ctx.font = font_size + "px arial";
for(var i = 0; i < drops.length; i++){
var text = matrix[Math.floor(Math.random()*matrix.length)];
ctx.fillText(text, i*font_size, drops[i]*font_size);
if(drops[i]*font_size > bglitch.height && Math.random() > 0.975)
drops[i] = 0;
drops[i]++;
}
}
setInterval(draw, 35);
window.addEventListener('resize', () => {
bglitch.height = window.innerHeight;
bglitch.width = window.innerWidth;
var columns = bglitch.width/font_size;
for(var x = 0; x < columns; x++) drops[x] = 1;
})
*{
margin:0;
background-color:#010b13;
overflow: hidden;
}
#bglitch{
opacity: 0.5;
z-index: -10;
top: 0;
right:0;
}
<canvas id="bglitch" ></canvas>
It's better practice to separate your code into functions. For example init() function that sets all initial variables and run function that will run setTimeout and so on.
let bgData = {
element: undefined,
g: undefined,
matrix: "アィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶヷヸヹヺ・ーヽ".split(''),
fontSize: 24,
columns: undefined,
drops: [],
};
function init() {
bgData.element = document.getElementById("bglitch");
bgData.g = bgData.element.getContext("2d");
resize();
window.addEventListener('resize', resize)
}
function resize() {
bgData.element.height = window.innerHeight;
bgData.element.width = window.innerWidth;
bgData.columns = bgData.element.width / bgData.fontSize;
for(let x = 0; x < bgData.columns; x++) bgData.drops[x] = 1;
}
function draw() {
bgData.g.fillStyle = "rgba(0, 0, 0, 0.04)";
bgData.g.fillRect(0, 0, bgData.element.width, bgData.element.height);
bgData.g.fillStyle = "#f4427d";
bgData.g.font = bgData.fontSize + "px arial";
for(let i = 0; i < bgData.drops.length; i++) {
const text = bgData.matrix[Math.floor(Math.random()*bgData.matrix.length)];
bgData.g.fillText(text, i * bgData.fontSize, bgData.drops[i] * bgData.fontSize);
if(bgData.drops[i] * bgData.fontSize > bgData.element.height && Math.random() > 0.975) bgData.drops[i] = 0;
bgData.drops[i]++;
}
}
let interval;
function stop() {
clearInterval(interval);
window.removeEventListener('resize', resize)
}
function run() {
stop();
init();
interval = setInterval(draw, 35);
}
run();
*{
margin:0;
background-color:#010b13;
overflow: hidden;
}
#bglitch{
opacity: 0.5;
z-index: -10;
top: 0;
right:0;
}
<canvas id="bglitch" ></canvas>

Canvas not drawing after using

I have a function that, when called, clears the canvas.
function ClearCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
The problem I'm having is that when I try to draw something onto the canvas again using fillRect() the items I want to draw appear on the bottom of the canvas, only a few of them showing up. The second time I try, nothing shows up.
To see my full code and a test run, go here
var width = 50;
var height = 50;
var interpolate = d3.interpolate('white', 'black');
var elevation = [];
var colormap = [];
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
var rectY = 0;
Generate2DArray(elevation, 0, width, height);
Generate2DArray(colormap, 0, width, height);
var gen = new SimplexNoise();
function Generate2DArray(EmptyArray, fill, width, height) {
for(var i = 0; i < height; i++) {
EmptyArray.push([]);
for(var j = 0; j < width; j++) {
EmptyArray[i][j] = fill;
}
}
}
function noise(nx, ny) {
// Rescale from -1.0:+1.0 to 0.0:1.0
return gen.noise2D(nx, ny) / 2 + 0.5;
}
function ClearCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
function GenTerrain() {
for(var y = 0; y < height; y++) {
for(var x = 0; x < width; x++) {
var nx = x/width - 0.5, ny = y/height - 0.5;
elevation[y][x] = noise(nx * 2.57, ny * 2.57);
colormap[y][x] = interpolate(elevation[y][x]);
ctx.fillStyle = colormap[y][x];
ctx.fillRect(x*10, y+rectY, 10, 10);
}
rectY += 9
}
}
Your rectY is being declared at the top of your code, at the global level:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
var rectY = 0;
So, every time GenTerrain runs, it references that variable and adds to it:
rectY += 9
Fix it by encapsulating rectY inside GenTerrain so it starts at 0 each time the function is called.
function GenTerrain() {
var rectY = 0;
for(var y = 0; y < height; y++) {
for(var x = 0; x < width; x++) {
var nx = x/width - 0.5, ny = y/height - 0.5;
elevation[y][x] = noise(nx * 2.57, ny * 2.57);
colormap[y][x] = interpolate(elevation[y][x]);
ctx.fillStyle = colormap[y][x];
ctx.fillRect(x*10, y+rectY, 10, 10);
}
rectY += 9
}
}

Canvas rotation - fixed background, moving foreground

Goal
The stripes in the background remain fixed while the cones rotate about the center.
Current State
live demo:
https://codepen.io/WallyNally/pen/yamGYB
/*
The loop function is around line 79.
Uncomment it to start the animation.
*/
var c = document.getElementById('canv');
var ctx = c.getContext('2d');
var W = c.width = window.innerWidth;
var H = c.height = window.innerHeight;
var Line = function() {
this.ctx = ctx;
this.startX = 0;
this.startY = 0;
this.endX = 0;
this.endY = 0;
this.direction = 0;
this.color = 'blue';
this.draw = function() {
this.ctx.beginPath();
this.ctx.lineWidth = .1;
this.ctx.strokeStlye = this.color;
this.ctx.moveTo(this.startX, this.startY);
this.ctx.lineTo(this.endX, this.endY);
this.ctx.closePath();
this.ctx.stroke();
}
this.update = function() {
//for fun
if (this.direction == 1) {
this.ctx.translate(W/2, H/2);
this.ctx.rotate(-Math.PI/(180));
}
}//this.update()
}//Line();
objects=[];
function initLines() {
for (var i =0; i < 200; i++) {
var line = new Line();
line.direction = (i % 2);
if (line.direction == 0) {
line.startX = 0;
line.startY = -H + i * H/100;
line.endX = W + line.startX;
line.endY = H + line.startY;
}
if (line.direction == 1) {
line.startX = 0;
line.startY = H - i * H/100;
line.endX = W - line.startX;
line.endY = H - line.startY;
}
objects.push(line);
line.draw();
}
}
initLines();
function render(c) {
c.clearRect(0, 0, W, H);
for (var i = 0; i < objects.length; i++)
{
objects[i].update();
objects[i].draw();
}
}
function loop() {
render(ctx);
window.requestAnimationFrame(loop);
}
//loop();
What I have tried
The translate(W/2, H/2) should place the context at the center of the page, then this.ctx.rotate(-Math.PI/(180)) should rotate it one degree at a time. This is the part that is not working.
Using save()and restore() is the proper way to keep some parts of an animation static while others move. I placed the save and restore in different parts of the code to no avail. There are one of two types of result : Either a new entirely static image is produced, or some erratic animation happens (in the same vein of where it is now).
Here is the changed pen: http://codepen.io/samcarlinone/pen/LRwqNg
You needed a couple of changes:
var c = document.getElementById('canv');
var ctx = c.getContext('2d');
var W = c.width = window.innerWidth;
var H = c.height = window.innerHeight;
var angle = 0;
var Line = function() {
this.ctx = ctx;
this.startX = 0;
this.startY = 0;
this.endX = 0;
this.endY = 0;
this.direction = 0;
this.color = 'blue';
this.draw = function() {
this.ctx.beginPath();
this.ctx.lineWidth = .1;
this.ctx.strokeStlye = this.color;
this.ctx.moveTo(this.startX, this.startY);
this.ctx.lineTo(this.endX, this.endY);
this.ctx.closePath();
this.ctx.stroke();
}
this.update = function() {
//for fun
if (this.direction == 1) {
this.ctx.translate(W/2, H/2);
this.ctx.rotate(angle);
this.ctx.translate(-W/2, -H/2);
}
}//this.update()
}//Line();
objects=[];
function initLines() {
for (var i =0; i < 200; i++) {
var line = new Line();
line.direction = (i % 2);
if (line.direction == 0) {
line.startX = 0;
line.startY = -H + i * H/100;
line.endX = W + line.startX;
line.endY = H + line.startY;
}
if (line.direction == 1) {
line.startX = 0;
line.startY = H - i * H/100;
line.endX = W - line.startX;
line.endY = H - line.startY;
}
objects.push(line);
line.draw();
}
}
initLines();
function render(c) {
c.clearRect(0, 0, W, H);
for (var i = 0; i < objects.length; i++)
{
ctx.save();
objects[i].update();
objects[i].draw();
ctx.restore();
}
}
function loop() {
render(ctx);
window.requestAnimationFrame(loop);
angle += Math.PI/360;
}
loop();
First I added a variable to keep track of rotation and increment it in the loop
Second I save and restore for each individual line, alternatively if all lines were going to perform the same transformation you could move that code before and after the drawing loop
Third to get the desired affect I translate so the center point is in the middle of the screen, then I rotate so that the lines are rotated, then I translate back because all the lines have coordinates on the interval [0, H]. Instead of translating back before drawing another option would be to use coordinates on the interval [-(H/2), (H/2)] etc.

How to make the objects fall in javascript?

I am trying to make this game, you should not collide the falling object. I have the objects falling and I have my black square, but it flashes when I run it and Im not sure how to make the code stop when the two objects collide together.
here is the code that I have so far!
<html>
<body>
<canvas id="canvasRegn" width="600" height="450"style="margin:100px;"></canvas>
<script>
var ctx;
var imgBg;
var imgDrops;
var noOfDrops = 50;
var fallingDrops = [];
function drawBackground(){
ctx.drawImage(imgBg, 0, 0); //Background
}
function draw() {
drawBackground();
for (var i=0; i< noOfDrops; i++)
{
ctx.drawImage (fallingDrops[i].image, fallingDrops[i].x, fallingDrops[i].y); //The rain drop
fallingDrops[i].y += fallingDrops[i].speed; //Set the falling speed
if (fallingDrops[i].y > 480) { //Repeat the raindrop when it falls out of view
fallingDrops[i].y = -25 //Account for the image size
fallingDrops[i].x = Math.random() * 800; //Make it appear randomly along the width
}
}
}
function setup() {
var canvas = document.getElementById('canvasRegn');
if (canvas.getContext) {
ctx = canvas.getContext('2d');
imgBg = new Image();
imgBg.src = "http://www.hamdancommunications.com/HComm/img/wite%20square.png";
setInterval(draw, 36);
for (var i = 0; i < noOfDrops; i++) {
var fallingDr = new Object();
fallingDr["image"] = new Image();
fallingDr.image.src = 'http://s18.postimg.org/o6jpmdf9x/Line1.jpg';
fallingDr["x"] = Math.random() * 800;
fallingDr["y"] = Math.random() * 5;
fallingDr["speed"] = 3 + Math.random() * 5;
fallingDrops.push(fallingDr);
anotherGame();
}
}
}
setup();
function anotherGame(){
var canvas = document.getElementById("canvasRegn");
var ctx = canvas.getContext('2d');
canvas.addEventListener("mousedown", clicked);
canvas.addEventListener("mousemove", moved);
canvas.addEventListener("mouseup", released);
var isclicked = 0;
var square = new Object();
square.color = "black";
square.x = 100;
square.y = 100;
square.w = 50;
square.h = 50;
var offX = 0;
var offY = 0;
function draw(){
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.fillStyle = square.color;
ctx.fillRect(square.x,square.y,square.w,square.h);
}
function game(){
}
function clicked(e){
var x = e.offsetX;
var y = e.offsetY;
if(x >= square.x && x <= square.x + square.w &&
y >= square.y && y <= square.y + square.h){
isclicked = 1;
offX = x - square.x;
offY = y - square.y;
}
}
function moved(e){
if(isclicked == 1){
var x = e.offsetX;
var y = e.offsetY;
square.x = x - offX;
square.y = y - offY;
}
}
function released(e){
var x = e.offsetX;
var y = e.offsetY;
isclicked = 0;
}
var drawtimer = setInterval(draw, 1000/30);
var gametimer = setInterval(game, 1000/10);
}
</script>
</body>
</html>

For-Loop not running when called

Code:
function SnakeGame() {
"use strict";
/***** Constant & Global Variables ***********************************/
var canvas = $("#canvas")[0];
var ctx = canvas.getContext('2d');
var width = $("#canvas").width();
var height = $("#canvas").height();
var snake, food;
function Snake() {
var startLength = 5; // default for starting size of snake
this.body = [];
this.chgStartLength = function(length) {
startLength = length;
};
this.create = function() {
var i;
for(i=0; i>5; i++) {
this.body.push({x:i, y:0});
}
};
}
var paintCanvas = function() {
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, width, height);
ctx.strokeStyle = 'black';
ctx.strokeRect(0, 0, width, height);
};
var paintFrame = function() {
var i, length = snake.body.length;
for(i=0; i<length; i++) {
var cell = snake.body[i];
ctx.fillStyle = 'black';
ctx.fillRect(cell.x*10, cell.y*10, 10, 10);
ctx.strokeStyle = 'white';
ctx.strokeRect(cell.x*10, cell.y*10, 10, 10);
}
};
this.start = function() {
snake = new Snake();
snake.create();
paintCanvas();
paintFrame();
console.log(snake.body); //for testing
};
}
For some reason snake.body is an empty array even after start is executed.
for(i=0; i>5; i++) {
That > is facing in the wrong direction, I believe.
for(i = 0; i < 5; i++) {

Categories

Resources