JavaScript - Restart setTimeout timer in a recursive function - javascript

I'm trying to make an automatic slideshow in css and js. I've got a function that infinitely loops through an array of images (in the slideshow) after a specified time.
function autoSlide(){
carouselSlide.style.transition = "transform 1s ease-in-out";
counter++;
carouselSlide.style.transform = 'translateX(' + (-size * counter) + 'px)';
t = setTimeout("autoSlide()", time);
}
But I want to reset the timer time if I manually change the slide by pressing a button. I tried this but it didn't work:
function autoSlide(){
carouselSlide.style.transition = "transform 1s ease-in-out";
counter++;
carouselSlide.style.transform = 'translateX(' + (-size * counter) + 'px)';
nextBtn.addEventListener('click',()=>{
clearTimeout(t);
})
t = setTimeout("autoSlide()", time);
}
Any help would be much appreciated.
Thanks.

Please use setInterval instead of setTimeout.
Like this:
function autoSlide(){
carouselSlide.style.transition = "transform 1s ease-in-out";
counter++;
carouselSlide.style.transform = 'translateX(' + (-size * counter) + 'px)';
}
var t = setInterval(autoSlide, time)
nextBtn.addEventListener('click',()=>{
clearInterval(t);
t= setInterval(autoSlide, time)
})

I don't see that you're defining the interval variable outside of the function scope so it might be getting lost. Also, shouldn't this be a setInterval vs setTimeout? You could use either, but if your goal is to infinitely repeat until some condition, setInterval is more appropriate
let interval = setInterval(autoSlide, time); // variable being initialized outside function scope
nextBtn.addEventListener('click',()=>{
clearInterval(interval);
interval = setInterval(autoSlide, time)
})
function autoSlide(){
carouselSlide.style.transition = "transform 1s ease-in-out";
counter++;
carouselSlide.style.transform = 'translateX(' + (-size * counter) + 'px)';
// ... presumably other logic to progress your slideshow every 'time'
}

One way to do it would be to recreate the timer when you click. Not only delete the timer, but also recreate it.
nextBtn.addEventListener('click',()=>{
clearTimeout(t);
t = setTimeout(autoSlide, time);
})
ps: it's always good to learn, but dont try too much to reinvent the wheel.
use this for exemple : https://owlcarousel2.github.io/OwlCarousel2/demos/basic.html
responseive, auto, touch support, etc...

If this is a carousel you want your timeout to be the same but to reset the counter when you click the button.
Here's a function that sets up your timer, and your button, and returns a closure (a function that retains the information in its preceding lexical environment after it's been returned) that controls the timeout.
function handler() {
const time = 1000;
let counter = 0;
const button = document.addEventListener('click', () => counter = 0);
return function loop() {
// Your transform code goes here
console.log(counter);
counter++;
setTimeout(loop, time);
}
}
// autoSlide is the returned function
const autoSlide = handler();
autoSlide();
<button>Stop the sliding!</button>

Related

Setting Image Transition after Loading w/ JavaScript

I have two functions, one loads the mobile images in and the other automatically translates the images after a set time. The problem is that the translate function is no longer working after moving all image loading to JavaScript instead of hard-coding it in the HTML (due to webpack asset management and the build process). Here is the site for reference: https://ecstatic-snyder-29f00e.netlify.app/
Load Mobile Images
function loadMobileImages() {
const mobileArr = [img1, img2, img3, img4];
const imgTags = document.querySelectorAll('.mobileBackground');
const lastClone = document.querySelector('#lastClone');
const firstClone = document.querySelector('#firstClone');
lastClone.src = img4;
firstClone.src = img1;
for (let i=0; i<imgTags.length; i++) {
imgTags[i].src = mobileArr[i];
};
return new Promise(function(resolve, reject) {
setTimeout(backgroundSlideShow, 100);
});
};
Start Slide Show
function backgroundSlideShow() {
const container = document.querySelector('#carousel-container');
const carouselImgs = document.querySelectorAll('.background');
const slideTime = 10000;
let counter = 1;
const size = carouselImgs[0].clientWidth;
container.style.transform = 'translateX(' + (-size * counter) + 'px)';
setInterval(function() {
if (counter >= carouselImgs.length - 1) {
return
};
container.style.transition = 'transform 0.4s ease-in-out';
counter++;
container.style.transform = 'translateX(' + (-size * counter) + 'px)';
}, slideTime);
container.addEventListener('transitionend', () => {
if (carouselImgs[counter].id === 'firstClone') {
container.style.transition = 'none';
counter = carouselImgs.length - counter;
container.style.transform = 'translateX(' + (-size * counter) + 'px)';
}
});
};
Both functions are being called, but the slideshow doesn't start until loading the page and then refreshing. Does anyone know what may be causing this type of behavior? I read that setting CSS w/ JavaScript can mess with how things load, but am not sure how to remedy this when images need to be set with JavaScript or CSS. Currently using a setTimout function to prolong the transition.
Loading in images with css solved the issue. Also gave a performance boost on load times.

Reset slider JavaScript upon window resize (NOT jQuery)

