Using this - random position of divs in javascript as a starting point I am trying to randomly position divs containing text from an array.
Current code (predominately copied Ken Redler's answer in the linked post):
(function makeDiv(){
var divsize = 200;
var color = '#'+ Math.round(0xffffff * Math.random()).toString(16);
//set up the array to hold the random div content
var boastsText = [];
var i = 0;
$(".boast ul li").each(function() { boastsText.push($(this).text()) });
$newdiv = $('<div/>').css({
'width':divsize+'px',
'height':divsize+'px',
'color': color
});
// make position sensitive to size and document's width
var posx = (Math.random() * ($(document).width() - divsize)).toFixed();
var posy = (Math.random() * ($(document).height() - divsize)).toFixed();
$newdiv.css({
'position':'absolute',
'left':posx+'px',
'top':posy+'px',
'display':'none'
}).html(boastsText[i]).appendTo( 'body' ).fadeIn(100).delay(1000).fadeOut(500, function(){
$(this).remove();
makeDiv();
});
})();
The only thing I have really added is the setting up of the array var boastsText = [] and the each function that populates that array.
The problem I have is I need to iterate over the array so each new div created uses the next item as it's content i.e. div 1 uses array item 0, div 2 uses item 1 etc... until it reaches the end of the array and then starts the process again.
I've modified your script a little bit to use a recursive function in order to iterate over the array and maintain the delay and fadeIn/Out you have:
(function() {
//set up the array to hold the random div content
var boastsText = [];
$(".boast ul li").each(function () {
boastsText.push($(this).text());
});
function makeDiv(i){
var divsize = 200;
var color = '#'+ Math.round(0xffffff * Math.random()).toString(16);
var $newdiv = $('<div/>').css({
'width':divsize+'px',
'height':divsize+'px',
'color': color
});
// make position sensitive to size and document's width
var posx = (Math.random() * ($(document).width() - divsize)).toFixed();
var posy = (Math.random() * ($(document).height() - divsize)).toFixed();
$newdiv.css({
'position':'absolute',
'left':posx+'px',
'top':posy+'px',
'display':'none'
}).html(boastsText[i]).appendTo('body').fadeIn(100).fadeOut(500, function() {
$(this).remove();
if (i === boastsText.length) return;
makeDiv(++i);
});
}
//Start the recursion
makeDiv(0);
}());
Related
I want to display random numbers inside a div at random positions without overlapping.
I am able to display random number at random position but its going outside the box and overlapping each other.
Here is my code:
JS Fiddle
var width = $('.container').innerWidth();
var height = $('.container').innerHeight();
(function generate() { // vary size for fun
for (i = 0; i < 15; i++) {
var divsize = 12;
var color = '#' + Math.round(0xffffff * Math.random()).toString(16);
$newdiv = $('<div/>').css({
'width': divsize + 'px',
'height': divsize + 'px'
});
// make position sensitive to size and document's width
var posx = (Math.random() * (width - divsize)).toFixed();
var posy = (Math.random() * (height - divsize)).toFixed();
$newdiv.css({
'position': 'absolute',
'left': posx + 'px',
'top': posy + 'px',
'float': 'left'
}).appendTo('.container').html(Math.floor(Math.random() * 9));
}
})();
How can I do this?
You've got most of it figured out. You just need to think of the .container div as a grid to avoid any overlap or outlying items.
Just check out this fiddle.
Here's what the code looks like:
var tilesize = 18, tilecount = 15;
var gRows = Math.floor($(".container").innerWidth()/tilesize);
var gCols = Math.floor($('.container').innerHeight()/tilesize);
var vals = _.shuffle(_.range(tilecount));
var xpos = _.shuffle(_.range(gRows));
var ypos = _.shuffle(_.range(gCols));
_.each(vals, function(d,i){
var $newdiv = $('<div/>').addClass("tile");
$newdiv.css({
'position':'absolute',
'left':(xpos[i] * tilesize)+'px',
'top':(ypos[i] * tilesize)+'px'
}).appendTo( '.container' ).html(d);
});
PS:I have used underscore in my fiddle to make things easier for me and because I personally hate writing for loops.
If the number of divs you need to create is small enough (i.e. you're not risking that they won't fit) then a simple algorithm is:
pick a random position (x0, y0)-(x1, y1)
check if any previously selected rect overlaps
if none overlaps then add the rect, otherwise loop back and choose another random position
in code
var selected = [];
for (var i=0; i<num_divs; i++) {
while (true) {
var x0 = Math.floor(Math.random() * (width - sz));
var y0 = Math.floor(Math.random() * (height - sz));
var x1 = x0 + sz;
var y1 = y0 + sz;
var i = 0;
while (i < selected.length &&
(x0 >= selected[i].x1 ||
y0 >= selected[i].y1 ||
x1 <= selected[i].x0 ||
y1 <= selected[i].y0)) {
i++;
}
if (i == selected.length) {
// Spot is safe, add it to the selection
selected.push({x0:x0, y0:y0, x1:x1, y1:y1});
break;
}
// The choice collided with a previously added div
// just remain in the loop so a new attempt is done
}
}
In case the elements are many and it's possible to place n-1 of them so that there's no position where to put n-th element then things are a lot more complex.
For the solution of the 1-dimensional version of this problem see this answer.
You can add to array position of each number. And then when ou generate new position for digit you should check if posx posy in array, if false place number there, if true generate new posx and posy
Objective: Display many squares or any object (words, images, etc.) simultaneously fading in and out.
The example below shows only one square at a time flashing in and out.
http://jsfiddle.net/redler/QcUPk/8/
(function makeDiv(){
var divsize = ((Math.random()*100) + 50).toFixed();
var color = '#'+ Math.round(0xffffff * Math.random()).toString(16);
$newdiv = $('<div/>').css({
'width':divsize+'px',
'height':divsize+'px',
'background-color': color
});
var posx = (Math.random() * ($(document).width() - divsize)).toFixed();
var posy = (Math.random() * ($(document).height() - divsize)).toFixed();
$newdiv.css({
'position':'absolute',
'left':posx+'px',
'top':posy+'px',
'display':'none'
}).appendTo( 'body' ).fadeIn(100).delay(300).fadeOut(200, function(){
$(this).remove();
makeDiv();
});
})();
So if there was an array $data displaying names from a database, how would this be accomplished showing for examples James, John, Mary, and Peter. So for every entry a user enters in a form the name shows flashing in and out of the squares at different times all at once.
Building on my previous inquiries, I have an image, cat.jpg, that is being cloned, resized (halved, to be precise), then sent to a random position on the page via jQuery's .css() and .animate(). Now, when a cat is clicked, I'd like it to generate a new image/element in its place temporarily before removing it. So the order of events would be:
Click cat.
Cat explodes into 3 smaller kittens.
Clicked cat element is removed and a new image temporarily takes its place.
Cat replacement image is removed after set amount of time (say, one second).
Here's where I'm at thus far. Everything is up to snuff save for keeping the new kittens within the document boundaries (which I'll solve on my own) and the replacement image. Here's the Fiddle, and here's the code:
var explode;
$('img.cat').click(explode=function() {
var contW = $(document).width();
var contH = $(document).height();
for (var i = 1; i <= 3; i++){
var source = $(this).position();
var posNeg = Math.random() < 0.5 ? -1 : 1;
var newTop = Math.floor(Math.random() * (contH / 2 + (posNeg * $(this).height()))) * posNeg;
var posNeg = Math.random() < 0.5 ? -1 : 1;
var newLeft = Math.floor(Math.random() * (contW / 2 + (posNeg * $(this).width()))) * posNeg;
var $kitty = $(this).clone().css({
width: $(this).width() / 2,
height: $(this).height() / 2
});
$('#container').append($kitty);
$kitty.css({ top: source.top, left: source.left })
.animate({ top: newTop+'px', left: newLeft+'px' }, 300)
.click(explode);
}
$(this).remove();
});
I know I have to get the current position of the $kitty (or rather img.cat) being clicked on and set the new object to that via CSS, but my implementation is flawed.
var $lion = $('#replacement').clone().css({
top: newTop,
left: newLeft,
});
$('#container').append($lion);
<img id="replacement" src="http://images1.wikia.nocookie.net/__cb20130326142633/warriors/images/4/47/Lion.png" />
How can I get the lion to show up for only a second when any img.cat is clicked, and show up in that cat's exact position?
instead of $(this).remove() try to replace the cat with lion
var $lion = $('<img id="replacement" src="http://images1.wikia.nocookie.net/__cb20130326142633/warriors/images/4/47/Lion.png" />')
$(this).replaceWith($lion);
setTimeout(function () {
$lion.remove()
}, 1000)
Demo: Fiddle, Make sure the image is displayed for 1 sec
I want to display random numbers inside a div at random positions without overlapping.
I am able to display random number at random position but its going outside the box and overlapping each other.
Here is my code:
JS Fiddle
var width = $('.container').innerWidth();
var height = $('.container').innerHeight();
(function generate() { // vary size for fun
for (i = 0; i < 15; i++) {
var divsize = 12;
var color = '#' + Math.round(0xffffff * Math.random()).toString(16);
$newdiv = $('<div/>').css({
'width': divsize + 'px',
'height': divsize + 'px'
});
// make position sensitive to size and document's width
var posx = (Math.random() * (width - divsize)).toFixed();
var posy = (Math.random() * (height - divsize)).toFixed();
$newdiv.css({
'position': 'absolute',
'left': posx + 'px',
'top': posy + 'px',
'float': 'left'
}).appendTo('.container').html(Math.floor(Math.random() * 9));
}
})();
How can I do this?
You've got most of it figured out. You just need to think of the .container div as a grid to avoid any overlap or outlying items.
Just check out this fiddle.
Here's what the code looks like:
var tilesize = 18, tilecount = 15;
var gRows = Math.floor($(".container").innerWidth()/tilesize);
var gCols = Math.floor($('.container').innerHeight()/tilesize);
var vals = _.shuffle(_.range(tilecount));
var xpos = _.shuffle(_.range(gRows));
var ypos = _.shuffle(_.range(gCols));
_.each(vals, function(d,i){
var $newdiv = $('<div/>').addClass("tile");
$newdiv.css({
'position':'absolute',
'left':(xpos[i] * tilesize)+'px',
'top':(ypos[i] * tilesize)+'px'
}).appendTo( '.container' ).html(d);
});
PS:I have used underscore in my fiddle to make things easier for me and because I personally hate writing for loops.
If the number of divs you need to create is small enough (i.e. you're not risking that they won't fit) then a simple algorithm is:
pick a random position (x0, y0)-(x1, y1)
check if any previously selected rect overlaps
if none overlaps then add the rect, otherwise loop back and choose another random position
in code
var selected = [];
for (var i=0; i<num_divs; i++) {
while (true) {
var x0 = Math.floor(Math.random() * (width - sz));
var y0 = Math.floor(Math.random() * (height - sz));
var x1 = x0 + sz;
var y1 = y0 + sz;
var i = 0;
while (i < selected.length &&
(x0 >= selected[i].x1 ||
y0 >= selected[i].y1 ||
x1 <= selected[i].x0 ||
y1 <= selected[i].y0)) {
i++;
}
if (i == selected.length) {
// Spot is safe, add it to the selection
selected.push({x0:x0, y0:y0, x1:x1, y1:y1});
break;
}
// The choice collided with a previously added div
// just remain in the loop so a new attempt is done
}
}
In case the elements are many and it's possible to place n-1 of them so that there's no position where to put n-th element then things are a lot more complex.
For the solution of the 1-dimensional version of this problem see this answer.
You can add to array position of each number. And then when ou generate new position for digit you should check if posx posy in array, if false place number there, if true generate new posx and posy
I'm creating a simple game and i am stuck currently at something i have a div called 'box' and an image inside it called 'Parachute' when the game start the parachute should move randomly inside the border of the div
my code :
<div id="box">
</div>
<script type="text/javascript">
var ToAppend = "<img src='Parachute.gif' width='25px' height='25px' class='Parachute' /> ";
setInterval(function () {
for (var i = 1; i <= 2; i++) {
$("#box").append(ToAppend);
MoveParticles();
}
}, 3000);
function MoveParticles() {
$(".Parachute").each(function () {
var x = Math.floor(Math.random() * 400);
var y = Math.floor(Math.random() * 400);
$(this).animate({ "left": x + "px" }, "slow");
$(this).animate({ "top": y + "px" }, "slow");
});
}
<script>
You seem to be animating #box, not .Parachute.
Here's a demo to get you in the right track.
//let's build the chutes
for (var i = 0; i < 50; ++i) {
$('<div/>', {
class: 'chute'
}).appendTo('#box');
}
//cache a few static values
var box = $('#box');
var width = box.width();
var height = box.height();
var chute = $('.chute');
//our main animation "loop"
chute.each(function foo() {
//generate random values
var top = (Math.random() * height) | 0;
var left = (Math.random() * width) | 0;
var time = Math.random() * (800 - 400) + 400 | 0;
//animate
//we introduce a random value so that they aren't moving together
//after the animation, we call foo for the current element
//to animate the current element again
$(this).animate({
left: left,
top: top
}, time, foo);
});