Switching tab makes CSS go crazy - javascript

Can anyone explain why this 3D works OK when you visit the page but disintegrates when you switch to another tab and then revert to the page?
But then...
... it disappears into the screen!
HTML:
<html>
<head>
<link href="styles/styles.css" rel="stylesheet" />
</head>
<body style='background-color: white; width: 900px;'>
<div style='margin: 50px auto;'>
<div id="img" style="background-image: url('img1.jpg'); width: 850px; height: 520px" />
</div>
<script src="js/libs/jquery/jquery-1.6.4.js" type="text/javascript"></script>
<script src="js/libs/jquery/jquery-slide-show-filter.js" type="text/javascript"></script>
</body>
</html>
CSS:
#container{
-webkit-perspective: 800;
width: 850px;
height: 520px;
}
#img, #s1 {
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
background-repeat: no-repeat;
}
#cube{
-webkit-transform-style: preserve-3d;
-webkit-transform: translateZ(-425px);
-webkit-backface-visibility: hidden;
width: 850px;
height: 520px;
}
#cube.enable
{
-webkit-animation: flash 0.75s ease-in-out;
-moz-animation: flash 0.75s ease-in-out;
-ms-animation: flash 0.75s ease-in-out;
-o-animation: flash 0.75s ease-in-out;
animation: flash 0.75s ease-in-out;
}
#-webkit-keyframes flash {
100% { -webkit-transform: translateZ(-425px) rotateY(90deg); }
}
Script:
var getImage = function(){
var images = ["img1.jpg", "img2.jpg", "img3.jpg"];
$.each(images, function( index, value ) {
$('<img />').attr('src', value);
});
index = 0;
return function(){
if (++index == images.length){
index = 0;
}
return images[index];
};
}();
setInterval(function(){
transform($('#img'), getImage());
}, 1000);
function transform(img, newImg){
img
.wrap('<div id="container"><div id="cube"></div>')
.css('-webkit-transform', 'translateZ(425px)');
img
.clone()
.attr('id', 's1')
.insertBefore(img)
.css('background-image', 'url("' + newImg + '")')
.css('position', 'absolute')
.css('-webkit-transform', 'rotateY(-90deg) translateZ(425px)');
PrefixedEvent($('#cube')[0], "AnimationEnd", function () {
img.unwrap().unwrap();
img.remove();
$('#s1')
.attr('id', 'img')
.css('-webkit-transform', '');
});
$('#cube').addClass('enable');
}
function PrefixedEvent(element, type, callback) {
var pfx = ["webkit", "moz", "MS", "o", ""];
for (var p = 0; p < pfx.length; p++) {
if (!pfx[p]) type = type.toLowerCase();
element.addEventListener(pfx[p]+type, callback, false);
}
}

You can fix the issue by calling transform only while the window has focus:
(function() {
var inTab= false;
$(window).blur(function() {
inTab= false;
});
$(window).focus(function() {
inTab= true;
});
setInterval(function() {
if(inTab) {
transform($('#img'), getImage());
}
}, 1000);
})();
Fiddle
Click the image to simulate the window being focused. You can then switch between tabs, and the animation will no longer break.

I think its because if you switch tab the AnimationEnd event doesn't fire so there's no clean up.

Related

CSS transition creating problem in JavaScript? [duplicate]

Consider such div:
<div id="someid"></div>
And it's style:
#someid {
transition: background-color 10s ease;
background-color: #FF0000;
height: 100px;
width: 100px;
}
#someid:hover {
background-color: #FFFFFF;
}
I want to have a possibility to detect state (currently animating or not) of #someid via JS and/or end animation if that's possible. I've tried a thing from this answer:
document.querySelector("#someid").style.transition = "none";
but it didn't work for currently animating element.
The point is I need to detect whether element is animating now and if so, wait for animation to end or end it immediately, otherwise do nothing
I've already found transitionend event, but using it I can't detect whether element is animating at the moment.
You can listen to transition event and remove it on demand:
const el = document.getElementById('transition');
let isAnimating = false;
el.addEventListener('transitionstart', function() {
isAnimating = true;
});
el.addEventListener('transitionend', () => {
isAnimating = false;
});
el.addEventListener('transitioncancel', () => {
isAnimating = false;
});
function removeTransition(checkIfRunning) {
if (checkIfRunning && !isAnimating) {
return;
}
el.style.transition = "none";
}
#transition {
width: 100px;
height: 100px;
background: rgba(255, 0, 0, 1);
transition-property: transform background;
transition-duration: 2s;
transition-delay: 1s;
}
#transition:hover {
transform: rotate(90deg);
background: rgba(255, 0, 0, 0);
}
<div id="transition">Hello World</div>
<br />
<button onclick="removeTransition(false)">Remove Transition</button>
<br />
<br />
<button onclick="removeTransition(true)">Remove Transition on if running</button>