I do not want a jQuery solution.
The problem: When my page is resized, the slides in the slider are positioned incorrectly.
I'm open to any solution, but my guess is I need to reset the JS for my heroSlider upon window resizing.
Here's the JSfiddle https://jsfiddle.net/3ou0ja4c/
// HERO SLIDER
const heroSlider = () => {
const carouselSlide = document.querySelector('.carousel-slide')
let carouselImages = document.querySelectorAll('.carousel-slide .slide-bg')
// Buttons
const prevBtn = document.querySelector('#prevBtn')
const nextBtn = document.querySelector('#nextBtn')
// Timer
let interval = setInterval( () => rotateSlide(), 5000)
// Counter
let counter = 1
let size = carouselImages[0].clientWidth
carouselSlide.style.transform = 'translateX(' + (-size * counter ) + 'px)'
const rotateSlide = () => {
if (counter >= carouselImages.length -1) return
carouselSlide.style.transition = "transform 0.4s ease-in-out"
counter++
carouselSlide.style.transform = 'translateX(' + (-size * counter ) + 'px)'
}
// Button Listeners
nextBtn.addEventListener('click',() => {
clearInterval(interval)
rotateSlide()
})
prevBtn.addEventListener('click', () => {
if (counter <= 0) return
carouselSlide.style.transition = "transform 0.4s ease-in-out"
counter--
carouselSlide.style.transform = 'translateX(' + (-size * counter ) + 'px)'
clearInterval(interval)
})
carouselSlide.addEventListener('transitionend', () => {
// If image is a clone, jump to original image with no animation
if (carouselImages[counter].id === 'lastClone'){
carouselSlide.style.transition = "none"
counter = carouselImages.length - 2
carouselSlide.style.transform = 'translateX(' + (-size * counter ) + 'px)'
}
if (carouselImages[counter].id === 'firstClone'){
carouselSlide.style.transition = "none"
counter = carouselImages.length - counter
carouselSlide.style.transform = 'translateX(' + (-size * counter ) + 'px)'
}
})
}
heroSlider()
It doesn't look great on the fiddle, but you can still see it breaks upon being resized. It works on all window sizes, so long as you refresh the page, but I DO NOT want the page to refresh upon all resizes.
You can see the real deal over at http://www.justinkwapich.com/JH/index.html
Any help is really appreciated, thank you!
In your heroSlider() function you can add an event listener to check if the window is resized and create a callback where you update the size variable and anything else that depends on this size:
let counter = 1
let size = carouselImages[0].clientWidth
window.addEventListener('resize', () => {
size = carouselImages[0].clientWidth
carouselSlide.style.transform = 'translateX(' + (-size * counter ) + 'px)'
// ...
// ...
})

Javascript picture Transition [duplicate]

