Jquery slider auto again after finish - javascript

I´m new in Jquery and I need to help with this. I have Jquery image slider on the web page with rotation of few different images with timer 3000 per each image - they still repeat. Under the slider I have simple loader bar - based on other color hidding div with animation from left to right with the same timer 3000. Simple. But problem is, that this animation run only once and images rotate constantly. So question is, how can I make my loader bar with "reload" animation after timer is up? Like this - http://www.designbash.com/wp-content/uploads/2010/01/animated-loading-bar.gif
My JQUERY
function playslider(){
var hidden = $('.colorSlide2');
hidden.animate({"left":"0px"}, 3000).addClass('visible');
}
playslider();
My CSS
.colorSlide2 {
position:absolute;
width:100%;
z-index:2;
left:-100%;
height: 5px;
background: #f8e508;
}
.colorSlide1 {
position: relative;
width: 100%;
height: 5px;
background: #254b8b;
}

Try
$.fx.interval = -10;
function playslider(){
var hidden = $(".colorSlide2")
, reset = hidden.css("left");
return hidden.animate({"left":"0%"}, 3000, "linear", function() {
$(this).css("left", reset);
return playslider()
}).addClass("visible");
}
playslider();
$.fx.interval = -10;
function playslider(){
var hidden = $(".colorSlide2")
, reset = hidden.css("left");
return hidden.animate({"left":"0%"}, 3000, "linear", function() {
$(this).css("left", reset);
return playslider()
}).addClass("visible");
}
playslider();
.colorSlide2 {
position:absolute;
width:100%;
z-index:2;
left:-100%;
height: 5px;
background: #f8e508;
}
.colorSlide1 {
position: relative;
width: 100%;
height: 5px;
background: #254b8b;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="colorSlide1">
<div class="colorSlide2"></div>
</div>

Related

How to save object position after animation in JavaScript?

I am trying to animate an object for a game in which the ball is supposed to move up, right, left and down on pressing user button. I am trying to achieve this by using .animate() function on the ball. But after every animation event, the ball resets to its initial position and does not continue moving from its "new" position. Is there any way to accomplish this?
Following is my condensed code snippet for simplicity:
/* Animation */
var item = document.getElementById('item');
var anim;
function myMoveLeft(){
anim=item.animate([
// keyframes
{ transform: 'translateX(0px)' },
{ transform: 'translateX(-60px)' }
], {
duration: 1000,
iterations: 1
});
}
function myMoveDown(){
anim=item.animate([
// keyframes
{ transform: 'translateY(0px)' },
{ transform: 'translateY(60px)' }
], {
duration: 1000,
iterations: 1
});
// anim.onfinish(()=>{console.log("onfinish ran")})
}
item.addEventListener('animationend', () => {
console.log('Animation ended');
});
button{
display:inline-block;
height:40px;
width:80px;
}
#myContainer {
width: 400px;
height: 400px;
position: relative;
background: lightgray ;
}
#item {
background: orange;
position: absolute;
right:30px;
top:30px;
height: 30px;
width: 30px;
border-radius:50%;
}
<p>
<button onclick="myMoveLeft()">Left</button>
<button onclick="myMoveDown()">Down</button>
</p>
<div id ="myContainer">
<div id="item"></div>
</div>
As seen, I have already tried using .onfinish() and Event Listener 'animationend' hoping I could update the new 'right' and 'top' position but it does not work. Not sure if that would be the right approach.
Could someone please suggest on how to save the element to a new position and animate it further from that new position?
PS: I am also open to suggestions/techniques if you feel there are other better ways to do this.
Thanks a lot in Advance!!
You can make the ball get the final transform value using the fill option, which is the same as animation-fill-mode in css animation.
For not override the transform when you do the next animation, you can save the x and y value as variables, and do any animation according to the current x and y state. (from x to x-60, instead from 0 to -60, etc.)
Example:
/* Animation */
var item = document.getElementById('item');
var anim;
var x=0, y=0;
function myMoveLeft(){
anim=item.animate([
// keyframes
{ transform: `translate(${x}px, ${y}px)` },
{ transform: `translate(${x-60}px, ${y}px)` }
], {
duration: 1000,
iterations: 1,
fill: 'forwards'
});
x -= 60;
}
function myMoveDown(){
anim=item.animate([
// keyframes
{ transform: `translate(${x}px, ${y}px)` },
{ transform: `translate(${x}px, ${y+60}px)` }
], {
duration: 1000,
iterations: 1,
fill: 'forwards'
});
y += 60;
// anim.onfinish(()=>{console.log("onfinish ran")})
}
item.addEventListener('animationend', () => {
console.log('Animation ended');
});
button{
display:inline-block;
height:40px;
width:80px;
}
#myContainer {
width: 400px;
height: 400px;
position: relative;
background: lightgray ;
}
#item {
background: orange;
position: absolute;
right:30px;
top:30px;
height: 30px;
width: 30px;
border-radius:50%;
}
<p>
<button onclick="myMoveLeft()">Left</button>
<button onclick="myMoveDown()">Down</button>
</p>
<div id ="myContainer">
<div id="item"></div>
</div>

