Adding HTML rectangles with for loop in javascript - javascript

I would like to draw a 2 x 2 grid of blue rectangles on an HTML page, but my code does not draw anything. I create a fragment toAdd that I want to add later, and add divs to toAdd. I'm not quite sure where I went wrong, and when I tried to add a console.log() I could confirm that addSquares is being called. Do I need to add anything to the HTML file, or is there a mistake in this code?
I also noticed that this code produces five divs: b0, b1, b2, b3, b1 (returns error) and I'm not sure what is wrong with my for loop.
dim = 2;
width = 50;
height = 50;
// add the squares
function addSquares()
{
var toAdd = document.createDocumentFragment();
for(var i = 0; i < dim; i++)
{
for(var j = 0; j < dim; j++)
{
var label = j + i * dim;
var name = "b" + label;
console.log(name)
var div = document.createElement(name);
div.style.width = width + "px";
div.style.height = height + "px";
div.style.left = width * j + "px";
div.style.top = height * i + "px";
div.style.position = "absolute";
div.style.color = "blue";
toAdd.appendChild(div);
}
}
document.appendChild(toAdd);
}

So it appears that there's two issues. The first being that you need to change:
document.appendChild(toAdd);
to
document.body.appendChild(toAdd);
Your second issue is that your using the wrong CSS styling declaration. Your divs are in the DOM but don't have a backgroundColor assigned to them, which in turn gives the illusion that they're not there. So instead of color use backgroundColor.
dim = 2;
width = 50;
height = 50;
// add the squares
function addSquares()
{
var toAdd = document.createDocumentFragment();
for(var i = 0; i < dim; i++)
{
for(var j = 0; j < dim; j++)
{
var label = j + i * dim;
var name = "b" + label;
console.log(name)
var div = document.createElement(name);
div.style.width = width + "px";
div.style.height = height + "px";
div.style.left = width * j + "px";
div.style.top = height * i + "px";
div.style.position = "absolute";
div.style.backgroundColor = "blue";
toAdd.appendChild(div);
}
}
document.body.appendChild(toAdd);
}
addSquares();

I just wanted to point out a little trick to you...
You have this:
div.style.width = width + "px";
div.style.height = height + "px";
div.style.left = width * j + "px";
div.style.top = height * i + "px";
div.style.position = "absolute";
div.style.backgroundColor = "blue";
I believe can be written like this ES6:
div.style.cssText = `width: ${width + "px"};
height: ${height + "px"};
left: ${width * j + "px"};
top: ${height * i + "px"};
position: absolute;
backgroundColor: blue;`
As far as I know .cssText = will replace the existing inline...
To append the existing inline use .cssText +=
I'm sure this will help you in the long run.

Related

Creating an object generator

How do I create an object generator that will create a random square that is a random colour, size and position on the page? I think I have set up all the parameters but I can't put it all together.
//Size Generator
function getRndInteger(min, max) {
return Math.floor(Math.random() * (200 - 50 + 1) ) + 50;
}
var getSize = getRndInteger(50, 200);
//Colour Generator
function getRandomColor() {
var letters = '0123456789ABCDEF';
var colour = '#';
for (var i = 0; i < 6; i++) {
colour += letters[Math.floor(Math.random() * 16)];
}
return colour;
}
var colour = getRandomColor();
//Position Generator
function getPosition(min, max) {
return Math.floor(Math.random() * (600 - 0 + 1) ) + 0;
}
var getX = getPosition(0, 600);
var getY = getPosition(0, 600);
//Square Generator
function squareGenerator() {
var div = document.createElement("square");
div.style.backgroundColor = colour;
div.style.left = getX + "px";
div.style.top = getY + "px";
div.style.height = getSize + "px";
div.style.width = getSize + "px";
}
Where I am stuck is how to get this to show up on the page.
First of all, The created div will wrap around nothing, so You won't see it. a bypass would be setting the div.style.position to fixed.
Second of all, You need to append the div to the body, for example using: document.body.appendChild(div)
Third of all, You need to call the function, by placing the call: squareGenerator();
At last, when creating an element, use a valid HTML element, like div/section/article -> document.createElement('div'). It seems to be working with 'square' but I dont think all browsers will be that liberal.
//Size Generator
function getRndInteger(min, max) {
return Math.floor(Math.random() * (200 - 50 + 1) ) + 50;
}
var getSize = getRndInteger(50, 200);
//Colour Generator
function getRandomColor() {
var letters = '0123456789ABCDEF';
var colour = '#';
for (var i = 0; i < 6; i++) {
colour += letters[Math.floor(Math.random() * 16)];
}
return colour;
}
var colour = getRandomColor();
//Position Generator
function getPosition(min, max) {
return Math.floor(Math.random() * (200 - 0 + 1) ) + 0;
}
var getX = getPosition(0, 600);
var getY = getPosition(0, 600);
//Square Generator
function squareGenerator() {
var div = document.createElement("div");
div.style.backgroundColor = colour;
div.style.left = getX + "px";
div.style.top = getY + "px";
div.style.height = getSize + "px";
div.style.width = getSize + "px";
div.style.position='fixed';
document.body.appendChild(div);
}
squareGenerator();
You can see the desired square created at a random position.

