Setting Image Transition after Loading w/ JavaScript - 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.

Related

Glitch (content jumping) with parallax scrolling

I'm working on an animation for a site and I've gotten a glitch that I can not find a solution to. I update a 's translateY based on scroll connected to an eventListener on "scroll". The issue is that the is jumping and not behaving as expected. It works sometimes and almost all the time in Safari. The issue is always present in Firefox. I created a Codepen here.
I've tried exchange translateY to top, margin-top and padding-top. I've also tried exchange Grid to Flex and even Float. I've also tried to throttle the scroll event with lodash throttle.
If you can't see the issue, I can provide a video.
Basically, here is the JS:
const move_content = (leader, follower) => {
console.log(leader.getBoundingClientRect().top);
let margin_top = 0;
if (0 > leader.getBoundingClientRect().top) {
const pixels_scrolled = leader.getBoundingClientRect().top * -1;
const pixels_scrolled_with_viewport =
pixels_scrolled +
(window.innerHeight * pixels_scrolled) / leader.offsetHeight;
let percentage_scrolled =
pixels_scrolled_with_viewport / leader.offsetHeight;
if (1 <= percentage_scrolled) {
percentage_scrolled = 1;
}
const max_margin_pixels = leader.offsetHeight - follower.offsetHeight;
margin_top =
Math.round(max_margin_pixels * percentage_scrolled * 100) / 100;
}
follower.style.transform = "translateY(" + margin_top + "px)";
};
const syncronized_scroll = () => {
const content = document.querySelector(".test > div:first-child");
const reads = document.querySelector(".test > div:last-child");
if (content.offsetHeight > reads.offsetHeight) {
move_content(content, reads);
} else {
move_content(reads, content);
}
};
window.addEventListener("scroll", syncronized_scroll);

JavaScript - Restart setTimeout timer in a recursive function

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>

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)'
// ...
// ...
})

Using animate.css (link in description) how do I trigger an animation when a particular event is finished

I have an an image moving across the screen and out of viewport, when the image reaches a particular absolute position (right: - 200), I want to trigger the below animation. I am relatively new to programming, not sure how to track when a particular function is done so that I can trigger the below animation.
var $startLessonButton = $('.startLessonButtonUp');
$startLessonButton.mouseup(function() {
$(this).addClass('animated slideInLeft');
});
---------
var movingOutAnimationCounter = 2;
var movingOutCurrentPosition = window.innerWidth / 2 - 200
function moveTrumpOut() {
movingOutCurrentPosition -= 2;
trumpyWrapper.style.right = movingOutCurrentPosition + 'px';
if (movingOutAnimationCounter < 9 ) {
trumpy.src = '../images/trump_walking_out_' + movingOutAnimationCounter + '.png';
movingOutAnimationCounter += 1;
} else {
movingOutAnimationCounter = 1;
trumpy.src = '../images/trump_walking_out_' + movingOutAnimationCounter + '.png';
}
if (movingOutCurrentPosition > -200 ) {
requestAnimationFrame(moveTrumpOut);
}
}
All the best!
If you know time, when moving element is hidden, you can use this function:
setTimeout(function(){ $('.elem').addClass("animCssClass") }, 1000);
Last parameter, in this example: 1000 is time in ms, when function inside should execute. Run this function on mouseup when you adding class to moving element.

Changing pictures with changing opacity

I have built a code which change pictures every 5 second using setinterval() and everytime when a picture is changes, it will show up with it's opacity growing from 0 to 1, using setinterval() as well.
It all works excellently, but there is a single problem which I can find the way to fix it. The problem is that after I start the page, if I move to a differend tab, if I come back in a minute, it all goes craze and the opacity is growing too fast and more then once before a picture is changed.
Here is the code:
var images = [], x = 0, t = 0, timerid, s = 0;
images[0] = "Images/" + location.pathname.substring(1, location.pathname.length - 5) + "2.jpg";
images[1] = "Images/" + location.pathname.substring(1, location.pathname.length - 5) + ".jpg";
function ChangeOpacity() {
img = document.getElementById("img");
s += 0.003;
t = s.toString();
img.style.opacity = t;
if (img.style.opacity>=1) {
s = 0;
clearInterval(timerid);
}
}
function SwitchImage() {
img = document.getElementById("img");
img.src = images[x];
img.style.opacity = 0;
timerid = setInterval('ChangeOpacity()', 1);
x++;
if (x >= images.length)
x = 0;
}
function StartFun() {
setInterval('SwitchImage()', 5000);
}
You could add a window.onblur and window.onfocus function. Each time the tab loses focus (onblur) you could clear the interval and restart it when the tab gets focused again (onfocus).
More about focus on tabs
Edit:
Restarting the interval is not necessary in all cases.

Categories

Resources