JS and CSS Centering Slideshow Images

I have a slideshow that pulls its first image from a div, then pulls the rest of the images from an array of list items. I am following a tutorial exactly from The JavaScript Pocket Guide by Burdette (2010 printing), and while everything else works I cannot get any of the pictures after the first to center or align differently. They float left and to the top of the div.
HMTL:
<!DOCTYPE html>
<hmtl class="no-js">
<head>
<title>Slideshow</title>
<link rel="stylesheet" href="slideshow.css" type="text/css" />
<script type="text/javascript">
(function(d, c) { d[c] = d[c].replace(/\bno-js\b/,"js";})(document.documentElement, "className");
</script>
</head>
<body>
<div id="slideshow">
<div class="slides">
<img src="picture01.jpg" width="450" height="336" alt="stuff" />
</div>
<ul>
<li><a href="picture02.jpg" data-size="350x263"</li>
<li><a href="picture03.jpg" data-size="350x263"</li>
<li><a href="picture04.jpg" data-size="350x263"</li>
</ul>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js" type="text/javascript">
</script>
<script src="slideshow.js" type="text/javascript">
</script>
</body>
</hmtl>
CSS:
#slideshow {
background-color: #103f1c;
width:500px;
height:450px;
margin-left: auto;
margin-right: auto;
top:0px;
position: relative;
}
#slideshow .slides {
position: relative;
margin-left: auto;
margin-right: auto;
width: 450px;
}
#html.js #slideshow .slides img{
position: absolute;
margin-left: auto;
margin-right: auto;
}
#slideshow .next,
#slideshow .prev {
position: absolute;
top: 50%;
margin-top: -0.5em;
width: 40px;
font-size: 32px;
text-decoration: none;
}
#slideshow .next{
right: -50px;
padding-left:10px;
}
#slideshow .prev {
left:-50px;
padding-right: 10px;
text-align: right;
}
JS:
(function($) {
// Include utility jQuery plug-ins
$.fn.tallest = function(outer, margins) {
var fn = outer ? "height" : "outerHeight";
return Math.max.apply(Math, $.map(this, function(el) {
return $(el)[fn](margins);
}));
};
$.fn.widest = function(outer, margins) {
var fn = outer ? "width" : "outerWidth";
return Math.max.apply(Math, $.map(this, function(el) {
return $(el)[fn](margins);
}));
};
// Declare initial variables
var slideshow = $("#slideshow");
var slides = slideshow.find(".slides");
var currentImageIndex = 0;
// Create images from the link list
slideshow.find("ul a").each(function() {
var link = $(this);
var size = link.attr("data-size").split("x");
$("<img />").attr({
src : link.attr("href"),
width : size[0],
height : size[1],
alt : link.text()
}).hide().appendTo(slides);
});
// Collect all images in one node set and hide the list
var images = slides.find("img");
slideshow.find("ul").hide();
// Resize slides <div> to hold the largest images
var slidesWidth = images.widest();
var slidesHeight = images.tallest();
slides.css({
width : slidesWidth,
height : slidesHeight
});
// Center each image
images.each(function() {
var image = $(this);
image.css({
left: slidesHeight / 2 - image.width() / 2,
top: slidesHeight / 2 - image.height() / 2,
});
});
// Save a reference to the first image
var activeImage = images.eq(currentImageIndex);
// The function to show the next or previous image
function showImage(newIndex) {
currentImageIndex = newIndex >= images.length ? 0 : newIndex;
currentImageIndex = currentImageIndex < 0 ? images.length - 1 : currentImageIndex;
activeImage.fadeOut(0);
activeImage = images.eq(currentImageIndex).fadeIn(150);
}
// Start timer to cycle through images
var interval = setInterval(function() {
showImage(currentImageIndex + 1);
}, 5000);
// Create next and previous controls
$('\u232A').appendTo(slides).bind("click", +1, onClick);
$('\u2329').appendTo(slides).bind("click", -1, onClick);
// The event handler for the controls
function onClick(event) {
event.preventDefault();
clearInterval(interval);
showImage(currentImageIndex + event.data);
}
})(jQuery); // Self-invoking function executes automatically
The main problem here is in your CSS:
#html.js #slideshow .slides img{
position: absolute;
margin-left: auto;
margin-right: auto;
}
Margin: auto; will only work on objects that have a defined width. Since an image is a replaced inline-block, no real width exists. This is made worse by the fact that you've positioned it absolutely, which changes the way margins will work - the item will always pick up its position relative to the determined parent, and apply margins after that outside of the flow, so auto will not be relevant.
first step is to remove the absolute positioning on the image, it's not useful here.
By default, images are a type of inline-block, so simply adding "text-align:center;" to the "#slideshow .slides" selector will center the images.
Alternately, if we just want to edit the images and force them to center themselves, change the above block to:
#html.js #slideshow .slides img{
display:block;
margin-left: auto;
margin-right: auto;
}
and everything should line up like you wanted.

