change color of items one by one - javascript

I wrote a script that creates a set of smaller circles arranged in a circle, which are added to the DOM one by one with a loop. After first loop is done (so I would expected this to be when i == 54) I would like to start another loop, starting from the first circle in a list and one by one changing the color of the circles from grey to red.
This is my code:
var i = 1;
var appendCircle = function loop() {
setTimeout(function() {
var $circle = "<div class='circle circle" + i + "' style='transform:rotate(" + 7.2 * i + "deg) translate(3em)'></div>";
var $container = $(".circles-wrapper .circles");
$container.append($circle);
i++;
if (i < 55) {
loop();
}
}, 20);
// this is the problem because this change color of all small circles at once.
if (i == 54) {
setTimeout(function() {
$(".circle").each(function() {
$(this).css({
"background": "blue"
});
})
}, 20);
}
};
setTimeout(appendCircle, 100);
.circles-wrapper {
position: absolute;
top: 39%;
left: 51%;
}
.circles {
position: relative;
transform: rotateY(48deg);
}
.circle {
width: .2em;
height: .2em;
margin: -.2em;
border-radius: 50%;
background: #ceced0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="circles-wrapper">
<div class="circles"></div>
</div>

You're giving each circle the class "circle"+index so all you have to do is loop through each index and change the background color of each element. What I did was used the same loop function and after i reached 55 I took the mod 55 of it and used that to select the circle. Code and snippet below.
I also noticed that some circles overlap. if you generate 50 circles then there won't be any overlap. I wrote the code below to reflect this.
var i = 1;
var appendCircle = function loop() {
setTimeout(function() {
if (i < 51) {
var $circle = "<div class='circle circle" + i + "' style='transform:rotate(" + 7.2 * i + "deg) translate(3em)'></div>";
var $container = $(".circles-wrapper .circles");
$container.append($circle);
}
else{
var circleIndex = (i % 51)+1;
$(".circle"+circleIndex).css("background-color", "blue");
}
if(i<109){
loop();
}
i++;
}, 20);
};
setTimeout(appendCircle, 100);
.circles-wrapper {
position: absolute;
top: 39%;
left: 51%;
}
.circles {
position: relative;
transform: rotateY(48deg);
}
.circle {
width: .2em;
height: .2em;
margin: -.2em;
border-radius: 50%;
background: #ceced0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="circles-wrapper">
<div class="circles"></div>
</div>

After your first pass you probably want to find the circle created and modify those. You are giving them a class of circle + i so you can easily find them. Check the code snip. I added a third pass just because.
var i = 1,
CIRCLE_COUNT = 52;
var appendCircle = function loop() {
setTimeout(function() {
i++;
// first pass
if (i < CIRCLE_COUNT * 1) {
var $circle = "<div class='circle circle" + i + "' style='transform:rotate(" + 7.2 * i + "deg) translate(3em)'></div>";
var $container = $(".circles-wrapper .circles");
$container.append($circle);
}
// second pass
else if (i < CIRCLE_COUNT * 2) {
$(".circle" + (i % CIRCLE_COUNT+1)).css('background', 'blue');
}
// third pass
else if (i < CIRCLE_COUNT * 3) {
$(".circle" + (i % CIRCLE_COUNT+1)).remove();
}
// keep looping?
if (i <= CIRCLE_COUNT * 3)
loop();
}, 20);
};
setTimeout(appendCircle, 100);
.circles-wrapper {
position: absolute;
top: 39%;
left: 51%;
}
.circles {
position: relative;
transform: rotateY(48deg);
}
.circle {
width: .2em;
height: .2em;
margin: -.2em;
border-radius: 50%;
background: #ceced0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="circles-wrapper">
<div class="circles"></div>
</div>

something like this? i put a timeout function in your .each() in order to make a delay between each iteration of the loop when you change the color of the circles to blue
var i = 1;
var appendCircle = function loop() {
setTimeout(function() {
var $circle = "<div class='circle circle" + i + "' style='transform:rotate(" + 7.2 * i + "deg) translate(3em)'></div>";
var $container = $(".circles-wrapper .circles");
$container.append($circle);
i++;
if (i < 55) {
loop();
}
}, 20);
// this is the problem because this change color of all small circles at once.
if (i == 54) {
var time = 50;
$(".circle").each(function() {
var $this = $(this)
setTimeout(function(){
$this.css({
"background": "blue"
});
}, time)
time += 50;
});
}
};
setTimeout(appendCircle, 100);
.circles-wrapper {
position: absolute;
top: 39%;
left: 51%;
}
.circles {
position: relative;
transform: rotateY(48deg);
}
.circle {
width: .2em;
height: .2em;
margin: -.2em;
border-radius: 50%;
background: #ceced0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="circles-wrapper">
<div class="circles"></div>
</div>

You need to change the CSS of just one element, then start a timeout to change the next one.
var i = 1;
var appendCircle = function loop() {
setTimeout(function() {
var $circle = "<div class='circle circle" + i + "' style='transform:rotate(" + 7.2 * i + "deg) translate(3em)'></div>";
var $container = $(".circles-wrapper .circles");
$container.append($circle);
i++;
if (i < 55) {
loop();
}
}, 20);
var j = 0;
function changeColor() {
$(".circle").eq(j).css("background", "blue");
j++;
if (j >= $(".circle").length) {
clearInterval(changeInterval);
}
}
if (i == 53) {
setInterval(changeColor, 20);
}
}
setTimeout(appendCircle, 100);
.circles-wrapper {
position: absolute;
top: 39%;
left: 51%;
}
.circles {
position: relative;
transform: rotateY(48deg);
}
.circle {
width: .2em;
height: .2em;
margin: -.2em;
border-radius: 50%;
background: #ceced0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="circles-wrapper">
<div class="circles"></div>
</div>

jQuery has features that make animations like this reasonably trivial, though you need to understand several methods.
jQuery's .delay(), .promise(), .then() and javascript's Array.prototype.reduce() can be exploited as follows :
var appendCircles = function($container) {
//create and append hidden circles
for(var i=0; i<50; i++) {
$("<div class='circle'></div>").css('transform', 'rotate(' + 7.2 * i + 'deg) translate(3em)').hide().appendTo($container);
}
//find the freshly appended hidden circles
var $circles = $container.find(".circle");
//initial delay
$circles.eq(0).delay(100).promise()
.then(function() {
//show the circles, one by one
return $circles.get().reduce(function(promise, el) {
return promise.then(function() {
return $(el).show().delay(20).promise();
});
}, $.when());//$when() is a resolved promise that gets the built promise chain started
})
.then(function() {
//make circles blue, one by one
return $circles.get().reduce(function(promise, el) {
return promise.then(function() {
return $(el).css('backgroundColor', 'blue').delay(20).promise();
});
}, $.when());//$when() is a resolved promise that gets the built promise chain started
});
};
appendCircles($(".circles"));
codepen
.reduce() probably needs some explanation. $circles.get() returns an array and .reduce(...) is used to build a promise chain equivalent to initialPromise.then(...).then(...).then(...). This trick is performed twice, in sequence, to give the initial "show" effect followed by the color-change effect.
This suite of methods is worth learning if you want to make custom animation sequences with jQuery.

Related

Collision detection using pure jQuery is not giving desired output

I am trying to develop a very simple game where the ship (red box) will move left-right when user clicks on playground.
There are some moving walls (black boxes) as obstacles that the ship should avoid colliding with.
If any collision happens, the walls will stop moving and a text will be printed out in console.
I have succeeded to get this as close as I can. But its working sometime, not always. You can see it in the code below, try to collide with wall. Sometime it will stop them and print text, sometime it will just ignore the collision as if nothing happens.
I have no clue why this is happening.
Here is the code.
$('document').ready(function() {
var $totalHeight = $('.inner').height(); //of walls
var $maxHeight = Math.ceil(Math.ceil($totalHeight / 3) - (Math.ceil($totalHeight / 3) * 30) / 100); //30% of total wall height
$('.wall').each(function(i, obj) {
$(this).height($maxHeight);
$('.wall.four').css({
'height': $wallGap
});
})
var $wallGap = Math.ceil($totalHeight / 3) - $maxHeight;
var $wallOneTop = 0;
var $wallTwoTop = $maxHeight + $wallGap;
var $wallThreeTop = ($maxHeight * 2) + ($wallGap * 2);
var $wallFourTop = -$('.wall.four').height() - $wallGap;
$('.wall.one').css({
'top': $wallOneTop
});
$('.wall.two').css({
'top': $wallTwoTop
});
$('.wall.three').css({
'top': $wallThreeTop
});
$('.wall.four').css({
'top': $wallFourTop
});
function moveWall(wallObj) {
var $currentTop = wallObj.position().top;
var $limitTop = $('.inner').height();
if ($currentTop >= $limitTop) {
var $rand = Math.floor(Math.random() * ($maxHeight - $wallGap + 1) + $wallGap);
wallObj.height($rand);
var $top = -(wallObj.height());
} else {
var $top = (wallObj.position().top) + 5;
}
var $collide = checkCollision(wallObj);
wallObj.css({
'top': $top
});
return $collide;
}
var $wallTimer = setInterval(function() {
$('.wall').each(function(i, obj) {
var $status = moveWall($(this));
if ($status == true) {
clearInterval($wallTimer);
}
})
}, 40);
function checkCollision(wallObj) {
var $ship = $('.ship');
var $shipWidth = $ship.width();
var $shipHeight = $ship.height();
var $shipLeft = $ship.position().left;
var $shipRight = $shipLeft + $shipWidth;
var $shipTop = $ship.position().top;
var $shipBottom = $shipTop + $shipHeight;
var $wall = wallObj;
var $wallWidth = wallObj.width();
var $wallHeight = wallObj.height();
var $wallLeft = wallObj.position().left;
var $wallRight = $wallLeft + $wallWidth;
var $wallTop = wallObj.position().top;
var $wallBottom = $wallTop + $wallHeight;
if (
$shipLeft >= $wallRight ||
$shipRight <= $wallLeft ||
$shipTop >= $wallBottom ||
$shipBottom <= $wallTop
) {
return false;
} else {
console.log("dhumm!");
return true;
}
}
$('.outer .inner').click(function() {
var $ship;
$ship = $('.ship');
$shipLeft = $ship.position().left;
$shipRight = $shipLeft + $ship.width();
$inner = $('.inner');
$innerLeft = $inner.position().left;
$innerRight = $innerLeft + $inner.width();
if (($shipLeft < $inner.width() - $ship.width())) {
$ship.animate({
"left": $inner.width() - $ship.width()
}, 500, "linear");
} else if (($shipRight >= $inner.width())) {
$ship.animate({
"left": '0'
}, 500, "linear");
}
});
});
.outer {
background: #fff;
border: 20px solid #efefef;
width: 400px;
height: 600px;
display: inline-block;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
overflow: hidden;
}
.outer .inner {
background: #fff;
height: 100%;
width: 100%;
margin: auto;
position: relative;
overflow: hidden;
}
.outer .inner .wall {
width: 5px;
position: absolute;
left: 50%;
transform: translateX(-50%);
background: #000;
}
.outer .inner .ship {
width: 15px;
height: 15px;
background: red;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="outer">
<div class="inner">
<div class="wall one"></div>
<div class="wall two"></div>
<div class="wall three"></div>
<div class="wall four"></div>
<div class="ship"></div>
</div>
</div>
As freefomn-m already said.
Check for collision in the animation cycle of the ship, not the walls.
For this I use the second type of parameters for jQuery's .animate method
.animate( properties, options )
I use the "progress" option to check the collision in every movement cycle of the ship.
console.clear();
$('document').ready(function() {
var collided = false;
var collidedWith = null;
var $ship = $('.ship');
var $walls = $('.wall')
var $totalHeight = $('.inner').height(); //of walls
var $maxHeight = Math.ceil(Math.ceil($totalHeight / 3) - (Math.ceil($totalHeight / 3) * 30) / 100); //30% of total wall height
$('.wall').each(function(i, obj) {
$(this).height($maxHeight);
$('.wall.four').css({
'height': $wallGap
});
})
var $wallGap = Math.ceil($totalHeight / 3) - $maxHeight;
var $wallOneTop = 0;
var $wallTwoTop = $maxHeight + $wallGap;
var $wallThreeTop = ($maxHeight * 2) + ($wallGap * 2);
var $wallFourTop = -$('.wall.four').height() - $wallGap;
$('.wall.one').css({
'top': $wallOneTop
});
$('.wall.two').css({
'top': $wallTwoTop
});
$('.wall.three').css({
'top': $wallThreeTop
});
$('.wall.four').css({
'top': $wallFourTop
});
function moveWall(wallObj) {
var $currentTop = wallObj.position().top;
var $limitTop = $('.inner').height();
if ($currentTop >= $limitTop) {
var $rand = Math.floor(Math.random() * ($maxHeight - $wallGap + 1) + $wallGap);
wallObj.height($rand);
var $top = -(wallObj.height());
} else {
var $top = (wallObj.position().top) + 5;
}
// var $collide = checkCollision(wallObj);
wallObj.css({
'top': $top
});
// return $collide;
}
var $wallTimer = setInterval(function() {
$walls.each(function(i, obj) {
moveWall($(this));
if (collided) {
clearInterval($wallTimer);
}
})
}, 40);
function checkCollision() {
var $shipWidth = $ship.width();
var $shipHeight = $ship.height();
var $shipLeft = $ship.position().left;
var $shipRight = $shipLeft + $shipWidth;
var $shipTop = $ship.position().top;
var $shipBottom = $shipTop + $shipHeight;
$('.wall').each(function(i) {
var $wall = $(this);
var $wallWidth = $wall.width();
var $wallHeight = $wall.height();
var $wallLeft = $wall.position().left;
var $wallRight = $wallLeft + $wallWidth;
var $wallTop = $wall.position().top;
var $wallBottom = $wallTop + $wallHeight;
if (
$shipLeft < $wallRight &&
$shipRight > $wallLeft &&
$shipTop < $wallBottom &&
$shipBottom > $wallTop
) {
console.log("dhumm!");
collided = true;
collidedWith = $wall
$wall.addClass('crashed')
$ship.addClass('crashed')
$ship.stop();
return false;
}
})
}
$('.outer .inner').click(function() {
var $ship;
$ship = $('.ship');
$shipLeft = $ship.position().left;
$shipRight = $shipLeft + $ship.width();
$inner = $('.inner');
$innerLeft = $inner.position().left;
$innerRight = $innerLeft + $inner.width();
if (($shipLeft < $inner.width() - $ship.width())) {
$ship.animate({
"left": $inner.width() - $ship.width()
}, {
"duration": 500,
"easing": "linear",
"progress": checkCollision,
});
} else if (($shipRight >= $inner.width())) {
$ship.animate({
"left": '0'
}, {
"duration": 500,
"easing": "linear",
"progress": checkCollision,
});
}
});
});
.outer {
background: #fff;
border: 20px solid #efefef;
width: 400px;
height: 600px;
display: inline-block;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
overflow: hidden;
}
.outer .inner {
background: #fff;
height: 100%;
width: 100%;
margin: auto;
position: relative;
overflow: hidden;
}
.outer .inner .wall {
width: 5px;
position: absolute;
left: 50%;
transform: translateX(-50%);
background: #000;
}
.outer .inner .wall.crashed {
background: red;
}
.outer .inner .ship {
width: 15px;
height: 15px;
background: orange;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.outer .inner .ship.crashed {
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="outer">
<div class="inner">
<div class="wall one"></div>
<div class="wall two"></div>
<div class="wall three"></div>
<div class="wall four"></div>
<div class="ship"></div>
</div>
</div>
As a recommendation how I would do this from scratch.
Use an update cycle that is called by either setInterval or setTimeout, or even better with requestAnimationFrame. The updatecycle would be responsible for the time progress and orchestrate the different objects. The structure would be like this.
jQuery(function($) { // same as $('document').ready()
var ship = ...;
var boundaries = ...;
var walls = ...;
var clickEvents = [];
document.addEventListener('click', function(e) {clickEvents.push(e)})
var handleEvents = function() {}
var setupWalls = function () {}
var setupShip= function () {}
var moveWalls = function () {}
var moveShip = function () {}
var checkCollision() {}
var setup = function() {
setupWalls();
setupShip();
// set the initial positions of the ships and the walls
}
var update = function() {
handleEvents();
moveWalls();
moveShips();
var collided = checkCollision();
if (!collided) {
setTimeout(update, 30);
}
}
setup();
update();
})

I can't change the 'style.left' property of a paragraph

There are no errors when ran.
var P1 = document.getElementById("P1");
P1.style.left = "50%";
You need to have a position if you are going to use the left property.
var P1 = document.getElementById("P1");
var pct = 1;
function loop() {
setTimeout(function() {
P1.style.left = ++pct + "%";
loop();
}, 500)
}
loop();
#P1 {
background: black;
height: 10px;
width: 10px;
position: absolute;
}
<div id=P1></div>

How to reset a webpage with a button

I am having trouble with some programming that I want to perform..
On my page there is a button called "resetButton" and it is invisible button in the middle of the page. It is using: z-index: 100 to be place in front of the images that appear behind it to appear to have the effect that you are actually clicking the image to perform the action.
This buttons functionality is to reset the entire race, including: the stoplight switching back to red, the winner image going away, and the two participants in the race begin again at the starting position.
I feel as I am just overthinking this problem and cannot figure it out and would appreciate being led in the right direction.
// script to show and hide winner
function showFish() {
document.getElementById('bluefishwin').style.visibility = "visible";
}
function showTurtle() {
document.getElementById('turtlewins').style.visibility = "visible";
}
function showFishText() {
document.getElementById('fishwins').style.visibility = "visible";
}
function showTurtleText() {
document.getElementById('turtlewinss').style.visibility = "visible";
}
// script to call both functions to start race
function letsRace() {
startTimer();
myMove();
}
// script for stoplight
function displayNextImage() {
document.getElementById("stoplight").src = images[1];
}
function startTimer() {
setInterval(displayNextImage);
}
var images = [],
x = -1;
images[0] = "http://www.drivingtesttips.biz/images/traffic-light-red.jpg";
images[1] = "http://www.drivingtesttips.biz/images/traffic-lights-green.jpg";
// script for race
function myMove() {
var elemBluefish = document.getElementById("bluefish");
var elemTurtle = document.getElementById("turtle");
var posBluefish = 0;
var posTurtle = 0;
var id = setInterval(frame, 5);
function frame() {
if (posBluefish >= 1150 && posTurtle >= 1150) {
clearInterval(id);
return;
}
if (posBluefish < 1140) {
posBluefish += Math.round(Math.random() * 5);
if (posBluefish > 1140) {
posBluefish = 1140;
}
elemBluefish.style.left = posBluefish + 'px';
}
if (posTurtle < 1140) {
posTurtle += Math.round(Math.random() * 5);
if (posTurtle > 1140) {
posTurtle = 1140;
}
elemTurtle.style.left = posTurtle + 'px';
}
if (posBluefish >= 1140 || posTurtle >= 1140) {
clearInterval(id);
if (posBluefish >= 1140 && posTurtle < 1140) {
showFish();
showFishText();
} else if (posBluefish < 1140 && posTurtle >= 1140) {
showTurtle();
showTurtleText();
} else {
window.alert("Tie");
}
return;
}
}
}
#racePrompt {
position: absolute;
left: 10pc;
font-size: 20px;
}
.raceButton {
position: absolute;
width: 5pc;
right: 82pc;
height: 10pc;
z-index: 100;
background: transparent;
border: none !important;
font-size: 0;
}
body {
overflow: hidden;
}
#myStoplight {
position: absolute;
width: 10pc;
}
#bluefish {
position: absolute;
top: 31pc;
width: 17pc;
left: -.5pc;
}
#turtle {
position: absolute;
width: 15pc;
top: 20pc;
left: .5pc;
}
body {
background-image: url("http://www.hpud.org/wp-content/uploads/2015/08/WaterBackground2.jpg")
}
.finishline {
position: absolute;
right: -12pc;
top: 18pc;
}
#stoplight {
position: absolute;
width: 10pc;
}
#bluefishwin {
position: absolute;
right: 31pc;
top: 12pc;
visibility: hidden;
}
#turtlewins {
position: absolute;
width: 20pc;
right: 35pc;
top: 15pc;
visibility: hidden;
}
#fishwins {
font-size: 3pc;
position: absolute;
right: 35pc;
top: 25pc;
visibility: hidden;
}
#turtlewinss {
font-size: 3pc;
position: absolute;
right: 34pc;
top: 26pc;
visibility: hidden;
}
<input type="button" onclick="letsRace()" class="raceButton">
<img id="stoplight" src="http://www.drivingtesttips.biz/images/traffic-light-red.jpg" />
<p id="fishwins">The Fish Wins!</p>
<p id="turtlewinss">The Turtle Wins!</p>
<p id="racePrompt">Click anywhere on the light to start the race!</p>
<img id="bluefish" src="http://clipartist.net/openclipart.org/2013/July/Blue_Fish_Goldfish.png">
<img id="turtle" src="http://www.clipartkid.com/images/386/turtle-free-stock-photo-illustration-of-a-green-sea-turtle-uPgZrm-clipart.png">
<img src="https://t1.rbxcdn.com/877010da8ce131dfcb3fa6a9b07fea89" class="finishline">
<img id="bluefishwin" src="http://clipartist.net/openclipart.org/2013/July/Blue_Fish_Goldfish.png">
<img id="turtlewins" src="http://www.clipartkid.com/images/386/turtle-free-stock-photo-illustration-of-a-green-sea-turtle-uPgZrm-clipart.png">
<div id="container">
<div id="animate"></div>
Any ideas on how to create a function so when I call it with an onClick I can reset everything back to as if I just rendered the page, similar to hitting the refresh button on the web browser.
Well, this practically impossible.
In order to make this work you would have to move state out of the DOM.
To do that, you must specified the Model of you application and just let the UI to render around it. You can imagine it like this:
var ui = createDOM(state)
body.innerHTML = ''
body.appendChild(ui)
//and you state might look like
var state = {
players: [{id: 'turle', winner: true}]
}
//in createDOM fn
function createDOM(state) {
var turtleWinnerDiv = document.createElement('div')
if (state.players[0].winner) {
turtleWinnerDiv.style.visibility = 'visible'
}
return turtleWinnerDiv
}
This is like "nic" way of doing this.
Uglier one might be something like this:
// save original app DOM
var defaultHTML = document.body.innerHTML
// at the end
document.body.innerHTML = defaultHTML
// voila App is back to default state

