javascript - How to insert an img several times into a div using a loop - javascript

Hello I am trying to insert an img several times into a div, each time my img will have different properties. My Html code will have a div with an example id called ID_DIV.
I will have a style section into the html code like this img position absolute.
I will preset the variable NumberOfTimes according to the number of img I need into the div.
But I can't manage to make the loop work. Every time I refresh my browser my img appears in a different position, but it wont appear a "NumberOfTImes" times.
I have edited my code into this. But the loop wont work anyways. Still without knowing what it is.
function generateImg(){
var numberOfTimes=prompt("how many times?");
var div_id1=document.getElementById("div_id1");
do{
var oImg=document.createElement("img"); // Creates an oimg node
oImg.setAttribute('src', 's0me_s0urce'); // sets the source for img file
div_id1.appendChild(oImg); // append the img to #id Div.
document.querySelector('img').style.top = Math.floor(Math.random()*401)+'px';
document.querySelector('img').style.left = Math.floor(Math.random()*401)+'px';
numberOfTimes--;
}while(numberOfTimes>0);
}
Please Help. I can't find where is the mistake in this logic.

you need to declare "i" outside of the loop otherwise it will not decrement and will only ever be "NumberOfTimes - 1" and therefore your loop will loop repeadeteldy with the image in the same location. This is also assuming that "NumberOfTimes" is in in the same scope to be used in the first place. Note that I have moved the location of "i" and added a decrement to it in the loop.
function RandomPositionImgs(){
var i=NumberOfTimes;
do{
var oImg=document.createElement("img"); // Creates an oimg node
oImg.setAttribute('src', 'some_source'); // sets the source for img file
document.getElementById("ID_DIV").appendChild(oImg); // append the img to leftSide Div.
document.querySelector('img').style.top = Math.floor(Math.random()*401)+'px'; // random positioning
document.querySelector('img').style.left = Math.floor(Math.random()*401)+'px'; // random positioning
i--;
}while(i>0);
}

Thank you all for your answers you made me realize what I was doing wrong. This is the correct code I did after your comments, its working perfect.
function generateImgs(){
var numberOfTimes=prompt("how many times?");
for(i=0;i<numberOfFaces;i++){
var oImg=document.createElement("img"); // Creates an oimg node
oImg.setAttribute('src', 'valid source'); // sets the source for img file
document.getElementById("div id").appendChild(oImg); // append the img to Div.
oImg.style.top = Math.floor(Math.random()*401)+'px';
oImg.style.left = Math.floor(Math.random()*401)+'px';
}
}

My answer is obsolete now. Anyway, here is a way to deal with overlapping images:
var img, i, x, y;
var size = 48, w = 5, h = 3;
var grid = new Array(w * h).map(x => false);
var n = 5; // n > grid.length => infinite loop
var src = 'https://i.stack.imgur.com/6gwfY.gif?s=48&g=1';
var ct = document.getElementById('ct');
ct.style.width = size * w + 'px';
ct.style.height = size * h + 'px';
while (n-- > 0) {
i = next(), x = i % w, y = (i - x) / w;
img = document.createElement('img');
img.setAttribute('src', src);
img.style.left = size * x + 'px';
img.style.top = size * y + 'px';
ct.appendChild(img);
}
function next () {
var l = grid.length;
var i = Math.floor(Math.random() * l);
// as long as this position is not free, try the next one
while (grid[i]) i = (i + 1) % l;
return grid[i] = true, i;
}
img{position:absolute}
#ct{background:#eee}
#ct{position:relative}
<div id="ct"></div>

Related

Get div's width for p5.js