How to create a condition for scrolling below a point, and fire the function just once. instead of every time you scroll below that point

I'm trying to make the header fade out, then slide back in when you scroll past 100px, but the function fires every time you scroll anywhere past that point.
I don't want that to happen, I want it so that the function fires only once when you scroll past it and if you scroll again, even if you're past that point, nothing happens.
Check out my fiddle: http://jsfiddle.net/bazzle/6ykyjm0p/2/
Thanks in advance.
<header>
<div class="top">
This is the header
</div>
This is the point function should work.
</header>
html {
height: 200%;
}
header {
background-color: blue;
color: white;
width: 100%;
height: 300px;
}
.top{
height: 100px;
width: 100%;
border-bottom: 1px solid white;
display: block;
}
var stickyheader = function(){
if ($(window).scrollTop() > 100) {
$('header').hide(50, function(){
$(this).slideDown(1000);
});
}
else {
}
};
$(window).on('scroll',function(){
stickyheader();
});
Hi you can use a global variable as a flag to prevent the script from firing.
var flag = 0;
var stickyheader = function() {
if ($(window).scrollTop() > 100) {
if (flag == 0) {
$('header').hide(50, function() {
$(this).slideDown(1000);
flag = 1;
});
}
} else {
}
};
$(window).on('scroll', function() {
stickyheader();
});
html {
height:200%;
}
header {
background-color:blue;
color:white;
width:100%;
height:300px;
}
.top {
height:100px;
width:100%;
border-bottom:1px solid white;
display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
<div class="top">This is the header</div>This is the point function should work.</header>
You can also reset flag = 0; in the else case if you want the code to execute everytime the user scroll beyond the point.
Hope this help.

Applying background color based on scrolling content

Here is my JsFiddle
I want to apply background-color change property to circle when the window slides. Like in the beginning only first circle will have background-color. and when the images slides to second screen the second circle will have only color.
Can anybody guide me how to achieve that.
JQuery:
$(document).ready(function () {
setInterval(function () {
var A = $('.gallery').scrollLeft();
if (A < 993) {
$('.gallery').animate({
scrollLeft: '+=331px'
}, 300);
}
if (A >= 993) {
$('.gallery').delay(400).animate({
scrollLeft: 0
}, 300);
}
}, 3000);
});
Here's a simple solution of your problem: http://jsfiddle.net/pjvCw/44/ but....
The way you're doing galleries is quite wrong.
You have a really sensitive CSS full of margin bugs (see in CSS code),
you calculate all by hand, which will just complicate your life one day if you'll get to add images, change widths etc...
Your buttons are positioned really wrongly, and again you don't even need to manually add them in your HTML. Let jQuery do all the job for you:
Calculate margins, widths,
Get the number of slides
generate buttons,
Make your buttons clickable
Pause gallery on mouseenter (loop again on mouseleave)
LIVE DEMO
This is the way you should go with your slider:
HTML:
<div class="galleryContainer"> <!-- Note this main 'wrapper' -->
<div class="gallery">
<div class="row">
<!-- ..your images.. -->
</div>
<div class="row">
<!-- ..your images.. -->
</div>
</div>
<div class="content-nav-control"></div> <!-- Let jQ create the buttons -->
</div>
Note the general gallery wrapper, it allows you with this CSS to make your buttons parent not move with the gallery.
CSS:
In your code, using display:inline-block; adds 4px margin to your elements, ruining your math. So you just need to apply font-size:0; to remove that inconvenience.
As soon I did that the math was working and the right width was than 340px, having 5px border for your images and 20px margin.
.galleryContainer{
/* you need that one
// to prevent the navigation move */
position:relative; /* cause .content-nav-control is absolute */
background-color: #abcdef;
width:340px; /* (instead of 350) now the math will work */
height: 265px;
}
.gallery{
position:relative;
overflow: hidden; /* "overflow" is enough */
width:340px; /* (instead of 350) now the math will work */
height: 265px;
}
.gallery .row {
white-space: nowrap;
font-size:0; /* prevent inline-block 4px margin issue */
}
.gallery img {
display: inline-block;
margin-left: 20px;
margin-top: 20px;
}
.normalimage {
height: 80px;
width: 50px;
border: 5px solid black;
}
.wideimage {
height: 80px;
width: 130px;
border: 5px solid black;
}
img:last-of-type {
margin-right:20px;
}
.content-nav-control {
position: absolute;
width:100%; /* cause it's absolute */
bottom:10px;
text-align:center; /* cause of inline-block buttons inside*/
font-size:0; /* same trick as above */
}
.content-nav-control > span {
cursor:pointer;
width: 20px;
height: 20px;
display: inline-block;
border-radius: 50%;
border:1px solid #000;
box-shadow: inset 0 0 6px 2px rgba(0,0,0,.75);
margin: 0 2px; /* BOTH MARGINS LEFT AND RIGHT */
}
.content-nav-control > span.active{
background:blue;
}
And finally:
$(function () { // DOM ready shorty
var $gal = $('.gallery'),
$nav = $('.content-nav-control'),
galSW = $gal[0].scrollWidth, // scrollable width
imgM = parseInt($gal.find('img').css('marginLeft'), 10), // 20px
galW = $gal.width() - imgM, // - one Margin
n = Math.round(galSW/galW), // n of slides
c = 0, // counter
galIntv; // the interval
for(var i=0; i<n; i++){
$nav.append('<span />'); // Create circles
}
var $btn = $nav.find('span');
$btn.eq(c).addClass('active');
function anim(){
$btn.removeClass('active').eq(c).addClass('active');
$gal.stop().animate({scrollLeft: galW*c }, 400);
}
function loop(){
galIntv = setInterval(function(){
c = ++c%n;
anim();
}, 3000);
}
loop(); // first start kick
// MAKE BUTTONS CLICKABLE
$nav.on('click', 'span', function(){
c = $(this).index();
anim();
});
// PAUSE ON GALLERY MOUSEENTER
$gal.parent('.galleryContainer').hover(function( e ){
return e.type=='mouseenter' ? clearInterval(galIntv) : loop() ;
});
});
"- With this solution, What can I do now and in the future? -"
Nothing! just freely add images into your HTML and play, and never again have to take a look at your backyard :)
Try this: http://jsfiddle.net/yerdW/1/
I added a line that gets the scrollLeft and divides it by your width (331px) to get the position and use that to select the 'active' circle:
$(".circle").removeClass("coloured");
position = Math.ceil($(".gallery").scrollLeft()/331 + 2);
if(position > $(".circle").length){
position = 1; // yes...
}
$(".content-nav-control div:nth-child("+position+")").addClass("coloured");
Red background for active circle:
.coloured {
background : red;
}
Note that you should initialise with the first circle already having the .coloured class applied.
Here you go: http://jsfiddle.net/pjvCw/41/
i added new class
.selected
{
background-color: red;
}
and modified some js code
Here is your jsfiddle edited http://jsfiddle.net/pjvCw/45/
var scrolled = 0;
var circles = $(".circle");
var colorCircle = function(index) {
for(var i=0; i<circles.length; i++) {
if(i == index) {
circles.eq(i).css("background-color", "rgba(255, 0, 0, 1)");
} else {
circles.eq(i).css("background-color", "rgba(255, 0, 0, 0)");
}
}
}
$(document).ready(function () {
setInterval(function () {
var A = $('.gallery').scrollLeft();
if (A < 993) {
$('.gallery').animate({
scrollLeft: '+=331px'
}, 300);
colorCircle(++scrolled);
}
if (A >= 993) {
$('.gallery').delay(400).animate({
scrollLeft: 0
}, 300);
colorCircle(scrolled = 0);
}
}, 3000);
colorCircle(0);
});
I added a transition to the .circle class, so it looks a little bit better:
.circle {
width: 20px;
height: 20px;
display: inline-block;
border-radius: 50%;
border:1px solid #000;
box-shadow: inset 0 0 6px 2px rgba(0,0,0,.75);
margin-right: 5px;
transition: background-color 700ms;
-webkit-transition: background-color 700ms;
}