How to rotate a div by using two points coordinates in JavaScript?

I am using div to create lines by reducing their widths. I have two random points coordinates and I want to draw a line between them using div. However, div only need one point coordinate along with their width and height for their creation and the result is always a vertical div. Is there any way to rotate a div so as to join two random points? I have tried rotate function, but it uses the specified angle.Here is the code I am using for div creation:
function creatediv(id, width, height, left, top, opacity)
{
var newdiv = document.createElement('div');
newdiv.setAttribute('id', id);
newdiv.style.width = width + "px";
newdiv.style.height = height + "px";
newdiv.style.position = "absolute";
newdiv.style.left = left + "px";
newdiv.style.top = top + "px";
newdiv.style.background = "red";
newdiv.style.opacity = opacity;
//newdiv.style.transform = "rotate(37deg)";
document.body.appendChild(newdiv);
}
For two points •a and •b , both having x y coordinates
distance Math.hypot(by-ay, bx-ax)
degrees Math.atan2(by-ay, bx-ax) * 180 / Math.PI;
The div is than positioned top,left according to the point a coordinates.
The transformOrigin needs to be defined as left 50% in order to keep the div point-centered:
function creatediv(id, ax,ay, bx,by, size, opacity, color) {
var length = Math.hypot(by-ay, bx-ax),
deg = Math.atan2(by-ay, bx-ax) * 180 / Math.PI;
var newdiv = document.createElement('div');
newdiv.setAttribute('id', id);
newdiv.style.width = length + "px";
newdiv.style.height = (size||2) + "px";
newdiv.style.left = ax + "px";
newdiv.style.top = ay + "px";
newdiv.style.background = color || "red";
newdiv.style.opacity = opacity || 1;
newdiv.style.transformOrigin = "left 50%";
newdiv.style.transform = "rotate("+ deg +"deg)";
newdiv.style.position = "absolute";
document.body.appendChild(newdiv);
}
creatediv("a", 20, 20, 200, 80);
Several connected lines, and a different approach to set styles:
function creatediv(id, ax,ay, bx,by, size, opacity, color) {
var length = Math.hypot(by-ay, bx-ax),
deg = Math.atan2(by-ay, bx-ax) * 180 / Math.PI,
newdiv = document.createElement('div'),
css = {
width: length + "px",
height: (size||2) + "px",
left: ax + "px",
top: ay + "px",
background: color || "red",
opacity: opacity || 1,
transformOrigin: "left 50%",
transform: "rotate("+ deg +"deg)",
position: "absolute"
};
for(var s in css) newdiv.style[s] = css[s];
document.body.appendChild(newdiv);
}
creatediv("a", 0,30, 10,10);
creatediv("b", 10,10, 60,80, 5, 0.3, "#0bf");
creatediv("c", 60,80, 70,50);
creatediv("d", 70,50, 150,90, null, null, "gold");
You can check angle and range between two point values and rotate it with this angle like that:
var newdiv = document.createElement('div');
newdiv.setAttribute('id', 10);
var point1x = 65;
var point1y = 45;
var point2x = 80;
var point2y = 90;
var height = Math.sqrt(Math.pow((point2x-point1x),2) + Math.pow((point2y-point1y),2));
var angleDeg = Math.atan2(point2y - point1y, point2x - point1x) * 180 / Math.PI;
newdiv.style.width = 30 + "px";
newdiv.style.height = height + "px";
newdiv.style.position = "absolute";
newdiv.style.left = point1x + "px";
newdiv.style.top = point1y + "px";
newdiv.style.borderColor = "black";
newdiv.style.borderWidth = "1px";
newdiv.style.borderStyle = "solid";
newdiv.style.background = "red";
newdiv.style.opacity = 5;
newdiv.style.transform = "rotate("+angleDeg+"deg)";
document.body.appendChild(newdiv);
I am a little bit amateur about math functions so test it before you use it please. There may be little mistakes about angle or height of element.
Edit: Now i see that you didn't want calculate angle. I don't know if there is a proper way to do that with angle. I won't delete this solution in case of anybody want to do that with angle calculation.

