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.
Related
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.
I am trying to make this function works only when the screen size is above 1024px.
//Parallax background image
var velocity = 0.5;
function update(){
var pos = $(window).scrollTop();
$('.parallax').each(function() {
var $element = $(this);
var height = $element.height();
$(this).css('background-position', '40%' + Math.round((height - pos) * velocity) + 'px');
});
};$(window).bind('scroll', update); update();
Here is what I have tried to do:
//Parallax background image
var velocity = 0.5;
$(window).on("ready resize", function() {
if ($(window).width() < 770) {
function update(){
var pos = $(window).scrollTop();
$('.parallax').each(function() {
var $element = $(this);
var height = $element.height();
$(this).css('background-position', '40%' + Math.round((height - pos) * velocity) + 'px');
});
};});$(window).bind('scroll', update); update();
I really don't know what I am doing wrong...
You haven't stated what the problem you're coming across is. If it's "my code doesn't work", then perhaps you should check your syntax first. Your braces are messed up.
//Initialize velocity and empty update function
var velocity = 0.5;
var update = function () {};
//When window is ready (content loaded) OR resized, execute the following function
$(window).on("ready resize", function () {
if ($(window).width() >= 1024) { //Check if window width is 1024px wide or larger
update = function () { //Set update to run this function when executed.
var pos = $(window).scrollTop(); //Get scrollbar position https://api.jquery.com/scrollTop/
//For each element with 'parallax' class, execute the following function
$('.parallax').each(function () {
var $element = $(this); //Get the current parallax-classed element
var height = $element.height(); //Save the current height of this element
//Set the CSS of this parallax-classed element set the background position
$(this).css('background-position', '40% + ' + Math.round((height - pos) * velocity) + 'px');
});
};
} else { //Execute if screen width is < 1024px
update = function () {}; //Set update to do nothing
}
});
//When window is scrolled through, run the update function
$(window).bind('scroll', update);
//update();
Last line is unnecessary, as resize will handle function value, and scroll will handle the execution.
You were missing a + or - within the background-position setting.
So for example, if the result of your Math.round() was "30", then Javascript would interpret that line as $(this).css('background-position', '40%30px'); which obviously would cause issues. I'm sure you wanted it to say something like $(this).css('background-position', '40% + 30px');.
(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.
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/
Is it possible to know whether or not an HTML element like image is viewable in current viewport or it will be visible on scroll?
If it is viewable completely or partially then how can I get the amount of portions is visible?
I am trying to explain it from the following image:
The two images at the bottom is partially visible within the viewport and these will be completely visible if one scroll down a little bit.
Now I want to get the the aforesaid information.
In the actual scenario I am trying to get the popup-zoom effect on hover of image in my album like google image search. Everything is fine, except if the images are placed in the described manner then the zoomed div also displaying in half.
Normal condition where image is completely in viewport:
And partially in viewport:
I really appreciate your help.
The code:
var albumDetailOnReady = function() {
$('.image').each(function(){
var photo = $(this);
var wrap = $(findParentByClassName(document.getElementById(photo.attr('id')), 'wrap'));
var row = $(findParentByClassName(document.getElementById(wrap.attr('id')), 'albumDetailRow'));
var visibleZone = $(wrap).find('.alDtlColumn');
var pictureBlock = $(visibleZone).find('.pictuteBlock');
var hiddenZone = $(wrap).find('.hiddenZone');
$(photo).load(function(){
if(177 > $(photo).width()){
var imgleft = ($(pictureBlock).width() - $(photo).width())/2 + 'px';
$(photo).css({'left': imgleft});
}
});
$(photo).hover(function(){
var y;
if($(photo).height() > $(photo).width()) {
y = ($(visibleZone).offset().top - 50) + 'px';
} else {
y = ($(visibleZone).offset().top + 50) + 'px';
}
var x;
if($(row).find('.wrap:first').attr('id') === $(wrap).attr('id')) {
x = ($(visibleZone).offset().left - 10) + 'px';
} else if($(row).find('.wrap:last').attr('id') === $(wrap).attr('id')) {
x = ($(visibleZone).offset().left - 50) + 'px';
} else {
x = ($(visibleZone).offset().left - 20) + 'px';
}
$(hiddenZone).css({
'top': y,
'left': x,
'position': 'absolute',
'z-index': '10'
});
$(hiddenZone).fadeIn('fast');
}, function(){
});
$(hiddenZone).hover(function(){},function(){
$(hiddenZone).hide().stop(true, true);
});
});
}
var findParentByClassName = function(element, clazz) {
while (element.parentNode) {
element = element.parentNode;
if (hasClass(element, clazz)) {
return element;
}
}
return null;
}
function hasClass(element, cls) {
var regex = new RegExp('\\b' + cls + '\\b');
return regex.test(element.className);
}
I am unable to show any HTML as I haven't have any, I am working in ADF framework.
But for an explanation:
I have two zone for each image: visible and hidden. Both of them are in a wrap. Now on hover an image I am showing the hidden div. The top and left of the hidden div is measured by the top and left of the visible div with some condition.
jQuery.Viewport
Very helpfull and lightweight jQuery plugin that makes an element as a handy viewport for displaying elements with absolute position. The plugin is hosted on GitHub. You can see it in action right there:
https://github.com/borbit/jquery.viewport