Drop Down Animate Contact Box

I have been looking all day for a way to make a contact form similar to the one on this site: http://45royale.com/
If you click on the contact button a black background fades in and the from drops down using an ease function. I have been picking through the code trying to see what to do but I am stuck and I have also been looking and other javascript pop ups but so far it seems they only use php for the form however this one calls a html.
Any suggestions?
Here is something like the form in the example: http://jsfiddle.net/ep39v/3/.
And the source:
HTML
<div class="form"></div>
<button id="showFormBtn">Show form</button>
​
JavaScript
var form = $('.form');
$('#showFormBtn').click(function () {
fadeBackground(showForm);
});
(function () {
form.css({
top: -form.height(),
left: ($(document.body).width() - form.width()) / 2
});
}());
function fadeBackground(callback) {
var background = $('<div class="background"></div>');
$(document.body).append(background);
background.fadeTo(300, 0.5, function () {
if (typeof callback === 'function') {
callback();
}
});
}
function showForm() {
var form = $('.form');
form.animate({ top: 10 }, 1500, 'easeOutElastic');
}
​
CSS
.form {
width: 30%;
height: 40%;
background: black;
position: absolute;
}
body {
height: 100%;
}
.background {
height: 100%;
width: 100%;
position: absolute;
top: 0px;
left: 0px;
background: black;
opacity: 0;
}​
May be you need to change only the easing.

Categories