How to animate endless loop using jquery?

I have been trying using jquery animate to do a running text. But I can't seems to get it run in an endless loop. It always runs one time only..
/* js: */
$(document).ready(function(){
function scroll() {
$('.scroll').animate({
right: $(document).width()
}, 8000, scroll);
}
scroll();
});
/* css: */
.scroll {
position: absolute;
right: -200px;
width: 200px;
}
<!-- html: -->
<div class="scroll">This text be scrollin'!</div>
This is the demo:
https://jsfiddle.net/y9hvr9fa/1/
Do you guys know how to fix it?
So this is what I did:
Precalculate $(document).width() as if a horizontal scroll appears, the width will change in the next iteration
Remove the width you have set for scroll so that the width is only as long as the content - and you would have to give white-space:nowrap to keep the text in a line.
In the animate use the width of the scroll text using $('.scroll').outerWidth()
See demo below and update fiddle here
$(document).ready(function() {
// initialize
var $width = $(document).width();
var $scrollWidth = $('.scroll').outerWidth();
$('.scroll').css({'right': -$scrollWidth + 'px'});
// animate
function scroll() {
$('.scroll').animate({
right: $width
}, 8000, 'linear', function() {
$('.scroll').css({'right': -$scrollWidth + 'px'});
scroll();
});
}
scroll();
});
body {
overflow: hidden;
}
.scroll {
position: absolute;
white-space: nowrap;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="scroll">This text be scrollin'!</div>
Let me know your feedback on this, thanks!
CSS Alternative:
Alternatively you could use a CSS transition like in this CodePen:
https://codepen.io/jamesbarnett/pen/kfmKa
More advanced:
$(document).ready(function(){
var scroller = $('#scroller'); // scroller $(Element)
var scrollerWidth = scroller.width(); // get its width
var scrollerXPos = window.innerWidth; // init position from window width
var speed = 1.5;
scroller.css('left', scrollerXPos); // set initial position
function moveLeft() {
if(scrollerXPos <= 0 - scrollerWidth) scrollerXPos = window.innerWidth;
scrollerXPos -= speed;
scroller.css('left', scrollerXPos);
window.requestAnimationFrame(moveLeft);
}
window.requestAnimationFrame(moveLeft);
});
.scroll {
display: block;
position: absolute;
overflow: visible;
white-space: nowrap;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="scroller" class="scroll">This text be scrollin'!</div>
Dirty solution (my original answer):
In this example this would be a quick fix:
The text is running to the left without ever stopping. Here you will tell the text to always start at that position. (After the time has run up - meaning not necessarily just when it has left the screen)
$(document).ready(function(){
function scroll() {
$('.scroll').css('right', '-200px').animate({
right: $(document).width()
}, 8000, scroll);
}
scroll();
});
I have been trying using jquery animate to do a running text.
You know that the <marquee> HTML element works, right?
Which means you don't need CSS, Javascript or jQuery.
Pure HTML Solution:
<marquee>This text be scrollin'!</marquee>
The <marquee> element includes a large number of optional declarative attributes which control the behaviour of the scrolling text:
behavior
bgcolor
direction
height
hspace
loop
scrollamount
scrolldelay
truespeed
vspace
width
Further Reading:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/marquee
Note 1:
The resource above correctly notes that:
This feature is no longer recommended. Though some browsers might
still support it, it may have already been removed from the relevant
web standards, may be in the process of being dropped, or may only be
kept for compatibility purposes.
Note 2
The same resource also recommends:
see the compatibility table at the bottom of this page to guide your decision
And... a cursory look at that compatibility table shows that the <marquee> element is as browser-compatible as the most established, most browser-compatible elements which exist today.
I hope it is useful :)
function start() {
new mq('latest-news');
mqRotate(mqr);
}
window.onload = start;
function objWidth(obj) {
if (obj.offsetWidth) return obj.offsetWidth;
if (obj.clip) return obj.clip.width;
return 0;
}
var mqr = [];
function mq(id) {
this.mqo = document.getElementById(id);
var wid = objWidth(this.mqo.getElementsByTagName("span")[0]) + 5;
var fulwid = objWidth(this.mqo);
var txt = this.mqo.getElementsByTagName("span")[0].innerHTML;
this.mqo.innerHTML = "";
var heit = this.mqo.style.height;
this.mqo.onmouseout = function () {
mqRotate(mqr);
};
this.mqo.onmouseover = function () {
clearTimeout(mqr[0].TO);
};
this.mqo.ary = [];
var maxw = Math.ceil(fulwid / wid) + 1;
for (var i = 0; i < maxw; i++) {
this.mqo.ary[i] = document.createElement("div");
this.mqo.ary[i].innerHTML = txt;
this.mqo.ary[i].style.position = "absolute";
this.mqo.ary[i].style.left = wid * i + "px";
this.mqo.ary[i].style.width = wid + "px";
this.mqo.ary[i].style.height = heit;
this.mqo.appendChild(this.mqo.ary[i]);
}
mqr.push(this.mqo);
}
function mqRotate(mqr) {
if (!mqr) return;
for (var j = mqr.length - 1; j > -1; j--) {
maxa = mqr[j].ary.length;
for (var i = 0; i < maxa; i++) {
var x = mqr[j].ary[i].style;
x.left = parseInt(x.left, 10) - 1 + "px";
}
var y = mqr[j].ary[0].style;
if (parseInt(y.left, 10) + parseInt(y.width, 10) < 0) {
var z = mqr[j].ary.shift();
z.style.left = parseInt(z.style.left) + parseInt(z.style.width) * maxa + "px";
mqr[j].ary.push(z);
}
}
mqr[0].TO = setTimeout("mqRotate(mqr)", 20);
}
.marquee {
position: relative;
overflow: hidden;
text-align: center;
margin: 0 auto;
width: 100%;
height: 30px;
display: flex;
align-items: center;
white-space: nowrap;
}
#latest-news {
line-height: 32px;
a {
color: #555555;
font-size: 13px;
font-weight: 300;
&:hover {
color: #000000;
}
}
span {
font-size: 18px;
position: relative;
top: 4px;
color: #999999;
}
}
<div id="latest-news" class="marquee">
<span style="white-space:nowrap;">
<span> •</span>
one Lorem ipsum dolor sit amet
<span> •</span>
two In publishing and graphic design
<span> •</span>
three Lorem ipsum is a placeholder text commonly
</span>
</div>
How is this?
.scroll {
height: 50px;
overflow: hidden;
position: relative;
}
.scroll p{
position: absolute;
width: 100%;
height: 100%;
margin: 0;
line-height: 50px;
text-align: center;
-moz-transform:translateX(100%);
-webkit-transform:translateX(100%);
transform:translateX(100%);
-moz-animation: scroll 8s linear infinite;
-webkit-animation: scroll 8s linear infinite;
animation: scroll 8s linear infinite;
}
#-moz-keyframes scroll {
0% { -moz-transform: translateX(100%); }
100% { -moz-transform: translateX(-100%); }
}
#-webkit-keyframes scroll {
0% { -webkit-transform: translateX(100%); }
100% { -webkit-transform: translateX(-100%); }
}
#keyframes scroll {
0% {
-moz-transform: translateX(100%);
-webkit-transform: translateX(100%);
transform: translateX(100%);
}
100% {
-moz-transform: translateX(-100%);
-webkit-transform: translateX(-100%);
transform: translateX(-100%);
}
}
<div class="scroll"><p>This text be scrollin'!</p></div>