I'm learning on my own JavaScript so I'm doing something like a website using p5.js
The thing is that a div holding my canvas for p5.js and I want it to be responsive. In this canvas, I do have an object that needs the div width and height to be constructed.
Problem is that I don't know how to get this information. I tried jQuery but I don't know how to extract value out of a jQuery function and I'm don't know if it's an excessive way to do it.
//--------------------------constant--------------------------------------------
//Canvas
const DROPNUMBER = 1500;
//--------------------------classe---------------------------------------------
function Drop(width, heigth) {
//declaring and setting drop's attribute
this.spawn = function(width) {
//size and position
this.x = Math.random() * -width*1.5;
this.y = Math.random() * heigth;
this.size = Math.random() * 20 ;
//color
this.colorR = 138 + Math.random() * 50;
this.colorV = 43 + Math.random() * 50;
this.colorB = 226 + Math.random() * 50;
this.colorA = Math.random() * 127 +50;
//speed and landing
this.speed = Math.random();
this.hasLanded = false;
}
//call func to set the attribute
this.spawn(width);
//make the drop falls
this.fall = function() {
//if the drop can fall
if (this.x < width) {
this.x = this.x + this.speed;
this.speed = this.speed + 0.01;
//if the drop did land
if (this.y + this.size > width && this.hasLanded == false) {
this.hasLanded = true;
}
}
//if the drop did fall
else {
this.spawn(width);
}
}
//display the drop
this.display = function() {
noStroke();
//Some kind of purple color
fill(this.colorR, this.colorV, this.colorB, this.colorA);
rect(this.x, this.y, this.size, this.size)
}
}
//--------------------------setup---------------------------------------------
function setup() {
clientHeight = document.getElementById('header').clientHeight;
clientWidth = document.getElementById('header').clientWidth;
canvas = createCanvas(clientWidth, clientHeight);
canvas.parent('sketch-holder');
window.canvas = canvas;
}
//-------------------------Variable---------------------------------------------
var n = DROPNUMBER;
var drops = new Array();
//creating an array of drop for the rain
for (let i = 0; i < n; i++) {
//800 800 is height and the width that i want to change !
drops.push(new Drop(800,800));
}
//--------------------------draw------------------------------------------------
function draw() {
background(48, 64, 96);
//each drop
for (let i = 0; i < n; i++) {
//Make them falling
drops[i].fall();
//display the result
drops[i].display();
}
}
The code is just showing that drops ( the object that needs height and width) are being constructed out of draw or setup function.
I did search already on Stack Overflow to this kind of problem too.
use a regular DOM js it's worked:
let b = document.getElementById("parentElement");
let w = b.clientWidth;
let h = b.clientHeight;
console.log(w, h);
You don't need to use JQuery for this. Take a look at the P5.dom library that provides a bunch of functionality for manipulating HTML elements in P5.js.
I'm not sure exactly what you're trying to do, but here's a simple example. If we have a div on the page with and ID of myId, then to get its width we could use P5.dom to do this:
var myDiv = select('myId');
var myWidth = myDiv.style.width;
console.log('width: ' + myWidth);
To get the width of an element in JavaScript, you can select that element using document.querySelector(). Any CSS selector is a valid first argument to that function. E.g. the following will select the <body> tag:
document.querySelector('body')
Once you have an element selected, you can get it's width by accessing the clientWidth property. E.g. the following tells you the width of the <body> tag:
document.querySelector('body').clientWidth
So just replace body with a CSS selector for the element you want to select.

Javascript onclick event on newly created elements

