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/
Related
How can I make my progress bar show in increments based on my question number. Currently it completes to 100% after clicking the next question button. But, I am trying to let it increase in the increments of the question numbers and go backwards if the previous question button is clicked. The codepen with all the code is here. Thank you.
var i = 0;
function moveForward() {
if (i == 0) {
i = 1;
var elem = document.getElementById("myBar");
var width = 10;
var id = setInterval(frame, 10);
function frame() {
if (width >= 100) {
clearInterval(id);
i = 0;
} else {
width++;
elem.style.width = width + "%";
elem.innerHTML = width + "%";
}
}
}
}
function moveBackward() {
if (i == 0) {
i = 1;
var elem = document.getElementById("myBar");
var width = 10;
var id = setInterval(frame, 10);
function frame() {
if (width >= 100) {
clearInterval(id);
i = 0;
} else {
width++;
elem.style.width = width + "%";
elem.innerHTML = width + "%";
}
}
}
}
///// UPDATED FUNCTION
function moveForward(i) {
console.log('i: ' + i);
var elem = document.getElementById("myBar");
switch(i) {
case 0:
elem.style.width = "33%";
elem.innerHTML = "33%";
break;
case 1:
elem.style.width = "66%";
elem.innerHTML = "66%";
break;
case 2:
elem.style.width = "100%";
elem.innerHTMl = "100%";
}
}
The reason it is completing after one click is that setInterval runs the function repetitively every x milliseconds. That means that your frame function runs every 10 milliseconds until it hits the if statement that clears the interval. Since your stop check only stops at width >= 100 it continues to expand until it is set to 100%.
In order to properly track the existing and next widths you will need to have a persistent variable in a global scope and you'll need to pass a target width to frame so that it knows when to actually stop
There are two other issues with your code. The first is that the previous button also increases the width rather than decreasing it, and the other issue is that every time you click the next or previous buttons it first resets the width to 10 and then increases it to 100.
var move = function() {
Xpos = Math.round(Math.random() * 95);
food[num].css('left', Xpos + '%');
interval = setInterval(function() {
console.log(i);
var posTop = food[num].offset().top / $(window).height() * 100;
while(posTop < 80) {
if(posTop === 80) {
num++;
break;
}
posTop += 1;
food[num].css('top', posTop + '%');
break;
}
}, speed);
}
//Color the circle
circleColor();
move();
}
OK so this is my code. It creates a circle(a <div> element) on top of the screen and gives it a random x coordinate. Than it puts it in food[] array. The entire code starts by clicking the button, but every time I press the button again the circle that was last moving stops, function creates a new one and the new one moves. Is there a way I can make all elements in the array move without depending on each other?
http://jsfiddle.net/yqwjqx31/
I understand why this happens but I have no idea how to fix it.
First you're using a global variable num in setInterval function handler, so its value get modified while using it in new cercle create, secondly you're clearing interval of the last cercle you created before creating a new cercle. It means you're sharing the same interval between all cercles. Use instead an array of intervals just like var food =[] and use a temporary variable to prevent the index value modification inside your setInterval handler. Here's a working fiddle
//Interval
var interval =[];
var tempNum = num;
interval[num] = setInterval(function() {
var posTop = food[tempNum].offset().top / $(window).height() * 100;
while(posTop < 80) {
if(posTop === 80) {
break;
}
posTop += 1;
food[tempNum].css('top', posTop + '%');
break;
}
}, speed);
Increment your num variable
//Color the circle
circleColor();
move();
num++;
Your move function is only responsible for moving the last generated div via createCircle. If you want to move them all till collision, you need to loop through them all and move them accordingly. Or, you can animate them via CSS.
Here is the working version :
http://jsfiddle.net/yqwjqx31/3/
Notice how the setInterval callback loops through all the div and pushes them down until their height is 80.
var move = function () {
interval = setInterval(function () {
for (var i = 0; i < food.length; ++i) {
var posTop = food[i].offset().top / $(window).height() * 100;
if (posTop < 80) posTop += 1;
food[i].css('top', posTop + '%');
}
}, speed);
}
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.
(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 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.