I am currently building a website and want to fade several words at certain interval and certain fading time with infinite loop. This is exactly what I'm trying to achieve:
I've come up with this but don't know how to extend the time each word is displayed independently of fading time, so that it looks like on gif.
var text = ['fade1', 'fade2', 'fade3'];
var counter = 0;
var elem = document.getElementById("fade");
function change() {
jQuery(elem).fadeTo(1400, 0, function() {
this.innerHTML = text[counter];
counter = ++counter % text.length;
jQuery(this).fadeTo(1400, 1, change)
})
}
change()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Text <span id="fade"></span></p>
You can use jQuery.delay to pause the code for a certain number of milliseconds before moving to the next one:
var timeOnEachText = 2000; // Milliseconds to spend on each before moving to next
var text = ['fade1', 'fade2', 'fade3'];
var counter = 0;
var elem = document.getElementById("fade");
function change() {
jQuery(elem).delay(timeOnEachText).fadeTo(1400, 0, function() {
this.innerHTML = text[counter];
counter = ++counter % text.length;
jQuery(this).fadeTo(1400, 1, change)
})
}
change()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Text <span id="fade"></span></p>
If you just want to change the interval, you could convert your text array to an array-object and add some values to it, like this:
var text = [
{
text: 'fade1',
fadeIn: 1000,
fadeOut: 500,
timeout: 100,
},
{
text: 'fade2',
fadeIn: 1100,
fadeOut: 1500,
timeout: 1000,
},
{
text: 'fade3',
fadeIn: 500,
fadeOut: 300,
timeout: 3000,
}
];
var counter = 0;
var fadeTimeout = 0;
var elem = document.getElementById("fade");
function change() {
var currentTextItem = text[counter];
setTimeout( () => {
jQuery(elem).fadeTo(currentTextItem.fadeIn, 0, function() {
this.innerHTML = currentTextItem.text;
counter = ++counter % text.length;
jQuery(this).fadeTo(currentTextItem.fadeOut, 1, change)
});
// Set new timeout because in this set up the next item
// controls the timeout of the previous one.
fadeTimeout = currentTextItem.timeout;
}, fadeTimeout );
}
change()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Text <span id="fade">initial text</span></p>
I don't know if it'll work for you but have you thought about using #keyframes and just hiding showing the images at different intervals? If you know what the data is before hand and the number of images, you can set up key frames and it'll display much nicer.
Related
What would be the best way to have an array of background images and loop through them using js/jquery in an infinite loop?
this is what I have so far:
//ANIMATE JUMBOTRON BACKGROUND IMAGE
$(document).ready(function() {
var backgroundImage = [
'url(/static/images/slideshow/slide0.jpg)',
'url(/static/images/slideshow/slide1.jpg)',
'url(/static/images/slideshow/slide2.jpg)',
'url(/static/images/slideshow/slide3.jpg)',
'url(/static/images/slideshow/slide4.jpg)'
];
$('.jumbotron').css('background-image', backgroundImage[0]);
})
this is obviously just the array and simple css, but I am a bit lost on how to loop through the array?
A counter variable and a window.setInterval should do you. Increment the counter every time the interval'd function runs - once you hit the length of the background image array reset it back down to 0.
var backgroundImages = [
'url(/static/images/slideshow/slide0.jpg)',
'url(/static/images/slideshow/slide1.jpg)',
'url(/static/images/slideshow/slide2.jpg)',
'url(/static/images/slideshow/slide3.jpg)',
'url(/static/images/slideshow/slide4.jpg)'
],
backgroundImageCounter = 0,
jumbotron = $('.jumbotron');
window.setInterval(function() {
jumbotron.css('background-image', backgroundImages[backgroundImageCounter]);
backgroundImageCounter++;
if(backgroundImageCounter >= backgroundImages.length) {
backgroundImageCounter = 0;
}
}, 5000);
There is this thing called setInterval.
var count = 0;
var div = document.getElementById('a');
var btn = document.getElementById('b');
var interval = setInterval(function(){
div.innerText = count;
count++;
}, 1000);
btn.addEventListener('click', function(){
clearInterval(interval);
});
<div id="a">0</div>
<button id="b">Stop</button>
I am trying to make a simple 'Simon Game'. I am currently stuck trying to add a class 'on' to a div for one second, then remove that class for the same amount of time.
So I have four divs that I am blinking on and off depending on a sequence of numbers, e.g. [0, 1, 2, 3]. This would blink div[0] on for one second and off for one second then move to div[1], on and off and so on.
Here is my function
/**
* sequence => array [0, 1, 2, 3]
* speed => int 1000 (one second)
*/
playSequence: function(sequence, speed){
var self = this;
// removes class 'on'
view.turnOffPads();
setTimeout(function(){
// adds the 'on' class to a specific div
view.lightUpPad(model.startupSequence[model.count]);
}, speed / 2);
setTimeout(function(){
model.count++; // keeps track of the iterations
if (model.count < sequence.length) { // if we are still iterating
self.playSequence(sequence, speed); // light up the next div
} else {
model.count = 0; // set back to zero
}
}, speed);
},
The problem with this is that I am using two setTimeout functions with one another and although it works I am wondering if there is a better way. If you look I am using a count variable in my model object to keep track of iterations.
Here is my full javascript app so far...
$(function(){
var model = {
on: false,
strictMode: false,
startupSequence: [0, 1, 2, 3, 3, 3, 2, 1, 0, 3, 2, 1, 0, 2, 1, 3],
score: 0,
sequence: [],
count: 0,
}
var controller = {
init: function(){
view.cacheDOM();
view.bindEvents();
},
getSequence: function(){
// get a random number from one to 4
var random = Math.floor(Math.random() * 4);
// push it to the sequence array
model.sequence.push(random);
console.log(model.sequence);
// play it
this.playSequence(model.sequence);
},
/**
* sequence => array [0, 1, 2, 3]
* speed => int 1000 (one second)
*/
playSequence: function(sequence, speed){
console.log(sequence.length);
var self = this;
view.turnOffPads();
setTimeout(function(){
view.lightUpPad(model.startupSequence[model.count]);
}, speed / 2);
setTimeout(function(){
model.count++;
if (model.count < sequence.length) {
self.playSequence(sequence, speed);
} else {
model.count = 0;
}
}, speed);
// view.turnOffPads();
},
}
var view = {
cacheDOM: function(){
this.$round = $('#round');
this.$start = $('#start');
this.$strict = $('#strict');
this.$pad = $('.pad');
this.$padArray = document.getElementsByClassName('pad');
},
bindEvents: function(){
this.$start .change(this.start.bind(this));
this.$strict.change(this.setStrictMode.bind(this));
},
start: function(){
// turn on pads
if (model.on) {
this.$pad.removeClass('on');
this.$round.text('--');
model.on = false;
// reset everything
} else {
this.$round.text(model.score);
model.on = true;
controller.playSequence(model.startupSequence, 100)
// controller.getSequence();
}
},
lightUpPad: function(i){
$(this.$padArray[i]).addClass('on');
},
turnOffPads: function(){
this.$pad.removeClass('on');
},
setStrictMode: function(){
if (model.strictMode) {
model.strictMode = false;
} else {
model.strictMode = true;
}
}
}
controller.init();
});
Is there a cleaner way to add a class, and then remove a class?
Use setInterval instead of setTimeout I have created four divison and blink each division for 1 sec.
var i = 0,
j = 4;
function blink(i) {
new Promise(function(resolve, reject) {
x = setTimeout(function() {
document.querySelectorAll(".post-text")[i].classList.add("myClass");
resolve("added");
}, 1000)
}).then(function(a) {
new Promise(function(res, rej) {
setTimeout(function() {
clearInterval(x);
document.querySelectorAll(".post-text")[i].classList.remove("myClass");
res("deleted");
}, 1000)
}).then(function(a) {
i++;
if (i < j) {
blink(i);
} else {
i = 0;
blink(i);
}
});
});
}
blink(i);
.myClass {
background-color:yellow;
}
<div class="post-text">A</div>
<div class="post-text">B</div>
<div class="post-text">C</div>
<div class="post-text">D</div>
I think you could turn a list of buttons into a sequence of commands. Then you could use a single setInterval to play commands until it runs out of commands. The setInterval could use 1 second intervals if you want on and off to take just as long, but you could also set it to a little faster to easily allow for different durations.
The example below isn't really based on your code, but just to illustrate the idea. It starts (at the button of the code) with an array of buttons pressed. Those are passed to getSequence. This will return an array of commands, in this case simply the color of the button to switch on, so a sequence could be red,red,red,red,'','','','' to have red light up for 4 'intervals', and then switch it off for 4 'intervals'. This way you could create complicates sequences, and with minor adjustments you could even light up multiple buttons simultaneously.
The interval in the example is set to 1/10 of a second. Each color plays for 10 steps (= 1 second), and each pause plays for 5 steps (= .5 second). In the console you see the basis array of buttons/colors to play, followed by the more elaborate sequence that is played.
// The play function plays a sequence of commands
function play(sequence) {
var index = 0;
var lastid = '';
var timer = setInterval(function(){
// End the timer when at the end of the array
if (++index >= sequence.length) {
clearInterval(timer);
return;
}
var newid = sequence[index];
if (lastid != newid) {
// Something has changed. Check and act.
if (lastid != '') {
// The last id was set, so lets switch that off first.
document.getElementById(lastid).classList.remove('on');
console.log('--- ' + lastid + ' off');
}
if (newid != '') {
// New id is set, switch it on
document.getElementById(newid).classList.add('on');
console.log('+++ ' + newid + ' on');
}
lastid = newid;
}
}, 100);
}
// generateSequence takes a list of buttons and converts them to a
// sequence of color/off commands.
function generateSequence(buttons) {
var result = [];
for (var b = 0; b < buttons.length; b++) {
// 'On' for 10 counts
for (var i = 0; i < 10; i++) {
result.push(buttons[b]);
}
if (b+1 < buttons.length) {
// 'Off' for 5 counts
for (var i = 0; i < 5; i++) {
result.push('');
}
}
}
// One 'off' at the end
result.push('');
return result;
}
var buttons = ['red', 'green', 'red', 'yellow', 'yellow', 'blue'];
console.log(buttons);
var sequence = generateSequence(buttons);
console.log(sequence);
play(sequence);
div.button {
width: 100px;
height: 100px;
opacity: .5;
display: inline-block;
}
div.button.on {
opacity: 1;
}
#red {
background-color: red;
}
#green {
background-color: green;
}
#yellow {
background-color: yellow;
}
#blue {
background-color: blue;
}
<div id="red" class="button"></div>
<div id="green" class="button"></div>
<div id="yellow" class="button"></div>
<div id="blue" class="button"></div>
TLDR ;)
All you need to do is to use setInterval() or setTimeout() and within the callback function use element.classList.toggle() to add or remove a class from the element.
If/when you want the blinking to stop, just use clearTimeout() or clearInterval().
Here's an example:
var d = document.getElementById("test");
var b = document.querySelector("button");
b.addEventListener("click", function(){
// Cancel the timer
clearTimeout(timer);
});
// Assign the timer's ID to a variable so that
// you can stop it later
var timer = setInterval(function(){
// Toggle the use of the lightUp class
test.classList.toggle("lightUp");
},1000);
#test {
width:100px;
height:100px;
background-color:blue; /* <-- blue will be the default color */
}
#test.lightUp {
background-color:yellow;
}
<div id="test"></div>
<button>Stop Blinking</button>
I have a bit of javascript/jquery I am trying to figure out. What I have already is three boxes that the content fades in and out and loops through the three and repeats. What I am trying to do is when "box x" is hovered over the loop fades out and stops never to start again, and the box that is hovered on, the content below the box fades in and stays... unless another box is hovered over, then the content that faded in from the other hovered box will fade out and the new box that was hovered on, the content that coincides with that box fades in and stays fade in, and so forth.
How would I go about doing this?
Here is a jsfiddle example: http://jsfiddle.net/q0htx0no/
javascript/jquery
var infoboxes = $(".count p");
var counter = 0;
function rotate() {
$(infoboxes[counter]).fadeIn(1000, function() {
setTimeout(function() {
$(infoboxes[counter]).fadeOut(1000, function() {
counter = counter < infoboxes.length - 1 ? counter + 1 : 0;
rotate();
})
}, 1000);
});
}
$(function() {
rotate();
});
Thanks for any help
One option would be to have a global variable (a 'flag') that would indicate if the rotation should be stopped. Once a box has been hovered over, it should set hovered to True and should fade in that specific box.
Yep, use a global variable. Something like this:
var infoboxes = $(".count p");
var counter = 0;
var goAhead = true;
function rotate() {
$(infoboxes[counter]).fadeIn(1000, function() {
setTimeout(function() {
$(infoboxes[counter]).fadeOut(1000, function() {
counter = counter < infoboxes.length - 1 ? counter + 1 : 0;
checkRotate();
})
}, 1000);
});
}
function checkRotate() {
if (goAhead) { rotate(); }
}
$('.about').on('mouseover', function() {
goAhead = false;
var index = $(this).index();
var boxesToClear = $(infoboxes).filter(function(i) { return i !== index; });
$(boxesToClear).fadeOut(1000, function() {
$(infoboxes[index]).fadeIn(1000);
});
});
checkRotate();
DEMO
Here's one way to do it. It can probably be improved.
http://jsfiddle.net/vbt67x0h/2/
var infoboxes = $(".count p");
var counter = 0;
var isrotating = false;
function rotate(){
isrotating = true;
$(infoboxes[counter]).fadeIn(1000).delay(1000).fadeOut(1000);
counter = counter < infoboxes.length - 1 ? counter + 1 : 0;
}
//immediately stop rotate and hide all
function stoprotate(){
clearInterval(tmrrotate);
isrotating = false;
for(var x=0;x<infoboxes.length;x++){
$(infoboxes[x]).stop();
$(infoboxes[x]).hide();
}
}
rotate();
//rotate every 3 seconds, 1 to fadein, 1 to pause, 1 to fadeout
var tmrrotate = setInterval(function() {
rotate();
}, 3000);
$(".about").on('mouseover', function() {
if(isrotating){stoprotate()}
$(infoboxes[$(this).index()]).fadeIn(1000);
})
.on('mouseleave', function() {
$(infoboxes[$(this).index()]).fadeOut(1000);
});
You should make a timed array:
var arTimer = [];
and push all timers into that array, clearTimeout on hover and show only hovered index:
var infoboxes = $(".count p");
var counter = 0;
var arTimer = [];
function rotate() {
$(infoboxes[counter]).fadeIn(1000, function() {
arTimer.push(setTimeout(function() {
$(infoboxes[counter]).fadeOut(1000, function() {
counter = counter < infoboxes.length - 1 ? counter + 1 : 0;
rotate();
})
}, 1000));
});
}
function cleararTimer(){
for (var i = 0; i < arTimer.length; i++) {
clearTimeout(arTimer[i]);
}
}
$(function() {
rotate();
$('.about').on('mouseover', function(){
cleararTimer();
var hovered = $(this).index();
$('.count p').not(':eq('+hovered+')').fadeOut(1000);
$('.count p:eq('+hovered+')').fadeIn(1000);
});
});
jsFiddle Example
I have almost finished this slider, but I don't know how to implement the functionality for next() and prev(). How can I implement these functions?
http://jsfiddle.net/M4t4L/11/
$(function () {
var container = $("#scene"),
i = 0,
count = container.find("li").length,
j = container.find("li").length - 1,
isAnimating = false;
container.find("li:first").css({
"width": "100%"
});
$("#trigger").click(function (e) {
if (!isAnimating) {
isAnimating = true;
e.preventDefault(e);
i++; if (i >= count) { i = 0; }
j++; if (j >= count) { j = 0; }
container.find("li")
.finish()
.removeClass('active')
.last()
.width(0)
.addClass("active")
.animate({
"width": "100%"
}, 800,
function () {
container.find("li").first().appendTo(container);
isAnimating = false;
});
}
});
});
The problem is that when I implement these functions and press the next or prev. Displays the last slide on one second, and then switches to the desired
http://jsfiddle.net/M4t4L/9
If you want to get a Next or Prev function running, you want to take control of the number of the slider where you are. I'm afraid you will have to play around with your i/j and make the position go in both directions.
Right now you count up your i and j, where you might want to go is to have a position var and an array of slider objects, then the click only would have to call for the next/prev object to be loaded and the animation can begin.
Something like this maybe..
var pos = 0;
var container = $('#scene').find('li');
$('.back').click(function() {
pos = pos - 1;
moveIt(pos);
});
$('.forth').click(function() {
pos = pos +1;
moveIt(pos);
});
function moveIt(pos) {
container[pos]... // Your animation goes here
}
I'm trying to create div boxes step by step and animate them for several times when a button is pressed. I have a running code, and everything is going well. It goes right to the endhost, then it goes left again to its original place. This is mainly what I do, and also the demo is found here: http://jsfiddle.net/54hqm/3/
Now I want to happen after each click, is basically to move each DIV one after another, with a delay, instead of moving the whole stack of DIVs at once. I don't exactly know what to do. Can anyone help me with that?
$(document).ready(function () {
var count = 0;
var items = 0;
var packetNumber = 0;
var speed = 0;
$("button").click(function () {
if (count < 4) {
items = items + 1;
count++;
} else {
items = items * 2;
}
speed = $("#speed").val();
createDivs(items);
animateDivs();
});
function createDivs(divs) {
packetNumber = 1;
var left = 60;
for (var i = 0; i < divs; i++) {
var div = $("<div class='t'></div>");
div.appendTo(".packets");
$("<font class='span'>" + packetNumber + "</font>").appendTo(div);
packetNumber++;
div.css("left",left+"px");
div.hide();
left += 20;
}
}
function animateDivs() {
$(".t").each(function () {
var packet = $(this);
packet.show();
packet.animate({
left: '+=230px'
}, speed);
packet.animate({
left: '+=230px'
}, speed);
packet.animate({
top: '+=20px',
backgroundColor: "#f09090",
text: '12'
}, speed / 4, "swing", function () {
$('.span').fadeOut(100, function () {
$(this).text(function () {
return 'a' + $(this).text().replace('a', '');
}).fadeIn(100);
});
});
packet.delay(1000).animate({left:'-=230px'}, speed);
packet.animate({left:'-=230px'}, speed);
}).promise().done(function(){
$(".packets").empty();});
}
});
You can make this with 2 small modifications:
In your each() function, add the index parameter to know the index of the currently animating packet:
$(".t").each(function (index) {
Before your animate calls, insert a packet.delay() with a delay increasing with every item:
packet.delay(index * 250);
I updated your fiddle to show results.
Update: I made a second version based on your comment.