Make simple js fiddle animation start on button click instead of page load.

I found this rather cool Js fiddle and have been editing the animation a bit and think its something I can use on a current project. However im not the best with Javascript. All I really need to know to accomplish the rest of my goal is how to make the animation not start until you click a button.
Here is the animation for the js fiddle.
http://jsfiddle.net/apipkin/qUTwQ/
Here is the css.
#o {
width: 200px;
height: 400px;
position: relative;
border-bottom: 1px solid blue;}
.bubble {
border: 1px solid
#f40009; display: block;
position: absolute;
border-radius: 20px;
-webkit-border-radius: 20px;
-moz-border-radius: 20px;
}
The rest is in the JS fiddle.
Thanks fo any help!
You can simply wrap it in a function and call that function on click.
DEMO
Create a button:
<button id="btn">Click</button>
And this js:
document.getElementById('btn').addEventListener('click', startAnimation);
function startAnimation() {
YUI().use('node', 'anim', 'anim-node-plugin', function(Y) {
var o = Y.one('#o'),
oW = o.get('offsetWidth'),
oH = o.get('offsetHeight'),
max = 12,
min = 4,
bubbles = 20,
timerDelay = 4000;
function makeBubble() {
var b = Y.Node.create('<span class="bubble"></span>');
b.plug(Y.Plugin.NodeFX, {
duration: 7,
easing: Y.Easing.easeOut,
to: {
top: 0,
opacity: 0
},
on: {
end: function() {
Y.later(10000, this, function(){
animBubble(this.get('node'));
});
}
}
});
o.append(b);
animBubble(b);
}
function animBubble(b) {
var v = Math.floor(Math.random() * (max - min)) + min;
b.setStyles({
height: v + 'px',
width: v + 'px',
borderRadius: v + 'px',
top: (oH + 2) + 'px',
opacity: 1
});
b.setStyle('left', Math.floor(Math.random() * (oW - v)));
b.fx.set('duration', Math.floor(Math.random() * 2 + 3));
b.fx.set('to.top', Math.floor(Math.random() * (oH / 2)));
b.fx.run();
}
for (i = 0; i < bubbles; i++) {
Y.later(Math.random() * timerDelay, this, function() {
makeBubble();
});
}
});
}