I've got several functions all linked so it will ...
create new elements and set their properties and stuff
once elements are in place they should trigger function.
And they do! Kind of...
More like they trigger half of a function that's attached to them upon creation. The part where they onclick trigger a function that starts a loading on my progress bar (which is their purpose) is alright. But the much simpler part, where they hide after click, doesn't.
As the code is quite complex I'll place here larger part of it, so don't panic. Problem might be somewhere else then I expect. Here it is...
// defines function for checkpoint
function checkpointed() {
this.style.display = 'none'; // !here dwells the douch part!
if (toLoad < 100) {
toLoad += 100/$(this).attr('numButs');
var sim = setInterval(progressSim, 50);
}
// defining creation of checkpoints
function checkpoints(num) {
var angle = 4.72,
step = (2 * Math.PI) / num;
for (i = 1; i < num + 1; i++) {
var x = $('#progressBar').width()/2 + radius * Math.cos(angle) ;
var y = $('#progressBar').height()/2 + radius * Math.sin(angle);
angle += step;
var newContent = document.createElement('IMG');
var newCheckpoint = document.createElement('SPAN');
var numButs = document.createAttribute('numButs');
numButs.value = num;
var Class = document.createAttribute('class');
Class.value = 'checkpoint';
var img = document.createAttribute('src');
img.value = 'img/lock.png';
newContent.setAttributeNode(img);
newCheckpoint.setAttributeNode(numButs);
newCheckpoint.setAttributeNode(Class);
$(newCheckpoint).append(newContent);
$('.projectBar').append(newCheckpoint);
x -= 24;
y -= 24;
$(newCheckpoint).offset({top:y, left: x});
newCheckpoint.onclick = checkpointed;
};
};
// creates checkpoints upon clicking on create button
document.getElementById('create').onclick = function(){
checkpoints(document.getElementById('numCheckpoint').value);
$(this).hide();
$('#numCheckpoint').hide();
};
I should probably sum up what is this all about.
I have circular progressBar that measures progression of users project. User says "Hey, my project has like 5 steps (or 20 idc)" and "create" button will make 5 checkpoints placed on the progressBar evenly. By clicking on checkpoints you load the progress bar by 20% per clicked checkpoint.
Don't worry though, I've already figured out the code for loading and the geometrics.
However I'm bit stuck here... on simple onclick functions. Please if you have an idea try achieve it with plain JavaScript or jQuery (trying to do this without other frameworks, libraries or plugins).
EDIT: Just found out that checkpoint are set alright, as they really hide after clicking. Problem is in creation of checkpoints as the loop creates about 15 more checkpoints stacked one on another. So you have to click each of them to hide them all... So problem is in the loop.
EDIT2: Figured it out. The loop for (i = 1; i < num + 1; i++) had the numparameter as a String coming from input field. So simple parseInt() did the trick.
The mixed Jquery and plain Javascript is messing with my head... Any way how about when you create a new element, give it some sort of class. Instead of giving setting onclick, use jQuery's on selector to bind click events to those dynamic elements. Try The Following:
$(document).on("click", ".Checkpoint", function(event) {
$(event.target).hide();
if (toLoad < 100) {
toLoad += 100 / $(this).attr('numButs');
var sim = setInterval(progressSim, 50);
}
});
// defining creation of checkpoints
function checkpoints(num) {
var angle = 4.72,
step = (2 * Math.PI) / num;
for (i = 1; i < num + 1; i++) {
var x = $('#progressBar').width() / 2 + radius * Math.cos(angle);
var y = $('#progressBar').height() / 2 + radius * Math.sin(angle);
angle += step;
var newContent = $('<img></img>');
var newCheckpoint = $('<span></span>');
$("body").append(newCheckpoint);
newContent.attr("numButs", num);
newContent.attr("src", 'img/lock.png');
newContent.addClass("Checkpoint");
$(newCheckpoint).append(newContent);
$('.projectBar').append(newCheckpoint);
x -= 24;
y -= 24;
$(newCheckpoint).offset({
top: y,
left: x
});
}
}
// creates checkpoints upon clicking on create button
$(document).on("click","#create",function(e) {
checkpoints($('#numCheckpoint').val());
$(e.target).hide();
$('#numCheckpoint').hide();
});
Changed stuff to work more in jQuery, hope you don't mind...

Trouble getting images to display at random positions using javaScript

I am trying to generate 5 images on the left-hand side of the page in random positions. The images are displayed in a row across the top and not in the random positions that I require. I do have img{position:absolute} within my CSS. I am sorry if this has been covered previously, I have searched endlessly for an answer and tried many different examples, but I am still stuck, can someone point me in the right direction, please.
<script>
var numberOfFaces = 5;
var theLeftSide = document.getElementById("leftSide");
function getRandom(x, y) {
return Math.floor(Math.random() * (y - x)) + x + 'px';
};
function generateFaces() {
for (var i=0; i<numberOfFaces; i++) {
var faces = document.createElement("img");
faces.src = "smile.png";
faces.style.top = getRandom(0, 400);
faces.style.left = getRandom(0, 400);
leftSide.appendChild(faces);
};
};
</script>
http://jsfiddle.net/pynaam1f/
OR
http://jsfiddle.net/pynaam1f/1/
img{
position:absolute;
}

Creating image elements then setting style attributes through javascript error

So I created an image tag but I also want to be able to set attributes for the image tag created through the javascript that I have below
function start()
{
imageTag = document.createElement("IMG"); //Creates image tag
w = window.innerWidth //finds width of web page
h = window.innerHeight //finds height of web page
pic = document.getElementsByTagName("img"); //finds the tag name of "img"
x = Math.floor(Math.random()*(w))+1; //finds a random width that can be used for x coordinate that fits within site
y = Math.floor(Math.random()*(h))+1; //finds a random height that can be used for y coordinate that fits within site
pic.style.left = x+"px"; //Sets the style attribute that will be in the image tag that was created earlier *ERROR*
pic.style.top = y+"px"; //Sets the style attribute that will be in the image tag that was created earlier *ERROR*
imageTag.setAttribute("src", "popo.jpg" ); //sets the image tags source
document.body.appendChild(imageTag);
}
I can't seem to figure out why the style attribute of left and top aren't added like the other picture source attribute in the image tag that was created. If I have an image tag already in the html, then it works but not when I create one in javascript so this makes no sense because I feel like it should work.
Sounds like you'd benefit by keeping a reference to the last created image so you can set the position properties easily.
For example
var prevImage;
function start() {
if (prevImage) {
var x = Math.floor(Math.random() * window.innerWidth) + 1,
y = Math.floor(Math.random() * window.innerHeight) + 1;
prevImage.style.left = x + 'px';
prevImage.style.top = y + 'px';
}
var img = document.createElement('img');
img.src = 'popo.jpg';
document.body.appendChild(img);
prevImage = img;
}

Animating element to move up in html5/javascript canvas

I am making simple animations in JavaScript html canvas. Currently I have a function which makes the element (image) fall infinitely down. I would like to reverse it and make it go infinitely up (start at the bottom of the page and move up and up and up), but all my attempts and experiments failed.
I would be grateful for any ideas!
This is the function I have, which moves the element down:
function moveDown(){
start += 1;
var m = document.getElementById('money');
m.style.top = start + "px";
m.style.left = "300px";
}
var start = 350;
function rain() {
var m = document.createElement('img');
m.id = "money";
m.src = "images/holof.png";
m.style.position = "absolute";
m.style.top = start + "px";
// m.style.top="0px";
m.style.left = "300px";
m.setAttribute("class", "money");
document.body.appendChild( m );
setInterval(moveDown, 500);
}
How do I animate it to go up then?
I'm not sure what this has to do with canvas but you can simply do the following for your Image element to move upwards.
Reverse your start increment to a decrement
function moveUp(){
start--; /// move up 1 pixel
style.top = start + "px";
}
var start = 350;
var m = document.getElementById('money'); /// cache this here
var style = m.style; /// cache style
style.left = "300px"; /// set once here
The caching will improve the performance as it reduces the talkativeness between JS and the DOM.
However, as a tip: when the element has moved out of sight you will want to stop the loop as otherwise you will do unnecessary code invoking so adding a condition in there to stop the loop is something to consider.

Categories