How to animate cloned element?

What i want to do is looped horizontaly text slider.
My attempt - when end of text is displayed, clone this element move to right end and play animation for cloned element again - but i can't achieve that because for some reason cloned element don't want to animate.
This is chrome only app
Here is jsfiddle.
CSS
#elm {
width: 100px;
height:20px;
overflow: auto;
overflow-y: hidden;
position:absolute;
top:10px;
left:10px;
}
#elm::-webkit-scrollbar { width: 0 !important; height: 0 !important; }
#elm .inner-elm {
position:absolute;
white-space: nowrap;
}
HTML
<div id="elm">
<div class="inner-elm"> 11111111 2222222 333333 4444444</div>
</div>
JS
var elm_right = $('#elm').offset().left + $('#elm').outerWidth();
var settings = {
duration: 5000,
easing: 'linear',
step: function() {
var this_right = $(this).offset().left + $(this).outerWidth();
// make some clone
if(!$(this).hasClass('cloned') && ((this_right + 50) < elm_right)) {
$(this).addClass('cloned');
var clone = $(this).clone(true);
clone.addClass('cloned')
.css('left', $('#elm').width())
.appendTo('#elm')
.animate({right:100}, settings);
}
// remove parent
if( (this_right - 20) < $('#elm').offset().left) {
$(this).remove();
}
}
};
var that = $('#elm .inner-elm');
that.animate({right: that.outerWidth()}, settings);
You could use CSS3 transitions for a simple animation like this. fiddle
var interval = 2000;
var nextTimeout = 200;
var wrapper = $('#elm');
var elem = $('.inner-elm', wrapper);
elem.addClass('move');
setInterval(function(){
var clone = elem.clone(true);
elem.remove();
elem = clone;
elem.removeClass('move');
wrapper.append(elem);
setTimeout(function(){
elem.addClass('move');
}, nextTimeout);
}, interval);
#elm {
height:20px;
overflow: auto;
overflow-y: hidden;
position:absolute;
top:10px;
left:10px;
}
.inner-elm{
transition: all 2s linear;
-ms-transform: translate(110%, 0); /* IE 9 */
-webkit-transform: translate(110%x, 0); /* Safari */
transform: translate(110%, 0);
}
.move{
-ms-transform: translate(-130%, 0); /* IE 9 */
-webkit-transform: translate(-130%, 0); /* Safari */
transform: translate(-130%, 0);
}
#elm::-webkit-scrollbar { width: 0 !important; height: 0 !important; }
#elm .inner-elm {
position:relative;
white-space: nowrap;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div id="elm">
<div class="inner-elm">Stackoverflow</div>
</div>