Invalid assignment and onload problems in javascript/html

I'm very new to HTML, CSS, and Javascript. So while I've been having trouble with some of the errors. Here's my code so far
<!doctype html>
<html>
<head>
<style>
div {position: absolute};
</style>
<script type="text/javascript">
function pattern() {
var the_body = getElementById("theBody");
var xPos = 25;
var yPos = 25;
var width = 300;
var height = 300;
while (xPos <= 105) {
var newDiv = docoument.createElement("div");
newDiv.style.left = xPos;
newDiv.style.top = yPos;
newDiv.width = width;
newDiv.height = height;
var randR = Math.floor(Math.random()*255);
var randG = Math.floor(Math.random()*255);
var randB = Math.floor(Math.random()*255);
newDiv.background-color = rgb(randR, randG, randB);
the_body.appendChild(newDiv);
xPos += 10;
yPos += 10;
width -= 20;
height -= 20;
}
}
</script>
</head>
<body id="theBody" onload="pattern()">
</body>
</html>
This code will generate a series of squares on top of each other that get progressively smaller. It will assign each a different background color. However, I'm getting the following errors
Uncaught ReferenceError: Invalid left-hand side in assignment
newDiv.background-color = rgb(randR, randG, randB);
Uncaught ReferenceError: pattern is not defined at onload
<body id="theBody" onload="pattern()">
I' really appreciate some help here. I don't see what I did wrong.
Thanks
newDiv.backgroundColor = rgb(randR, randG, randB);
and add after the function definition
window.onload = pattern;
background-color is not a valid property name, and the value you assign to it should be a string (quoted, with variables interpolated using string concatenation). In other words:
newDiv.style.backgroundColor = 'rgb(' + [randR, randG, randB] + ')';
A few other notes:
Use document.getElementById instead of getElementById;
You misspelled document in document.createElement("div");
You should use .style.width and .style.height to set the dimensions of your div (and make sure the values you assign end in a unit, like 'px').
Demo:
function pattern() {
var the_body = document.getElementById("theBody");
var xPos = 25;
var yPos = 25;
var width = 300;
var height = 300;
while (xPos <= 105) {
var newDiv = document.createElement("div");
newDiv.style.left = xPos + 'px';
newDiv.style.top = yPos + 'px';
newDiv.style.width = width + 'px';
newDiv.style.height = height + 'px';
var randR = Math.floor(Math.random() * 255);
var randG = Math.floor(Math.random() * 255);
var randB = Math.floor(Math.random() * 255);
newDiv.style.backgroundColor = 'rgb(' + [randR, randG, randB] + ')';
the_body.appendChild(newDiv);
xPos += 10;
yPos += 10;
width -= 20;
height -= 20;
}
}
<!doctype html>
<html>
<head>
<style>
div {
position: absolute;
}
</style>
</head>
<body id="theBody" onload="pattern()">
</body>
</html>

dynamically positioning and animating images in JavaScript