I want to make an HTML div tag fade in and fade out.
I have some code that fades out, but when I fade in, the opacity of the div stays at 0.1 and doesn't increase.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<title>Fade to Black</title>
<script type="text/javascript">
//<![CDATA[
function slidePanel(elementToSlide, slideSource)
{
var element = document.getElementById(elementToSlide);
if(element.up == null || element.up == false) {
setTimeout("fadeOut(\"" + elementToSlide + "\")", 100);
element.up = true;
slideSource.innerHTML = "Bring it down";
} else {
setTimeout("fadeIn(\"" + elementToSlide + "\")", 100);
element.up = false;
slideSource.innerHTML = "Take it up";
}
}
function fadeIn(elementToFade)
{
var element = document.getElementById(elementToFade);
element.style.opacity += 0.1;
if(element.style.opacity > 1.0) {
element.style.opacity = 1.0;
} else {
setTimeout("fadeIn(\"" + elementToFade + "\")", 100);
}
}
function fadeOut(elementToFade)
{
var element = document.getElementById(elementToFade);
element.style.opacity -= 0.1;
if(element.style.opacity < 0.0) {
element.style.opacity = 0.0;
} else {
setTimeout("fadeOut(\"" + elementToFade + "\")", 100);
}
}
//]]>
</script>
</head>
<body>
<div>
<div id="slideSource"
style="width:150px; height:20px;
text-align:center; background:green"
onclick="slidePanel('panel', this)">
Take It up
</div>
<div id="panel"
style="width:150px; height:130px;
text-align:center; background:red;
opacity:1.0;">
Contents
</div>
</div>
</body>
</html>
What am I doing wrong and what is the best way to fade in and fade out an element?
Here is a more efficient way of fading out an element:
function fade(element) {
var op = 1; // initial opacity
var timer = setInterval(function () {
if (op <= 0.1){
clearInterval(timer);
element.style.display = 'none';
}
element.style.opacity = op;
element.style.filter = 'alpha(opacity=' + op * 100 + ")";
op -= op * 0.1;
}, 50);
}
you can do the reverse for fade in
setInterval or setTimeout should not get a string as argument
google the evils of eval to know why
And here is a more efficient way of fading in an element.
function unfade(element) {
var op = 0.1; // initial opacity
element.style.display = 'block';
var timer = setInterval(function () {
if (op >= 1){
clearInterval(timer);
}
element.style.opacity = op;
element.style.filter = 'alpha(opacity=' + op * 100 + ")";
op += op * 0.1;
}, 10);
}
Here is a simplified running example of Seattle Ninja's solution.
var slideSource = document.getElementById('slideSource');
document.getElementById('handle').onclick = function () {
slideSource.classList.toggle('fade');
}
#slideSource {
opacity: 1;
transition: opacity 1s;
}
#slideSource.fade {
opacity: 0;
}
<button id="handle">Fade</button>
<div id="slideSource">Whatever you want here - images or text</div>
why do that to yourself?
jQuery:
$("#element").fadeOut();
$("#element").fadeIn();
I think that's easier.
www.jquery.com
Here's my attempt with Javascript and CSS3 animation
So the HTML:
<div id="handle">Fade</div>
<div id="slideSource">Whatever you want images or text here</div>
The CSS3 with transitions:
div#slideSource {
opacity:1;
-webkit-transition: opacity 3s;
-moz-transition: opacity 3s;
transition: opacity 3s;
}
div#slideSource.fade {
opacity:0;
}
The Javascript part. Check if the className exists, if it does then add the class and transitions.
document.getElementById('handle').onclick = function(){
if(slideSource.className){
document.getElementById('slideSource').className = '';
} else {
document.getElementById('slideSource').className = 'fade';
}
}
Just click and it will fade in and out. I would recommend using JQuery as Itai Sagi mentioned. I left out Opera and MS, so I would recommend using prefixr to add that in the css. This is my first time posting on stackoverflow but it should work fine.
Ok, I've worked it out
element.style.opacity = parseFloat(element.style.opacity) + 0.1;
Should be used instead of
element.style.opacity += 0.1;
Same with
element.style.opacity = parseFloat(element.style.opacity) - 0.1;
Instead of
element.style.opacity -= 0.1;
Because opacity value is stored as string, not as float. I'm still not sure though why the addition has worked.
I usually use these utility functions. element is the HTML element and duration is the desired duration in milliseconds.
export const fadeIn = (element, duration) => {
(function increment(value = 0) {
element.style.opacity = String(value);
if (element.style.opacity !== '1') {
setTimeout(() => {
increment(value + 0.1);
}, duration / 10);
}
})();
};
export const fadeOut = (element, duration) => {
(function decrement() {
(element.style.opacity -= 0.1) < 0 ? element.style.display = 'none' : setTimeout(() => {
decrement();
}, duration / 10);
})();
};
Heres my code for a fade in/out toggle functions.
fadeIn: function (len) {
var obj = this.e;
obj.style.display = '';
var op = 0;
var timer = setInterval(function () {
if (op >= 1 || op >= 1.0){
console.log('done', op)
clearInterval(timer);
}
obj.style.opacity = op.toFixed(1);
op += 0.1;
console.log(obj.style.opacity);
}, len);
return this;
},
fadeOut: function (len) {
var obj = this.e;
var op = 1;
var timer = setInterval(function () {
if (op <= 0){
clearInterval(timer);
console.log('done', op)
obj.style.display = 'none';
}
obj.style.opacity = op.toFixed(1);
op -= 0.1;
console.log(obj.style.opacity)
}, len);
return this;
},
This was from a jQuery style lib i did. hope it's helpfull. link to lib on cloud9:
https://c9.io/christopherdumas/magik_wb
I like Ibu's one but, I think I have a better solution using his idea.
//Fade In.
element.style.opacity = 0;
var Op1 = 0;
var Op2 = 1;
var foo1, foo2;
foo1 = setInterval(Timer1, 20);
function Timer1()
{
element.style.opacity = Op1;
Op1 = Op1 + .01;
console.log(Op1); //Option, but I recommend it for testing purposes.
if (Op1 > 1)
{
clearInterval(foo1);
foo2 = setInterval(Timer3, 20);
}
}
This solution uses a additional equation unlike Ibu's solution, which used a multiplicative equation. The way it works is it takes a time increment (t), an opacity increment (o), and a opacity limit (l) in the equation, which is: (T = time of fade in miliseconds) [T = (l/o)*t]. the "20" represents the time increments or intervals (t), the ".01" represents the opacity increments (o), and the 1 represents the opacity limit (l). When you plug the numbers in the equation you get 2000 milliseconds (or 2 seconds). Here is the console log:
0.01
0.02
0.03
0.04
0.05
0.060000000000000005
0.07
0.08
0.09
0.09999999999999999
0.10999999999999999
0.11999999999999998
0.12999999999999998
0.13999999999999999
0.15
0.16
0.17
0.18000000000000002
0.19000000000000003
0.20000000000000004
0.21000000000000005
0.22000000000000006
0.23000000000000007
0.24000000000000007
0.25000000000000006
0.26000000000000006
0.2700000000000001
0.2800000000000001
0.2900000000000001
0.3000000000000001
0.3100000000000001
0.3200000000000001
0.3300000000000001
0.34000000000000014
0.35000000000000014
0.36000000000000015
0.37000000000000016
0.38000000000000017
0.3900000000000002
0.4000000000000002
0.4100000000000002
0.4200000000000002
0.4300000000000002
0.4400000000000002
0.45000000000000023
0.46000000000000024
0.47000000000000025
0.48000000000000026
0.49000000000000027
0.5000000000000002
0.5100000000000002
0.5200000000000002
0.5300000000000002
0.5400000000000003
0.5500000000000003
0.5600000000000003
0.5700000000000003
0.5800000000000003
0.5900000000000003
0.6000000000000003
0.6100000000000003
0.6200000000000003
0.6300000000000003
0.6400000000000003
0.6500000000000004
0.6600000000000004
0.6700000000000004
0.6800000000000004
0.6900000000000004
0.7000000000000004
0.7100000000000004
0.7200000000000004
0.7300000000000004
0.7400000000000004
0.7500000000000004
0.7600000000000005
0.7700000000000005
0.7800000000000005
0.7900000000000005
0.8000000000000005
0.8100000000000005
0.8200000000000005
0.8300000000000005
0.8400000000000005
0.8500000000000005
0.8600000000000005
0.8700000000000006
0.8800000000000006
0.8900000000000006
0.9000000000000006
0.9100000000000006
0.9200000000000006
0.9300000000000006
0.9400000000000006
0.9500000000000006
0.9600000000000006
0.9700000000000006
0.9800000000000006
0.9900000000000007
1.0000000000000007
1.0100000000000007
Notice how the opacity follows the opacity increment amount of .01 just like in the code. If you use the code Ibu made,
//I made slight edits but keeped the ESSENTIAL stuff in it.
var op = 0.01; // initial opacity
var timer = setInterval(function () {
if (op >= 1){
clearInterval(timer);
}
element.style.opacity = op;
op += op * 0.1;
}, 20);
you will get these numbers (or something similar) in you console log. Here is what I got.
0.0101
0.010201
0.01030301
0.0104060401
0.010510100501
0.010615201506009999
0.0107213535210701
0.0108285670562808
0.010936852726843608
0.011046221254112044
0.011156683466653165
0.011268250301319695
0.011380932804332892
0.01149474213237622
0.011609689553699983
0.011725786449236983
0.011843044313729352
0.011961474756866645
0.012081089504435313
0.012201900399479666
0.012323919403474463
0.012447158597509207
0.0125716301834843
0.012697346485319142
0.012824319950172334
0.012952563149674056
0.013082088781170797
0.013212909668982505
0.01334503876567233
0.013478489153329052
0.013613274044862343
0.013749406785310966
0.013886900853164076
0.014025769861695717
0.014166027560312674
0.014307687835915801
0.01445076471427496
0.01459527236141771
0.014741225085031886
0.014888637335882205
0.015037523709241028
0.015187898946333437
0.01533977793579677
0.015493175715154739
0.015648107472306286
0.01580458854702935
0.015962634432499644
0.01612226077682464
0.016283483384592887
0.016446318218438817
0.016610781400623206
0.01677688921462944
0.016944658106775732
0.01711410468784349
0.017285245734721923
0.017458098192069144
0.017632679173989835
0.01780900596572973
0.01798709602538703
0.018166966985640902
0.01834863665549731
0.018532123022052285
0.018717444252272807
0.018904618694795535
0.01909366488174349
0.019284601530560927
0.019477447545866538
0.0196722220213252
0.019868944241538455
0.02006763368395384
0.02026831002079338
0.020470993121001313
0.020675703052211326
0.02088246008273344
0.021091284683560776
0.021302197530396385
0.02151521950570035
0.021730371700757353
0.021947675417764927
0.022167152171942577
0.022388823693662
0.022612711930598623
0.022838839049904608
0.023067227440403654
0.02329789971480769
0.023530878711955767
0.023766187499075324
0.024003849374066077
0.02424388786780674
0.024486326746484807
0.024731190013949654
0.024978501914089152
0.025228286933230044
0.025480569802562344
0.025735375500587968
0.025992729255593847
0.026252656548149785
0.026515183113631283
0.026780334944767597
0.027048138294215273
0.027318619677157426
0.027591805873929
0.02786772393266829
0.028146401171994972
0.028427865183714922
0.02871214383555207
0.02899926527390759
0.029289257926646668
0.029582150505913136
0.029877972010972267
0.030176751731081992
0.030478519248392812
0.03078330444087674
0.031091137485285508
0.031402048860138365
0.03171606934873975
0.03203323004222715
0.03235356234264942
0.03267709796607591
0.03300386894573667
0.03333390763519403
0.03366724671154597
0.03400391917866143
0.03434395837044805
0.03468739795415253
0.03503427193369406
0.035384614653031
0.035738460799561306
0.03609584540755692
0.03645680386163249
0.03682137190024882
0.03718958561925131
0.03756148147544382
0.03793709629019826
0.03831646725310024
0.038699631925631243
0.03908662824488755
0.039477494527336426
0.03987226947260979
0.040270992167335894
0.04067370208900925
0.04108043910989934
0.04149124350099834
0.04190615593600832
0.042325217495368404
0.04274846967032209
0.04317595436702531
0.04360771391069556
0.044043791049802515
0.04448422896030054
0.04492907124990354
0.04537836196240258
0.045832145582026605
0.04629046703784687
0.04675337170822534
0.047220905425307595
0.04769311447956067
0.04817004562435628
0.04865174608059984
0.04913826354140584
0.0496296461768199
0.0501259426385881
0.05062720206497398
0.05113347408562372
0.05164480882647996
0.05216125691474476
0.05268286948389221
0.053209698178731134
0.05374179516051845
0.05427921311212363
0.05482200524324487
0.05537022529567732
0.05592392754863409
0.056483166824120426
0.05704799849236163
0.05761847847728525
0.0581946632620581
0.05877660989467868
0.059364375993625464
0.05995801975356172
0.060557599951097336
0.06116317595060831
0.06177480771011439
0.06239255578721554
0.0630164813450877
0.06364664615853857
0.06428311262012396
0.0649259437463252
0.06557520318378844
0.06623095521562633
0.0668932647677826
0.06756219741546042
0.06823781938961503
0.06892019758351117
0.06960939955934628
0.07030549355493974
0.07100854849048914
0.07171863397539403
0.07243582031514798
0.07316017851829945
0.07389178030348245
0.07463069810651728
0.07537700508758245
0.07613077513845827
0.07689208288984285
0.07766100371874128
0.0784376137559287
0.07922198989348798
0.08001420979242287
0.0808143518903471
0.08162249540925057
0.08243872036334307
0.0832631075669765
0.08409573864264626
0.08493669602907272
0.08578606298936345
0.08664392361925709
0.08751036285544966
0.08838546648400417
0.08926932114884421
0.09016201436033265
0.09106363450393598
0.09197427084897535
0.0928940135574651
0.09382295369303975
0.09476118322997015
0.09570879506226986
0.09666588301289256
0.09763254184302148
0.0986088672614517
0.09959495593406621
0.10059090549340688
0.10159681454834095
0.10261278269382436
0.1036389105207626
0.10467529962597022
0.10572205262222992
0.10677927314845222
0.10784706587993674
0.10892553653873611
0.11001479190412347
0.1111149398231647
0.11222608922139635
0.11334835011361032
0.11448183361474643
0.11562665195089389
0.11678291847040283
0.11795074765510685
0.11913025513165793
0.1203215576829745
0.12152477325980425
0.12274002099240229
0.12396742120232632
0.12520709541434957
0.12645916636849308
0.127723758032178
0.12900099561249978
0.13029100556862477
0.13159391562431103
0.13290985478055414
0.1342389533283597
0.13558134286164328
0.1369371562902597
0.1383065278531623
0.13968959313169393
0.14108648906301088
0.142497353953641
0.1439223274931774
0.14536155076810917
0.14681516627579025
0.14828331793854815
0.14976615111793362
0.15126381262911295
0.15277645075540408
0.15430421526295812
0.1558472574155877
0.15740572998974356
0.158979787289641
0.1605695851625374
0.16217528101416276
0.16379703382430438
0.16543500416254742
0.1670893542041729
0.16876024774621462
0.17044785022367676
0.17215232872591352
0.17387385201317265
0.17561259053330439
0.17736871643863744
0.1791424036030238
0.18093382763905405
0.1827431659154446
0.18457059757459904
0.18641630355034502
0.1882804665858485
0.19016327125170698
0.19206490396422404
0.19398555300386627
0.19592540853390494
0.197884662619244
0.19986350924543644
0.20186214433789082
0.20388076578126973
0.20591957343908243
0.20797876917347324
0.21005855686520797
0.21215914243386005
0.21428073385819865
0.21642354119678064
0.21858777660874845
0.22077365437483593
0.2229813909185843
0.22521120482777013
0.22746331687604782
0.2297379500448083
0.23203532954525638
0.23435568284070896
0.23669923966911605
0.2390662320658072
0.24145689438646528
0.24387146333032994
0.24631017796363325
0.24877327974326957
0.25126101254070227
0.2537736226661093
0.2563113588927704
0.2588744724816981
0.26146321720651505
0.2640778493785802
0.266718627872366
0.26938581415108964
0.27207967229260055
0.27480046901552657
0.27754847370568186
0.28032395844273866
0.28312719802716607
0.28595847000743774
0.2888180547075121
0.2917062352545872
0.2946232976071331
0.2975695305832044
0.3005452258890364
0.3035506781479268
0.3065861849294061
0.3096520467787002
0.3127485672464872
0.31587605291895204
0.31903481344814155
0.322225161582623
0.3254474131984492
0.3287018873304337
0.33198890620373805
0.33530879526577545
0.3386618832184332
0.34204850205061754
0.3454689870711237
0.34892367694183496
0.35241291371125333
0.35593704284836586
0.3594964132768495
0.363091377409618
0.3667222911837142
0.3703895140955513
0.37409340923650686
0.37783434332887195
0.38161268676216065
0.38542881362978226
0.3892831017660801
0.3931759327837409
0.3971076921115783
0.40107876903269407
0.405089556723021
0.4091404522902512
0.4132318568131537
0.41736417538128523
0.4215378171350981
0.42575319530644906
0.43001072725951356
0.43431083453210867
0.43865394287742976
0.4430404823062041
0.44747088712926614
0.4519455960005588
0.45646505196056436
0.46102970248017
0.4656399995049717
0.47029639950002144
0.47499936349502164
0.47974935712997185
0.48454685070127157
0.4893923192082843
0.4942862424003671
0.4992291048243708
0.5042213958726145
0.5092636098313407
0.5143562459296541
0.5194998083889507
0.5246948064728402
0.5299417545375685
0.5352411720829442
0.5405935838037736
0.5459995196418114
0.5514595148382295
0.5569741099866118
0.5625438510864779
0.5681692895973427
0.5738509824933161
0.5795894923182493
0.5853853872414317
0.5912392411138461
0.5971516335249846
0.6031231498602344
0.6091543813588367
0.615245925172425
0.6213983844241493
0.6276123682683908
0.6338884919510748
0.6402273768705855
0.6466296506392913
0.6530959471456843
0.6596269066171412
0.6662231756833126
0.6728854074401457
0.6796142615145472
0.6864104041296927
0.6932745081709896
0.7002072532526995
0.7072093257852266
0.7142814190430788
0.7214242332335097
0.7286384755658448
0.7359248603215033
0.7432841089247183
0.7507169500139654
0.7582241195141051
0.7658063607092461
0.7734644243163386
0.7811990685595019
0.789011059245097
0.7969011698375479
0.8048701815359234
0.8129188833512826
0.8210480721847955
0.8292585529066434
0.8375511384357098
0.8459266498200669
0.8543859163182677
0.8629297754814503
0.8715590732362648
0.8802746639686274
0.8890774106083137
0.8979681847143969
0.9069478665615408
0.9160173452271562
0.9251775186794278
0.9344292938662221
0.9437735868048843
0.9532113226729332
0.9627434358996625
0.9723708702586591
0.9820945789612456
0.9919155247508581
1.0018346799983666
1.0118530267983503
Notice that there is no discernible pattern. If you ran Ibu's code, you would never know how long the fade was. You would have to grab a timer and guess and check 2 seconds. Nonetheless, Ibu's code did make a pretty nice fade in (it probably works for fade out. I don't know because I didn't use a fade out yet). My code will also work for a fade out. Let's just say you wanted 2 seconds for a fade out. You can do that with my code. Here is how it would look:
//Fade out. (Continued from the fade in.
function Timer2()
{
element.style.opacity = Op2;
Op2 = Op2 - .01;
console.log(Op2); //Option, but I recommend it for testing purposes.
if (Op2 < 0)
{
clearInterval(foo2);
}
}
All I did was change the opacity to 1 (or fully opaque). I changed the opacity increment to -.01 so it would start turning invisible. Lastly, I changed the opacity limit to 0. When it hits the opacity limit, the timer will stop. Same as the last one, except it used 1 instead of 0. When you run the code, here is what the console log should relatively look like.
.99
0.98
0.97
0.96
0.95
0.94
0.9299999999999999
0.9199999999999999
0.9099999999999999
0.8999999999999999
0.8899999999999999
0.8799999999999999
0.8699999999999999
0.8599999999999999
0.8499999999999999
0.8399999999999999
0.8299999999999998
0.8199999999999998
0.8099999999999998
0.7999999999999998
0.7899999999999998
0.7799999999999998
0.7699999999999998
0.7599999999999998
0.7499999999999998
0.7399999999999998
0.7299999999999998
0.7199999999999998
0.7099999999999997
0.6999999999999997
0.6899999999999997
0.6799999999999997
0.6699999999999997
0.6599999999999997
0.6499999999999997
0.6399999999999997
0.6299999999999997
0.6199999999999997
0.6099999999999997
0.5999999999999996
0.5899999999999996
0.5799999999999996
0.5699999999999996
0.5599999999999996
0.5499999999999996
0.5399999999999996
0.5299999999999996
0.5199999999999996
0.5099999999999996
0.49999999999999956
0.48999999999999955
0.47999999999999954
0.46999999999999953
0.4599999999999995
0.4499999999999995
0.4399999999999995
0.4299999999999995
0.4199999999999995
0.4099999999999995
0.39999999999999947
0.38999999999999946
0.37999999999999945
0.36999999999999944
0.35999999999999943
0.3499999999999994
0.3399999999999994
0.3299999999999994
0.3199999999999994
0.3099999999999994
0.2999999999999994
0.28999999999999937
0.27999999999999936
0.26999999999999935
0.25999999999999934
0.24999999999999933
0.23999999999999932
0.22999999999999932
0.2199999999999993
0.2099999999999993
0.1999999999999993
0.18999999999999928
0.17999999999999927
0.16999999999999926
0.15999999999999925
0.14999999999999925
0.13999999999999924
0.12999999999999923
0.11999999999999923
0.10999999999999924
0.09999999999999924
0.08999999999999925
0.07999999999999925
0.06999999999999926
0.059999999999999255
0.04999999999999925
0.03999999999999925
0.02999999999999925
0.019999999999999248
0.009999999999999247
-7.528699885739343e-16
-0.010000000000000753
As you can see, the .01 pattern still exists in the fade out. Both fades are smooth and precise. I hope these codes helped you or gave you insight on the topic. If you have any additions or suggestions let me know. Thank you for taking the time to view this!
I think i get the problem :
Once you make the div fade out you aren't exiting the function : fadeout calls itself again over even after opacity has become 0
if(element.style.opacity < 0.0) {
return;
}
And do the same for fadein too
let count=0;
let text = document.getElementById('heading');
let btn = document.getElementById('btn');
btn.addEventListener('click', function(){
if(count%2==0){
text.style.opacity="0.1";
unfade(text);
text.innerText="Welcome to Javascript </>";
text.style.color="forestgreen";
}//end of if
else{ text.style.opacity="0.1";
unfade(text);
text.innerText="Hello javascript";
text.style.color="blueviolet";
}//end of else
count++;//for toggling the text
});
//function for fade effect--------
function unfade(element) {
var op = 0.1; // initial opacity
element.style.display = 'block';
var timer = setInterval(function () {
if (op >= 1){
clearInterval(timer);
}
element.style.opacity = op;
element.style.filter = 'alpha(opacity=' + op * 100 + ")";
op += op * 0.1;
}, 30);
}
<h1 style="color:blueviolet" id="heading">Hello javascript</h1>
<button id="btn">Click me</button>
The following javascript will fade in an element from opacity 0 to whatever the opacity value was at the time of calling fade in. You can also set the duration of the animation which is nice:
function fadeIn(element) {
var duration = 0.5;
var interval = 10;//ms
var op = 0.0;
var iop = element.style.opacity;
var timer = setInterval(function () {
if (op >= iop) {
op = iop;
clearInterval(timer);
}
element.style.opacity = op;
op += iop/((1000/interval)*duration);
}, interval);
}
*Based on IBUs answer but modified to account for previous opacity value and ability to set duration, also removed irrelevant CSS changes it was making
My answer is based on Gb01's answer (thank you!). I wanted to abstract out the logic so that we could simply pass an element to a function and have that element fade toggle, fade in, or fade out.
POD
To use the code below:
Elements that can be faded should be given the fadeable class.
Fade in/out with fadeInElement(element) and fadeOutElement(element).
Turn fade on/off with toggle, toggleElementFade(element).
Improvements Over Gb01's answer
Bug Fix: Gb01's answer only worked because id-based CSS rules take precedence over class-based CSS rules, and if you removed #slideSource from #slideSource.fade, it would cease to work.
Bug Fix: Gb01's answer provides for when you start with the element displayed. What if you want to start with it hidden? Completely different code is required
Code: Elements Begin Being Displayed
function fadeInElement(element) {
element.classList.remove('fade');
}
function fadeOutElement(element) {
element.classList.add('fade');
}
function toggleElementFade(element) {
element.classList.toggle('fade');
}
document.getElementById('fade-toggle').onclick = function () {
toggleElementFade(document.getElementsByClassName('fadeable')[0]);
}
document.getElementById('fade-in').onclick = function () {
fadeInElement(document.getElementsByClassName('fadeable')[0]);
}
document.getElementById('fade-out').onclick = function () {
fadeOutElement(document.getElementsByClassName('fadeable')[0]);
}
.fadeable {
opacity: 1;
transition: opacity 1s;
}
.fade {
opacity: 0 !important;
}
<button id="fade-toggle">Fade Toggle</button>
<button id="fade-in">Fade In</button>
<button id="fade-out">Fade Out</button>
<div class="fadeable">Whatever you want here - images or text</div>
Code: Elements Begin Being Hidden
function fadeInElement(element) {
element.style.removeProperty('display');
setTimeout(function() {
element.classList.remove('fade');
}, 10);
}
function fadeOutElement(element) {
element.classList.add('fade');
}
function toggleElementFade(element) {
element.style.removeProperty('display');
setTimeout(function() {
element.classList.toggle('fade');
}, 10);
}
document.getElementById('fade-toggle').onclick = function () {
toggleElementFade(document.getElementsByClassName('fadeable')[0]);
}
document.getElementById('fade-in').onclick = function () {
fadeInElement(document.getElementsByClassName('fadeable')[0]);
}
document.getElementById('fade-out').onclick = function () {
fadeOutElement(document.getElementsByClassName('fadeable')[0]);
}
.fadeable {
opacity: 1;
transition: opacity 1s;
}
.fade {
opacity: 0 !important;
}
<button id="fade-toggle">Fade Toggle</button>
<button id="fade-in">Fade In</button>
<button id="fade-out">Fade Out</button>
<div class="fadeable fade" style="display:none;">Whatever you want here - images or text</div>
That was actually quite simple .
for ex: if you are hiding the text or changing it's color .
document.getElementById('availabletoday').style.color = '#f4f6f7';
make a css property like this
#availabletoday{
transition: 1s;
}
depending upon your event listener when the JavaScript executes it will transition in 1s . really easy to change the delay .
Let me know if this helps