Empty space appearing at the end of my carousel

I have used this script to create an infinite carousel on my website here. It's been customized with CSS so the first and last items are displayed half way.
If you keep clicking the right arrow, you will end up hitting an empty space at the end. So far I haven't been able to fix this. Can anybody offer any solutions?
Here is the relevant script:
/**
* #author Stéphane Roucheray
* #extends jquery
*/
jQuery.fn.simplecarousel = function(previous, next, options){
var sliderList = jQuery(this).children()[0];
if (sliderList) {
var increment = jQuery(sliderList).children().outerWidth(true),
elmnts = jQuery(sliderList).children(),
numElmts = elmnts.length,
sizeFirstElmnt = increment,
shownInViewport = Math.round(jQuery(this).width() / sizeFirstElmnt),
firstElementOnViewPort = 1,
isAnimating = false;
for (i = 0; i < shownInViewport; i++) {
jQuery(sliderList).css('width',(numElmts+shownInViewport)*increment + increment + "px");
jQuery(sliderList).append(jQuery(elmnts[i]).clone());
}
jQuery(previous).click(function(event){
if (!isAnimating) {
if (firstElementOnViewPort == 1) {
jQuery(sliderList).css('left', "-" + numElmts * sizeFirstElmnt + "px");
firstElementOnViewPort = numElmts;
}
else {
firstElementOnViewPort--;
}
jQuery(sliderList).animate({
left: "+=" + increment,
y: 0,
queue: true
}, "swing", function(){isAnimating = false;});
isAnimating = true;
}
});
jQuery(next).click(function(event){
if (!isAnimating) {
if (firstElementOnViewPort > numElmts) {
firstElementOnViewPort = 2;
jQuery(sliderList).css('left', "0px");
}
else {
firstElementOnViewPort++;
}
jQuery(sliderList).animate({
left: "-=" + increment,
y: 0,
queue: true
}, "swing", function(){isAnimating = false;});
isAnimating = true;
}
});
}
};
#home-carousel-container {
position: relative;
}
#home-carousel {
overflow: hidden;
}
#home-carousel ul {
margin-left: -143px;
padding: 0;
position: relative;
}
#home-carousel li {
float: left;
height: 645px;
list-style: none outside none;
margin: 0 3px;
width: 256px;
}
As per my comment.
You have set a negative left-margin on your carousel causing it to hide half of an image. As a result when you click next/previous, it shows where an image is moved to create the continuous affect.
Witihin your css, I changed
#home-carousel ul{
position: relative;
padding: 0;
margin-left: -143px;
}
to
#home-carousel ul{
position: relative;
padding: 0;
margin-left: -3px;
}
And had no problems what so ever.

Categories