Call gallery images randomly from databse, overlapping at intervals - javascript

(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(700).delay(3500).fadeOut(300, function(){
$(this).remove();
makeDiv();
});
})();
FIDDLE: http://jsfiddle.net/redler/QcUPk/8/
Design mockup: http://i.imgur.com/D4mhXPZ.jpg
I've tried fiddling with this code I found but I just end up butchering it and breaking it. In one instance I had the code doubling the objects every iteration and it almost crashed my PC, heh.
I need a few things happening here.
I need there to be at least 8 of these objects simultaneously performing this appearing and disappearing act, overlapping each other slightly offset (centerOffset?). Each appearing square should be in the front of previous images that still linger.
The objects are not colored squares, but should be images called randomly from a database (an inventory of products).
When you mouseover any of the pictures, the process should pause and that object will come to the front while you keep your mouse on it, displaying some text about the piece. If you click it it will navigate you away to the items page.
Note: The random sizing element is nice but I have some taller images, some wider images, etc. Not sure how to handle that.

There is quite a bit of animation/timing work to keep 8 objects simultaneously appearing/disappearing. The next hard bit is capturing the mouseover the objects and when to "come to the front", you might need the jQuery hover intent plugin. Anyways, here's some working code that will simultaneously animate 8 random objects onto the screen, and the appearing/disappearing act will stop when you mouseover an object. When your mouse leaves the object, the animation will continue: http://jsfiddle.net/amyamy86/Q6XKv/
The main gist is this (see fiddle for full code):
// Adds the box and animates in/out
var addBox = function () {
var makeBox = function () {
var divsize = ((Math.random() * 100) + 50).toFixed();
var color = '#' + Math.round(0xffffff * Math.random()).toString(16);
var newBox = $('<div class="box" id="box' + boxIds + '"/>').css({
'width': divsize + 'px',
'height': divsize + 'px',
'background-color': color
});
return newBox;
};
var newBox = makeBox();
var boxSize = newBox.width();
var posx = (Math.random() * ($(document).width() - boxSize)).toFixed();
var posy = (Math.random() * ($(document).height() - boxSize)).toFixed();
newBox.css({
'position': 'absolute',
'left': posx + 'px',
'top': posy + 'px',
'display': 'none'
}).appendTo('body').fadeIn(ANIMATE_SPEED / 2, function () {
if (timer !== null) {
$(this)
.delay(ANIMATE_SPEED * MAX_BOXES)
.fadeTo(1, 1, function () {
if (timer !== null) {
var id = $(this).attr('id');
removeBox(id);
}
});
}
});
boxIdList.push(boxIds++);
lastBox = newBox;
numBoxes++;
return newBox;
};
// Add the boxes in at interval animateSpeed, if there's too many then don't add
var animateBox = function () {
if (numBoxes < MAX_BOXES) {
addBox();
} else {
removeBox(boxIdList[0]);
}
timer = setTimeout(animateBox, ANIMATE_SPEED); // re-set timer for the next interval
};
// starts everything off
var start = function () {
timer = setTimeout(animateBox, ANIMATE_SPEED);
};
This should be enough for you to work off of to add the level of detail you want for the interaction and effects.

Related

how to animate image & change the direction from right to left