Reduce setTimeout time relative to time left

I'm making a random "spinner" that loops through 8 divs and add a class active like this:
https://jsfiddle.net/9q1tf51g/
//create random setTimeout time from 3sec to 5sec
var time = Math.floor(Math.random() * (5000 - 3000 + 1)) + 3000;
var exit = false;
function repeat(){
//my code
if(!exit){
setTimeout(repeat, 50);
}
}
My problem is, I want the function repeat to end slowly, to create more suspense. I think I can do this by raising the 50 from the timeout but how can I do this accordingly to the time left?
Thanks in advance!
You can try this.
$('button').on('click', function(){
var time = Math.floor(Math.random() * (5000 - 3000 + 1)) + 3000;
var anCounter = 1;
var anState = "positive";
var exit = false;
//var time1 = 50000;
setInterval(function(){time = time-1000;}, 1000);
function repeat(){
if(anCounter>7 && anState=="positive"){ anState="negative"}
if(anCounter<2 && anState=="negative"){ anState="positive"}
$('div[data-id="'+anCounter+'"]').addClass('active');
$('div').not('div[data-id="'+anCounter+'"]').removeClass('active');
if(anState=="positive"){anCounter++;}else{anCounter--;}
if(!exit){
if(time <1000)
setTimeout(repeat, 300);
else if(time< 2000)
setTimeout(repeat, 100);
else setTimeout(repeat, 50);
}
}
repeat();
setTimeout(function(){
exit=true;
},time);
});
Once you know that you need to exit the flow (exit is true ) you can trigger some animation by creating a dorm linear serials of you code. Usually this animation should not last more than 2 sec.
You were kind of on the right track but it'd be easier to check the time you've passed by and increment accordingly at a fixed rate. I set it to increase by 50ms every iteration but you could change that to whatever you like.
Fiddle Demo
Javascript
$('button').on('click', function() {
var time = Math.floor(Math.random() * (5000 - 3000 + 1)) + 3000;
var anCounter = 1;
var anState = "positive";
var elapsed = 0;
var timer;
function repeat(timeAdded) {
if (anCounter > 7 && anState == "positive") {
anState = "negative"
}
if (anCounter < 2 && anState == "negative") {
anState = "positive"
}
$('div[data-id="' + anCounter + '"]').addClass('active');
$('div').not('div[data-id="' + anCounter + '"]').removeClass('active');
if (anState == "positive") {
anCounter++;
} else {
anCounter--;
}
if (elapsed < time) {
timer = setTimeout(function() {
repeat(timeAdded + 50);
}, timeAdded);
elapsed += timeAdded;
}
else {
clearTimeout(timer);
}
}
repeat(0);
});
You can add a parameter called intTime to your function repeat and inside that function you can adjust the next timeout and call the repeat function with the new timeout. each time it gets called it will take 20 ms longer. however you adjust the increment by changing the 20 in
var slowDown=20; to a different number.
var slowDown=20;
setTimeout ("repeat",50);
function repeat(intTime){
//my code
if(!exit){
intTime=Math.floor (intTime)+slowDown;
setTimeout(repeat(intTime), intTime);
}
}
And then you will need to create another timeout for the exit.
var time = Math.floor(Math.random() * (5000 - 3000 + 1)) + 3000;
var exit = false;
setTimeout ("stopSpinning",time);
function stopSpinning(){
exit = true;
}
so the whole thing should look something like this
var slowDown=20;
var time = Math.floor(Math.random() * (5000 - 3000 + 1)) + 3000;
var exit = false;
setTimeout ("stopSpinning",time);
setTimeout ("repeat",50);
function repeat(intTime){
//my code
if(!exit){
intTime=Math.floor (intTime)+20;
setTimeout(repeat(intTime), intTime);
}
}
function stopSpinning(){
exit = true;
}
Fiddle Demo
Linear deceleration: //values are just an example:
add a var slowDown = 0; inside the click event handler
add slowDown += 1; inside the repeat function
pass 50+slowDown to setTimeout
Curved deceleration:
add a var slowDown = 1;and a var curveIndex = 1.05 + Math.random() * (0.2); // [1.05-1.25)inside the click event handler
add slowDown *= curveIndex; inside the repeat function
pass 50+slowDown to setTimeout