I'm trying to animate an image dynamically by assigning a slope and a starting position randomly. I don't understand why my image is not appearing and when I take the comments off the animate function my code won't run. Everything works properly except the animate functions at the bottom. Any help will be graciously accepted!
//Generate the table for the game
function createTable(difficulty, mineArray)
{
document.getElementById("buttons").style.visibility="hidden";
var time = 0.00;
var row = 0;
var size = 0;
var Lives = 0;
var column = 0;
var input = "";
var completion = 0;
var minesLeft = 0;
if(difficulty == 0)
{
Lives = 5;
size = 600;
row = 30;
column = 20;
}
else if (difficulty == 1)
{
Lives = 3;
size = 600;
row = 30;
column = 20;
}
else if (difficulty == 2)
{
Lives = 5;
size = 1000;
row = 40;
column = 25;
}
else if (difficulty == 3)
{
Lives = 3
size = 1000;
row = 40;
column = 25;
}
for (var i = 0; i < size; i++)
{
if (mineArray[i] == 9)
{
minesLeft = minesLeft + 1;
}
}
//Header
var head = document.getElementById("header").style.width = "100%"
document.getElementById("lives").innerHTML = "Lives: " + Lives;
document.getElementById("title").innerHTML = "Minesweeper Bullet Hell";
document.getElementById("time").innerHTML = "Time: " + time;
document.getElementById("footer").innerHTML = "Mines Left: " + minesLeft;
var name = document.getElementById("Name");
document.getElementById("names").innerHTML = "Welcome " + name.value;
//Main div (where the game is played)
var main = document.getElementById("main");
main.style.width = "100%"
main.style.height = "100%"
//Table
var div = document.getElementById("Table");
div.style.position = "absolute";
div.style.left = "5%";
div.style.top = "5%";
div.style.right = "5%";
div.style.verticalAlign = "true";
if(difficulty == 1 || difficulty == 0)
{
div.style.height = "900";
div.style.width = "600";
}
if(difficulty == 1 || difficulty == 0)
{
div.style.height = "1000";
div.style.width = "625";
}
div.style.zIndex="1";
//Iterate through columns
while(completion < size)
{
for (var i = 0; i < column; i++)
{
var tr = document.createElement('tr');
//Iterate through rows
for(var j = 0; j < row; j++)
{
var place = completion;
var td = document.createElement('td');
//For smaller minefield
if (size == 600)
{
td.style.width = "30";
td.style.height = "auto";
td.style.color = "blue";
//Add an image
var img = document.createElement('img');
img.src = "grey square.png";
img.style.display = "block";
img.style.height = "30";
img.style.width = "30";
td.appendChild(img);
}
//For larger minefield
else
{
td.style.width = "25";
td.style.height = "auto";
td.style.color = "blue";
//Add an image
var img = document.createElement('img');
img.src = "grey square.png";
img.style.display = "block";
img.style.height = "25";
img.style.width = "25";
td.appendChild(img);
}
//If it is a mine
if (mineArray[completion] == 9)
{
td.style.backgroundColor = "grey";
td.style.color = "red";
}
td.style.border = "1px solid #666666"
td.style.textAlign = "center"
tr.appendChild(td);
completion++;
}
//Think about adding an event listener instead of overlaying buttons?
main.appendChild(tr);
}
var cells = document.getElementsByTagName("td");
for (var j = 0; i < row; j++)
{
cells[j].addEventListener("click", function () {
//show number
var thiscol = this.cellIndex;
var thisrow = this.parentNode.rowIndex;
console.log("Clicked at " + thisrow + thiscol);
var cell = main.rows[thisrow].cells[thiscol];
cell.innerHTML = mineArray[(thisrow * row) + thiscol];
})
}
}
setTimeout(function(){bullets()}, 100);
}
function bullets()
{
//randomly generate bullets including starting positions, direction, and trajectory
//Generate starting position
//Generate starting edge
var xpos;
var ypos;
var bullets;
var slopes
var edge = (Math.floor(Math.random() * 4) + 1)
var bullet = document.createElement('img')
var screen = docuemnt.getElementById("bullets");
bullet.src = "blank.png"
bullet.style.position = "relative"
switch (edge)
{
//left edge
case 1:
bullet.style.left = 20 + "px";
ypos = (Math.floor(Math.random() * 100) + 1);
bullet.style.top = ypos + "px";
bullet.id = "left";
break;
//top edge
case 2:
bullet.style.top = 20 + "px";
xpos = (Math.floor(Math.random() * 100) + 1);
bullet.style.right = xpos + "px";
bullet.id = "top"
break;
//right edge
case 3:
bullet.style.right = 20 + "px";
ypos = (Math.floor(Math.random() * 100) + 1);
bullet.style.top = ypos+ "px";
bullet.id = "right";
break;
//bottom edge
case 4:
bullet.style.bottom = 20 + "px";
xpos = (Math.floor(Math.random() * 100) + 1);
bullet.style.right = xpos + "px";
bullet.id = "bottom";
break;
}
//Get the slope
var xslope = (Math.floor(Math.random() * 20) + 5);
var yslope = (Math.floor(Math.random() * 20) + 5);
bullets.append(bullet);
slopes.append(xpos);
slopes.append(ypos);
screen.appendChild(bullet);
//startAnimation(slopes, bullets);
}
/*
function startAnimation(var slopes, var bullets)
{
var j = 0;
var posy;
var posx;
var id;
for(i = 0; i < bullets.size(); i++)
{
while(j < (j+2))
{
id = bullets(i).id;
switch(id)
{
case "left":
posx = bullets(i).style.left;
posy = bullets(i).style.top;
bullets(i).style.left = posx + slopes(j);
bullets(i).style.top = posy + slopes(j+1);
break;
case "top":
posx = bullets(i).style.left;
posy = bullets(i).style.top;
bullets(i).style.left = posx + slopes(j);
bullets(i).style.top = posy + slopes(j+1);
break;
case "right":
posx = bullets(i).style.right;
posy = bullets(i).style.top;
bullets(i).style.right = posx + slopes(j);
bullets(i).style.top = posy + slopes(j+1);
break;
case "bottom":
posx = bullets(i).style.left;
posy = bullets(i).style.bottom;
bullets(i).style.left = posx + slopes(j);
bullets(i).style.bottom = posy + slopes(j+1);
break;
}
j += 2;
}
}
}*/
Looks like there could be a few things making startAnimation stop your script. Here's a few changes to try out:
In your startAnimation function declaration try removing the var keyword before the parameters. So you'd have:
function startAnimation(slopes, bullets) {
Within the for loop, use the .length property to check the array length rather than .size() (see: Array.size() vs Array.length)
The while loop is creating an infinite loop, because the condition (j < (j+2)) will always be true, since it's checking the current value of j. It might be easier to swap this out with a for loop.
Next, within the function, replace the parentheses with square brackets for accessing array indexes (replace bullets(i) with bullets[i] and slopes(j) with slopes[j]. By using parentheses, the JavaScript interpreter is attempting to call these variables as functions. Since you already have a function called bullets I'd recommend renaming either the function or your local variable / parameter to avoid the complexity of dealing with variable name conflicts and scope (more info: What is the scope of variables in JavaScript? )

remove elements in dom animation

I try to delete some animated elements if they pass the screen height. For that an array will be checked in a for loop. The array have the id's of the created div's. Theoretically should all div's which have an y position which is higher than the screen height become removed and the values from the array deleted. But now it becomes every n element removed. Know anyone the issue for that? box = setInterval(newbox, 1000); affect the behaviour when I change the interval time.
fiddle
var cx = wwidth / 100;
var cy = wheight / 100;
var maxpos = cx * 80;
var speed;
var box;
var counter = 0;
var rectids = [];
var deleting;
function newbox() {
var allpositions = Array(0, cx * 25, cx * 50, cx * 75);
var rectpos = allpositions[Math.floor(Math.random() * allpositions.length)];
speed = 0;
var box = document.createElement('div');
counter++;
box.className = "game-btn";
box.id = 'n' + counter;
box.style.cssText = "top:" + speed + "px;left:" + rectpos + "px;width:" + cx * 25 + "px;height:" + cy * 10 + "px;position:absolute";
console.log(rectpos);
document.body.appendChild(box);
rectids.push(box.id);
}
function game() {
box = setInterval(newbox, 1000);
animaterects = setInterval(function () {
speed += cx / 300;
$(".game-btn").css("top", "+=" + speed + "px");
}, 10);
deleting = setInterval(function () {
for (var i = 0; i < rectids.length; i++) {
var x = $("#" + rectids[i]).position();
if (x.top > wheight) {
$("#" + rectids[i]).remove();
rectids.splice(rectids[i]);
}
}
}, 50);
}
game();

Categories