Please find the code, which iam facing issue with changing the direction of arrow, the arrow should change the facing from right to left once it reach the screen width. THE REQUIRED FUNCTIONALITY IS THE ARROW SHOULD NOT GO IN REVERSE it has to change its direction.
tried lot some one give solution.
http://jsfiddle.net/7xyuqe1k/5/
function AnimateFish() {
var Fish3 = $("[id^=fish]").not(".HoverFish"),
theContainer = $("#container"),
maxLeft = theContainer.width() - Fish3.width() - 50,
maxTop = theContainer.height() - Fish3.height(),
leftPos = Math.floor(Math.random() * maxLeft),
topPos = Math.floor(Math.random() * maxTop) + 100,
imgRight = "Assets/fish-glow3-right.gif",
imgLeft = "Assets/fish-glow3.gif";
/*Get position of the fish*/
//console.log(Fish3.position().left +" +"+leftPos);
//alert(Fish3.position().left);
if ($("[id^=fish]").position().left >= leftPos) {
$(this).css("background-image", 'url("' + imgRight + '")');
} else {
$(this).css("background-image", 'url("' + imgLeft + '")');
}
Fish3.animate({
"left": leftPos,
"top": topPos
}, 1800, AnimateFish);
}
There was a problem on fish's destination points(positions left & top) picking. First fish works properly since it's picking the destination point respective to itself, but rest of the fishes also were taking the destination points respective to 1st fish not themselves.
The working sample is available here http://jsfiddle.net/ravinila/7xyuqe1k/26/
$(document).ready(function(e) {
var newfishid = 0;
$('.post-button').click( function(e) {
var fish = $("<div/>", {"class":"large-fish fish", "id" : "fish"+(newfishid++)});
$('#container').append(fish);
fish.on("anim", function(e){
var _this = $(this),
theContainer = $("#container"),
maxLeft = theContainer.width() - _this.width() - 50,
maxTop = theContainer.height() - _this.height(),
leftPos = Math.floor(Math.random() * maxLeft),
topPos = Math.floor(Math.random() * maxTop) + 100,
imgLeft = "http://free-icon-download.com/modules/PDdownloads/images/screenshots/free-icon-download_left-arrow-blue.png",
imgRight = "http://www.newclassicdesign.com/r_arrow.png";
if (_this.position().left < leftPos) {
_this.css("background-image", 'url("' + imgRight + '")');
} else {
_this.css("background-image", 'url("' + imgLeft + '")');
}
_this.animate({
"left": leftPos,
"top": topPos
}, 2500, function(){
$(this).trigger("anim");
});
});
fish.trigger("anim");
fish.hover(function(e) {
$(this).stop();
}, function(e) {
$(this).trigger("anim");
});
});
});
I have taken a look at it and it looks like its a silly mistake. Your fiddle showed something was working since it changed something when the direction changed, so the basics are okay. You just forgot that there was an image tag inside you div that you're meant to be manipulating.
function AnimateFish() {
var Fish3 = $("#fish1").not(".HoverFish"),
theContainer = $("#container"),
maxLeft = theContainer.width() - Fish3.width() - 50,
maxTop = theContainer.height() - Fish3.height(),
leftPos = Math.floor(Math.random() * maxLeft),
topPos = Math.floor(Math.random() * maxTop) + 100;
imgRight = "http://www.newclassicdesign.com/r_arrow.png",
imgLeft = "http://free-icon-download.com/modules/PDdownloads/images/screenshots/free-icon-download_left-arrow-blue.png";
// below here you used $(Fish3), but Fish3 is already a JS object - you don't need to rewrap it.
// The biggest problem however, is that below that you used '$(this)', which won't work as there
// is no context defined (you're in an if, not a jQuery function).
// Replacing this with the same Fish3 does the job,
// as it already was a jQuery object anyhow.
// I have also changed your background from an image to red and green for testing purposes.
// As you can see, thats working. However, your image isn't changing..
// This is because you have an image inside you wrapper which you aren't changing.
if (Fish3.position().left >= leftPos) {
Fish3.css("background", 'green');
// So lets change the image...
Fish3.find("img").attr("src", imgLeft);
} else {
Fish3.css("background", 'red');
// So lets change the image...
Fish3.find("img").attr("src", imgRight);
}
Fish3.animate({
"left": leftPos,
"top": topPos
}, 1800, AnimateFish);
}
Check my comments inside the code to see what happened, but copying this into your fiddle and replacing the animation function did the trick.

Text Fadein/Fadeout at Random Positions