Javascript: Why isn't my javascript running both animations?

I'm working on a video game for my project and i'm running into a animation problem. Basically i'm doing a Final Fantasy style game where your recharging your ATB bar and once its full, you can do a skill. So I have 3 functions here. The first one is clearing my ATB bar so that it resets. This code works. The second one is refilling the time-bar by moving a DIV block into place. This works as well. The third function is my attack skill function, which also works except for the fact that it does not do both of these animation functions in the order I placed them.
If you look below, you'll notice I have the code to first run the clear ATB function, and then run the time bar function, hoping that every time I click the button it would reset my ATB. The problem is, it completely ignores the FIRST function and runs the second one. I tried switching them and same thing occurs. So basically I'm stuck where my code will always ignore the first one and operate the 2nd one if both of my animation functions are in the code. So now I'm confused on how to fix this because I want BOTH codes to work. They work separately and independently as it stands now, but when I combine them, only the 2nd one registers.
// 5. ATB TIMEBAR FUNCTION
function clearTimeBar (el, color) { //Clears the bar
var elem = document.getElementById(el);
elem.style.transition = "width 0.0s, ease-in 0s";
elem.style.background = color;
elem.style.width = "0px"
}
function timeBar (el, color) { // Runs the animation
var elem = document.getElementById(el);
elem.style.transition = "width 6.0s, ease-in 0s";
elem.style.background = color;
elem.style.width = "289px";
}
// ATTACK SKILL
document.getElementById("attack").addEventListener('click', function(){
clearTimeBar('overlay','white'); // Clear the ATB bar
timeBar('overlay', 'blue'); // Run the ATB bar
var criticalRoll = Math.floor(Math.random() * 100 + 1);
var precisionRoll = Math.floor(Math.random() * cs.precision + 1);
var npcParryRoll = Math.floor(Math.random() * dragonstats.parry + 1);
var damage = Math.floor(Math.random() * cs.strength + 1);
if (precisionRoll < npcParryRoll) {
addMessage("The Dragon evaded your attack!");
return;
}
if (cs.critical >= criticalRoll) {
damage *= 2;
damage -= dragonstats.armor;
dragon.hp -= damage;
document.getElementById("npchp").innerHTML = dragon.hp;
addMessage("Critical Strike! Dragon suffers " + damage + " hp!")
}
else if (damage - dragonstats.armor <= 0) {
addMessage("Your opponents armor withstood your attack!");
}
else {
damage -= dragonstats.armor;
dragon.hp -= damage;
document.getElementById("npchp").innerHTML = dragon.hp;
addMessage("You hit the dragon for " + damage + " hp!");
}
});
Run your timeBar function after the clearTimeBar has completed taking place.
window.setTimeout(function() { timeBar('overlay', 'blue') }, 1000/60);
or
window.requestAnimationFrame(function() { timeBar('overlay', 'blue') });

Categories

Resources