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
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.
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.
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>
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? )
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();