I'm attempting to put together a webpage that has text that pops up at random locations on the page, fade out, then appear again at a random location again. I found something that suits my purposes for example. I want something like this, but with text that I can manipulate and make a list out of with text-shadow effects if needed.
(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();
});
})();
Fiddle
This is a second example of something similar, only it doesn't have random position.
$('li').each(function(){
var randomTop = $('div').height()*Math.random(); //random top position
var randomLeft = $('div').width()*Math.random(); //random left position
$(this).css({ //apply the position each li
top : randomTop,
left : randomLeft
});
});
Fiddle
I'm hoping to sort of splice the two together in order to get what I'm ideally looking for. Please forget the formatting as its my first time here and I'm trying to conform to the standards.
I'm not sure if I understand exactly what you're looking for but I "spliced them together."
Fiddle
(function fadeInDiv(){
var divs = $('.fadeIn');
var divsize = ((Math.random()*100) + 50).toFixed();
var posx = (Math.random() * ($(document).width() - divsize)).toFixed();
var posy = (Math.random() * ($(document).height() - divsize)).toFixed();
var maxSize = 30;
var minSize = 8;
var size = (Math.random()*maxSize+minSize)
var elem = divs.eq(Math.floor(Math.random()*divs.length));
if (!elem.is(':visible')){
elem.fadeIn(Math.floor(Math.random()*1000),fadeInDiv);
elem.css({
'position':'absolute',
'left':posx+'px',
'top':posy+'px',
'font-size': size+'px'
});
} else {
elem.fadeOut(Math.floor(Math.random()*1000),fadeInDiv);
}
})();
EDIT: Updated Fiddle URL

Tweaking animation to make divs appear more frequently

I am creating a whack-a-mole style game where the user had to click on the correct number in accordance to a sum above that is randomly generated each time a question is answered. The problem that I am having is that the user sometimes has to wait a long time before the answer they need actually appears, and sometimes it takes around ten second for anything to appear. I need the animation to make the divs appear more frequently but I don't know how to make this happen.
Here is the animation attributes for the number divs
function randomFromTo(from, to) {
return Math.floor(Math.random() * (to - from + 1) + from);
}
function scramble() {
var children = $('#container').children();
var randomId = randomFromTo(1, children.length);
moveRandom("char" + randomId);
}
var currentMoving = [];
function moveRandom(id) {
// If this one's already animating, skip it
if ($.inArray(id, currentMoving) !== -1) {
return;
}
// Mark this one as animating
currentMoving.push(id);
var cPos = $('#container').offset();
var cHeight = $('#container').height();
var cWidth = $('#container').width();
var bWidth = $('#' + id).width();
var bHeight = $('#' + id).css('top', '395px').fadeIn(100).animate({
'top': '-55px'
}, AnimationSpeed).fadeOut(100);
maxWidth = cPos.left + cWidth - bWidth;
minWidth = cPos.left;
newWidth = randomFromTo(minWidth, maxWidth);
$('#' + id).css({
left: newWidth
}).fadeIn(1000, function () {
setTimeout(function () {
$('#' + id).fadeOut(1000);
// Mark this as no longer animating
var ix = $.inArray(id, currentMoving);
if (ix !== -1) {
currentMoving.splice(ix, 1);
}
window.cont++;
}, 1000);
});
}
Can someone show me how to make it so that there is always a set number of answers on the screen at once, rather than having long waiting periods with now numbers?
Fiddle:http://jsfiddle.net/xgDZ4/3/

Moving Div by everyclick without JQuery