Javascript Text Rotate

Hello guys it's been bugging me all night. I've been trying to get together a word rotate feature that decreases in speed and then eventually stops. Think of it like a word roulette. So i have the words stored in an array and it looks over the words and displays them. Now, i need to decelerate the speed and slowly make it stop and a random lettter, how would i go about this ?
<?php
$json=file_get_contents('http://ddragon.leagueoflegends.com/cdn/5.18.1/data/en_US/champion.json');
$champions = json_decode($json);
?>
<?php
$championsArray = array();
foreach($champions->data as $champion){
$championsArray[] = $champion->id;
}
shuffle($championsArray);
$speed = 1000;
$count = count($championsArray);
var_dump($championsArray);
?>
<!DOCTYPE html>
<html lang="en" class="demo1 no-js">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jQuery Super Simple Text Rotator Demo 1: Default Settings</title>
<meta name="description" content="Rotating text is a very simple idea where you can add more content to a text area without consuming much space by rotating an individual word with a collection of others" />
<meta name="keywords" content="jquery text rotator, css text rotator, rotate text, inline text rotator" />
<meta name="author" content="Author for Onextrapixel" />
<link rel="shortcut icon" href="../file/favicon.gif">
<link rel="stylesheet" type="text/css" href="css/default.css" />
<!-- Edit Below -->
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script>
<link rel="stylesheet" href="jquery.wordrotator.css">
<script src="jquery.wordrotator.js"></script>
</head>
<body class="demo1">
<div class="container">
<p><span id="myWords"></span></p>
<div class="main">
Go!
</div>
</div><!-- Container -->
<script type="text/javascript">
function eventFire(el, etype){
if (el.fireEvent) {
el.fireEvent('on' + etype);
} else {
var evObj = document.createEvent('Events');
evObj.initEvent(etype, true, false);
el.dispatchEvent(evObj);
}
}
function erm() {
var cont = $("#myWords");
$(function () {
$("#myWords").wordsrotator({
randomize: true,
stopOnHover: true, //stop animation on hover
words: ['Heimerdinger','Ezreal','Skarner','Nunu','Kennen','Lulu','Morgana','Sejuani','Draven','Nocturne','KogMaw','Jinx','Khazix','Cassiopeia','Fiora','Maokai','Zac','Quinn','Vladimir','RekSai','LeeSin','TwistedFate','MissFortune','Shaco','Vayne','Sivir','Urgot','Nautilus','Annie','Fizz','Janna','Irelia','Karthus','Trundle','Jax','Graves','Leona','Rengar','Amumu','Malzahar','TahmKench','MasterYi','Twitch','Rumble','Nidalee','Shyvana','Veigar','Singed','Riven','Leblanc','Katarina','Azir','Viktor','Poppy','Ahri','Yorick','Aatrox','Brand','Tryndamere','DrMundo','Hecarim','Braum','Nasus','Pantheon','Elise','Velkoz','Swain','Darius','Kayle','Thresh','Nami','Ekko','Alistar','Galio','Warwick','Orianna','Sona','Lux','Ryze','Jayce','Kassadin','Volibear','Blitzcrank','Gangplank','Karma','XinZhao','Ziggs','Malphite','Tristana','Soraka','Anivia','Xerath','Renekton','Shen','Lissandra','Ashe','Mordekaiser','Talon','Zilean','JarvanIV','Rammus','Yasuo','Vi','Bard','Sion','Udyr','MonkeyKing','Akali','Diana','Varus','Kalista','Evelynn','Teemo','Gnar','Garen','Taric','FiddleSticks','Chogath','Zed','Lucian','Caitlyn','Corki','Zyra','Syndra','Gragas','Olaf']
});
});
eventFire(document.getElementById('myWords'), 'click');
}
</script>
</body>
</html>
Can anyone figure out a solution for this?
You could modify a bit the wordrotator plugin so that it allows to change the speed on each rotate.
You'll have to tweak the animation and the speed increment, but this should give you some ideas:
(function ($) {
$.fn.wordsrotator = function (options) {
var defaults = {
autoLoop: true,
randomize: false,
stopOnHover: false,
changeOnClick: false,
words: null,
animationIn: "flipInY",
animationOut: "flipOutY",
speed: 40,
onRotate: function () {},//you add these 2 methods to allow the effetct
stopRotate: function () {}
};
var settings = $.extend({}, defaults, options);
var listItem
var array_bak = [];
var stopped = false;
settings.stopRotate = function () {//you call this one to stop rotate
stopped = true;
}
return this.each(function () {
var el = $(this)
var cont = $("#" + el.attr("id"));
var array = [];
//if array is not empty
if ((settings.words) || (settings.words instanceof Array)) {
array = $.extend(true, [], settings.words);
//In random order, need a copy of array
if (settings.randomize) array_bak = $.extend(true, [], array);
listItem = 0
//if randomize pick a random value for the list item
if (settings.randomize) listItem = Math.floor(Math.random() * array.length)
//init value into container
cont.html(array[listItem]);
// animation option
var rotate = function () {
cont.html("<span class='wordsrotator_wordOut'><span>" + array[listItem] + "</span></span>");
if (settings.randomize) {
//remove printed element from array
array.splice(listItem, 1);
//refill the array from his copy, if empty
if (array.length == 0) array = $.extend(true, [], array_bak);
//generate new random number
listItem = Math.floor(Math.random() * array.length);
} else {
//if reached the last element of the array, reset the index
if (array.length == listItem + 1) listItem = -1;
//move to the next element
listItem++;
}
$("<span class='wordsrotator_wordIn'>" + array[listItem] + "</span>").appendTo(cont);
cont.wrapInner("<span class='wordsrotator_words' />");
cont.find(".wordsrotator_wordOut").addClass("animated " + settings.animationOut);
cont.find(".wordsrotator_wordIn").addClass("animated " + settings.animationIn);
settings.onRotate();//this callback will allow to change the speed
if (settings.autoLoop && !stopped) {
//using timeout instead of interval will allow to change the speed
t = setTimeout(function () {
rotate()
}, settings.speed, function () {
rotate()
});
if (settings.stopOnHover) {
cont.hover(function () {
window.clearTimeout(t)
}, function () {
t = setTimeout(rotate, settings.speed, rotate);
});
};
}
};
t = setTimeout(function () {
rotate()
}, settings.speed, function () {
rotate()
})
cont.on("click", function () {
if (settings.changeOnClick) {
rotate();
return false;
};
});
};
});
}
}(jQuery));
function eventFire(el, etype) {
if (el.fireEvent) {
el.fireEvent('on' + etype);
} else {
var evObj = document.createEvent('Events');
evObj.initEvent(etype, true, false);
el.dispatchEvent(evObj);
}
}
function erm() {
var cont = $("#myWords");
$(function () {
$("#myWords").wordsrotator({
animationIn: "fadeOutIn", //css class for entrace animation
animationOut: "fadeOutDown", //css class for exit animation
randomize: true,
stopOnHover: true, //stop animation on hover
words: ['Heimerdinger', 'Ezreal', 'Skarner', 'Nunu', 'Kennen', 'Lulu', 'Morgana', 'Sejuani', 'Draven', 'Nocturne', 'KogMaw', 'Jinx', 'Khazix', 'Cassiopeia', 'Fiora', 'Maokai', 'Zac', 'Quinn', 'Vladimir', 'RekSai', 'LeeSin', 'TwistedFate', 'MissFortune', 'Shaco', 'Vayne', 'Sivir', 'Urgot', 'Nautilus', 'Annie', 'Fizz', 'Janna', 'Irelia', 'Karthus', 'Trundle', 'Jax', 'Graves', 'Leona', 'Rengar', 'Amumu', 'Malzahar', 'TahmKench', 'MasterYi', 'Twitch', 'Rumble', 'Nidalee', 'Shyvana', 'Veigar', 'Singed', 'Riven', 'Leblanc', 'Katarina', 'Azir', 'Viktor', 'Poppy', 'Ahri', 'Yorick', 'Aatrox', 'Brand', 'Tryndamere', 'DrMundo', 'Hecarim', 'Braum', 'Nasus', 'Pantheon', 'Elise', 'Velkoz', 'Swain', 'Darius', 'Kayle', 'Thresh', 'Nami', 'Ekko', 'Alistar', 'Galio', 'Warwick', 'Orianna', 'Sona', 'Lux', 'Ryze', 'Jayce', 'Kassadin', 'Volibear', 'Blitzcrank', 'Gangplank', 'Karma', 'XinZhao', 'Ziggs', 'Malphite', 'Tristana', 'Soraka', 'Anivia', 'Xerath', 'Renekton', 'Shen', 'Lissandra', 'Ashe', 'Mordekaiser', 'Talon', 'Zilean', 'JarvanIV', 'Rammus', 'Yasuo', 'Vi', 'Bard', 'Sion', 'Udyr', 'MonkeyKing', 'Akali', 'Diana', 'Varus', 'Kalista', 'Evelynn', 'Teemo', 'Gnar', 'Garen', 'Taric', 'FiddleSticks', 'Chogath', 'Zed', 'Lucian', 'Caitlyn', 'Corki', 'Zyra', 'Syndra', 'Gragas', 'Olaf'],
onRotate: function () {
//on each rotate you make the timeout longer, until it's slow enough
if (this.speed < 600) {
this.speed += 20;
} else {
this.stopRotate();
}
}
});
});
eventFire(document.getElementById('myWords'), 'click');
}
#charset"utf-8";
.wordsrotator_words {
display: inline-block;
position: relative;
white-space:nowrap;
-webkit-transition: width 100ms;
-moz-transition: width 100ms;
-o-transition: width 100ms;
transition: width 100ms;
}
.wordsrotator_words .wordsrotator_wordOut, .wordsrotator_words .wordsrotator_wordIn {
position: relative;
display: inline-block;
-webkit-animation-duration: 50ms;
-webkit-animation-timing-function: ease;
-webkit-animation-fill-mode: both;
-moz-animation-duration: 50ms;
-moz-animation-timing-function: ease;
-moz-animation-fill-mode: both;
-ms-animation-duration: 50ms;
-ms-animation-timing-function: ease;
-ms-animation-fill-mode: both;
}
.wordsrotator_words .wordsrotator_wordOut {
left: 0;
top: 0;
position: absolute;
display: inline-block;
}
.wordsrotator_words .wordsrotator_wordOut span {
width: auto;
position: relative;
}
.wordsrotator_words .wordsrotator_wordIn {
opacity: 0;
}
#-webkit-keyframes fadeInDown {
0% {
opacity: 0;
-webkit-transform: translateY(-20px);
transform: translateY(-20px);
}
100% {
opacity: 1;
-webkit-transform: translateY(0);
transform: translateY(0);
}
}
#keyframes fadeInDown {
0% {
opacity: 0;
-webkit-transform: translateY(-20px);
-ms-transform: translateY(-20px);
transform: translateY(-20px);
}
100% {
opacity: 1;
-webkit-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
}
}
.fadeInDown {
-webkit-animation-name: fadeInDown;
animation-name: fadeInDown;
}
#-webkit-keyframes fadeOutDown {
0% {
opacity: 1;
-webkit-transform: translateY(0);
transform: translateY(0);
}
100% {
opacity: 1;
-webkit-transform: translateY(20px);
transform: translateY(20px);
}
}
#keyframes fadeOutDown {
0% {
opacity: 1;
-webkit-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
}
100% {
opacity: 1;
-webkit-transform: translateY(20px);
-ms-transform: translateY(20px);
transform: translateY(20px);
}
}
.fadeOutDown {
-webkit-animation-name: fadeOutDown;
animation-name: fadeOutDown;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="container">
<p><span id="myWords"></span>
</p>
<div class="main"> Go!
</div>
</div>

Creating a simple, full-width, infinite carousel with jQuery

I'm creating a slider with jquery. I've looked on line if I could use any of the already made plugins, but none could do what I need to.
On a site I'm working on, I have a 1260px container where the content is.
The slider is fullwidth, and in the center is the active slide, and on the sides are previous and next slides that should serve as a previous and next click.
I plan to expand on that slider so that I have thumbnails beneath it, but for now I need to make the slider working.
HTML is (the images are 1260x520px)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Simple Fullwidth Slider</title>
<link rel="stylesheet" href="style.css" type="text/css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="init.js"></script>
</head>
<body>
<div class="slider clearfix" data-autoplay="0" data-items="1" data-easing="linear" data-duration="750" data-height="520">
<div class=" single_slide" style="height: 520px; background-image: url('image.jpg'); background-size: cover; background-position: 0% 0%; background-repeat: no-repeat;">
<div class="slider_text">
</div>
</div>
<div class="single_slide active" style="height: 520px; background-image: url('image.jpg'); background-size: cover; background-position: 0% 0%; background-repeat: no-repeat;">
<div class="slider_text">
</div>
</div>
<div class=" single_slide" style="height: 520px; background-image: url('image.jpg'); background-size: cover; background-position: 0% 0%; background-repeat: no-repeat;">
<div class="slider_text">
</div>
</div>
<div class=" single_slide" style="height: 520px; background-image: url('image.jpg'); background-size: cover; background-position: 0% 0%; background-repeat: no-repeat;">
<div class="slider_text">
</div>
</div>
<div class=" single_slide" style="height: 520px; background-image: url('image.jpg'); background-size: cover; background-position: 0% 0%; background-repeat: no-repeat;">
<div class="slider_text">
</div>
</div>
</div>
</body>
</html>
Style css is:
/***************** Image Slider ****************/
.slider{
list-style: none;
display: block;
width: 100%;
overflow: hidden;
position: relative;
}
.slider .single_slide{
float: left;
display: block;
margin: 0;
padding: 0;
border-radius: 0px;
overflow: hidden;
opacity: 0.15;
width: 1260px;
cursor: pointer;
-webkit-transition: opacity 800ms ease-in-out;
transition: opacity 800ms ease-in-out;
}
.slider .single_slide.active{
opacity: 1;
cursor: default;
-webkit-transition: opacity 800ms ease-in-out;
transition: opacity 800ms ease-in-out;
}
jQuery code:
jQuery(document).ready(function($) {
$('.slider').each(function () {
var $slider = $(this);
var autoplay = $slider.data("autoplay");
var items = $slider.data("items");
var easing = $slider.data("easing");
var duration = $slider.data("duration");
var $single_slide = $slider.find('.single_slide');
var slider_height = $single_slide.css('height', $slider.data('height')+'px');
var left_offset = ($(window).width()-1260)/2;
$slider.css({'width' : $single_slide.length*1260+'px', 'left':- 1260+left_offset + 'px'});
$single_slide.eq(1).addClass('active');
var $prev = $('.active').prev();
var $next = $('.active').next();
function moveLeft() {
var $a = $('.active');
$a.removeClass('active').prev().addClass('active');
$slider.animate({
left: parseInt($slider.css('left'), 10) + $single_slide.outerWidth(true),
easing: easing,
step: items,
}, duration, function () {
$('.single_slide:first').before($('single_slide:last'));
});
}
function moveRight() {
var $a = $('.active');
$a.removeClass('active').next().addClass('active');
$slider.animate({
left: parseInt($slider.css('left'), 10) - $single_slide.outerWidth(true),
easing: easing,
step: items,
}, duration, function () {
$('.single_slide:last').after($('single_slide:first'));
});
}
$prev.click(function () {
moveLeft();
});
$next.click(function () {
moveRight();
});
if (autoplay == 1) {
setInterval(function () {
moveRight();
}, duration);
}
});
});
I've created a git repository as well, so you can download the html files.
I'm originally doing this for wordpress, but the workings is the same.
The problem is that it doesn't seem like the appending of the images once you click previous or next images works. Switching of the classes works, but the next and previous images are not changing when you click on them (I've done something similar but the prev/next buttons were fixed elements, so I could just target them all the time, but here they are changing)-
I think I got to the root of the issue with the previous and next selectors. They got cached once as a variable but were never updated when the active class changes to another slide - so the event listeners would stick to the elements that were initially set as siblings of the active slide :
var $prev = $('.active').prev();
var $next = $('.active').next();
Unfortunately this doesn't seem to work :
$('.active').prev().click(function() { ... });
But this almost does the trick :
$('.slider').find($('.single_slide').eq($('.active').index()+2)).click(function() {
moveLeft();
});
$('.slider').find($('.single_slide').eq($('.active').index()-1)).click(function() {
moveRight();
});
Update - made functional and infinite with the .detach() method and a delegated event listener :
http://codepen.io/anon/pen/aOoPgZ?editors=001
$('.slider').each(function() {
var slider = $(this);
var autoplay = slider.data('autoplay');
var items = slider.data('items');
var easing = slider.data('easing');
var duration = slider.data('duration');
var single_slide = slider.find('.single_slide');
var slider_height = single_slide.css('height', slider.data('height'));
var offset = ($(window).width()-1260)/2-1260;
$.each(single_slide, function(index) {
if (index == 0) $(this).addClass('img' + single_slide.length);
else $(this).addClass('img' + index);
});
slider.css({'width': single_slide.length*1260, 'left': offset});
single_slide
.eq(0).addClass('prev').end()
.eq(1).addClass('active').end()
.eq(2).addClass('next');
function moveLeft() {
$('.active').removeClass('active').prev().addClass('active');
slider.animate({
left: slider.position().left+single_slide.outerWidth(true),
easing: easing,
step: items
}, duration, function() {
$('.single_slide:last').detach().prependTo(slider);
slider.css('left', offset);
newNav();
});
}
function moveRight() {
$('.active').removeClass('active').next().addClass('active');
slider.animate({
left: slider.position().left-single_slide.outerWidth(true),
easing: easing,
step: items
}, duration, function() {
$('.single_slide:first').detach().appendTo(slider);
slider.css('left', offset);
newNav();
});
}
function newNav() {
$('.prev').removeClass('prev');
$('.next').removeClass('next');
$('.single_slide')
.eq(0).addClass('prev').end()
.eq(2).addClass('next');
}
$(document).on('click', '.prev', function() {
moveLeft();
});
$(document).on('click', '.next', function() {
moveRight();
});
if (autoplay == 1) {
setInterval(function() {
moveRight();
}, duration);
}
});
I'm sure there's room for some optimisation but it seems to do the trick. Has a feature to keep track of the images that may not be needed (but it's handy for debugging).
Now for some swipe support. :-D

Categories