I used this jquery to move a div by every click.
$(document).ready(function(){
$('#hero').click(function(){
$(this).animate({
left: '+=50px'
},300);
})
})
I'd like to avoid jquery whenever it is possible to get deeper into pure JS.
Is there anyway to achieve the same effect without using jquery?
I know that this will be more complex, but just trying to learn.
you can use the same technique in javascript:
// get the object refrence
var hero_obj = document.getElementById('hero');
// attach the onclick event
hero_obj.onclick = function(){
this.style.left = ( parseInt(this.style.left, 10) + 50 ) + 'px'
};
However, the effect won't be as smooth as jquery
I've stumbled upon this gem on vanilla-js.com a few weeks ago:
var s = document.getElementById('thing').style;
s.opacity = 1;
(function(){(s.opacity-=.1)<0?s.display="none":setTimeout(arguments.callee,40)})();
I really like the simplicity and the size of the code. Elegant and efficient!
I've created a function that affects the left property of an element of your choice based on the code above:
/* element: DOM element such as document.getElementById('hero')
distance: distance in pixels to move to the left such as 50 or 100 */
function moveBy(element, distance){
var target = isNaN(parseInt(s.left)) ? distance : parseInt(s.left) + distance;
(function(){
s.left = isNaN(parseInt(s.left)) ? '1px' : (parseInt(s.left) + 1).toString() + 'px';
if(parseInt(s.left) <= distance) setTimeout(arguments.callee, 40);
})();
}
You can play around and see what fits to your liking in terms of speed and smoothness. Try it here on a jsfiddle.
/* So you go: */
moveBy(document.getElementById('hero'), 50);
/* Or you can bind it to an event */
document.getElementById('hero').addEventListener('click', function(event){
moveBy(this, 50);
});
What a solution like this would need if you're willing to make it better is to replace the left property by translate. As Paul Irish states on his blog, translate provides way better performance than moving elements around with TRBL (top-left-bottom-right). Some sort of easing functions could be added as well to smooth things out.
Here's a code with animation. This snippet is only for modern browsers, but it is easy to modify to work with older browsers (IEs) too. (Actually only attachment of the event needs to be fixed.)
window.onload = function () {
var timer, k, intervals, kX, kY,
counter = 0,
hero = document.getElementById('hero'),
posX = hero.offsetLeft,
posY = hero.offsetTop,
anim = function (elem, params) {
posX += kX;
posY += kY;
elem.style.left = posX + 'px';
elem.style.top = posY + 'px';
if (counter > intervals) {
clearInterval(timer);
counter = 0;
} else {
counter++;
}
return;
},
move = function (elem, params) {
if (timer) {
clearInterval(timer);
counter = 0;
}
k = Math.atan2(params.left, params.top);
kX = Math.sin(k);
kY = Math.cos(k);
intervals = Math.floor(Math.sqrt(Math.pow(params.left, 2) + Math.pow(params.top, 2)));
timer = setInterval(function () {
anim(elem, params);
return;
}, params.speed);
return;
};
document.getElementById('hero').addEventListener('click', function (e) {
move(e.currentTarget, {left: 50, top: 0, speed: 0});
return;
}, false);
return;
}
As you can see, with this code you can also move elements vertical and adjust speed. To switch direction, just add - to corresponding property. The code is using pixels only as units, but that's easy to modify if needed.
It's also easy to convert this functional code to an object. Also jQuery-like duration can be added by passing property params.duration instead of params.speed and doing some advanced calculations with that and kX, kY.
Working demo at jsFiddle
I needed to create an animation solution with easing a while back without using a framework.
The tricky part for me was coping with interrupting/restarting animations part way through when they are tied to user interactions. I found that you can run into trouble pretty quickly if your animations double-fire.
Here is on github: https://github.com/robCrawford/js-anim
There are a few supporting functions but here's the main animation:
function animate(el, prop, to, pxPerSecond, easing, callback){
/**
* Animate style property
* i.e. animate(div1, "width", 1100, 1000, "out", function(){console.log('div1 anim end')});
*
* #param el DOM element
* #param prop Property to animate
* #param to Destination property value
* #param pxPerSecond Speed of animation in pixels per second
* #param easing (optional) Easing type: "in" or "out"
* #param callback (optional) Function to call when animation is complete
*/
var frameDur = 10,
initPropVal = parseInt(getCurrCss(el, prop)),
distance = Math.abs(to-initPropVal),
easeVal = (easing==="in")?1.5:(easing==="out")?0.5:1, // >1 ease-in, <1 ease-out
elAnimData = getData(el, 'animData');
//Quit if already at 'to' val (still fire callback)
if(initPropVal===to){
if(callback)callback.call();
return;
}
//Init animData for el if first anim
if(!elAnimData){
elAnimData = {};
setData(el, {'animData':elAnimData});
}
//Get data for prop being animated or create entry
var animDataOb = elAnimData[prop];
if(!animDataOb)animDataOb = elAnimData[prop] = {};
//Don't re-initialise an existing animation i.e. same prop/to
if(animDataOb.to === to)return;
animDataOb.to = to; //Store 'to' val
//Clear any exisiting interval
if(animDataOb.intId){
clearInterval(animDataOb.intId);
animDataOb.intId = null;
}
//Create new anim
animDataOb.intId = (function(animDataOb){
var totalSteps = Math.round((distance/pxPerSecond)/(frameDur*.001)),
thisStep = 0;
return setInterval(function(){
var newVal = easeInOut(initPropVal, to, totalSteps, thisStep++, easeVal);
if(!isNaN(newVal))el.style[prop] = newVal + "px"; //Allow 0
if(thisStep > totalSteps)endAnim(animDataOb, callback);
}, frameDur);
})(animDataOb);
}
function endAnim(animDataOb, callback){
//End anim
clearInterval(animDataOb.intId);
animDataOb.intId = animDataOb.to = null;
if(callback)callback.call();
}

jQuery - Fixing the animation

I am creating a new "whack-a-mole" style game where the children have to hit the correct numbers in accordance to the question.
I have the numbers animating from a set top position to another with a random width so that they look like they are floating up like bubbles.
The only problem I am having with it is that sometimes the numbers glitch and the width on them changes suddenly making it appear to jump from one side of the container to the other.
The only explanation I can think of is the width must be resetting somewhere which I have tried to look for.
Either I am blind or it is something else, can someone help me to find the source of the problem.
Here is the code that maps the numbers...
function randomFromTo(from, to) {
return Math.floor(Math.random() * (to - from + 1) + from);
}
function scramble() {
var children = $('#container').children();
var randomId = randomFromTo(1, children.length);
moveRandom("char" + randomId);
}
function moveRandom(id) {
var cPos = $('#container').offset();
var cHeight = $('#container').height();
var cWidth = $('#container').width();
var bWidth = $('#' + id).width();
var bHeight = $('#' + id).css(
'top', '400px'
).fadeIn(1000).animate({
' top': '-100px'
}, 10000).fadeOut(1000);
maxWidth = cPos.left + cWidth - bWidth;
minWidth = cPos.left;
newWidth = randomFromTo(minWidth, maxWidth);
$('#' + id).css({
left: newWidth
}).fadeIn(1000, function () {
setTimeout(function () {
$('#' + id).fadeOut(1000);
window.cont++;
}, 1000);
});
Here is also a working fiddle so you can see the issue I am talking about: http://jsfiddle.net/pUwKb/26/
The problem is that you are re-entering your moveRandom function for an ID that is already animated. The new width calculation causes the piece to seem to jump when it is reassigned during the already animated movement. One way to fix this is to reject new piece movements for pieces you are already animating. I modified your jsFiddle and fixed it with this code:
// Keep track of the pieces actually moving
var currentMoving = [];
function moveRandom(id) {
// If this one's already animating, skip it
if ($.inArray(id, currentMoving) !== -1) {
return;
}
// Mark this one as animating
currentMoving.push(id);
var cPos = $('#container').offset();
var cHeight = $('#container').height();
var cWidth = $('#container').width();
var bWidth = $('#' + id).width();
var bHeight = $('#' + id).css('top', '400px').fadeIn(1000).animate({
'top': '-100px'
}, 10000).fadeOut(1000);
maxWidth = cPos.left + cWidth - bWidth;
minWidth = cPos.left;
newWidth = randomFromTo(minWidth, maxWidth);
$('#' + id).css({
left: newWidth
}).fadeIn(1000, function () {
setTimeout(function () {
$('#' + id).fadeOut(1000);
// Mark this as no longer animating
var ix = $.inArray(id, currentMoving);
if (ix !== -1) {
currentMoving.splice(ix, 1);
}
window.cont++;
}, 1000);
});
}
Forked jsFiddle here.
Edit: The OP wanted to show more divs at once without speeding the animation up. To do this I added 20 more character divs (each a duplicate of the first 10 numbers), fixed the guarding code a bit, altered the CSS to specify the image of the character by class, and then put a limit of 20 animations at a given time. I also put a loop around the rejection of an already animated piece, to pick another. I made some other minor improvements. Updated JSFiddle here.

Categories