I am attempting to make the fade in and out effect function properly in my slideshow

I've encountered an issue where the fading effect only occurs when the page initially loads and solely on the first image. Subsequently, the fading effect does not work on any other images displayed.

This is the CSS code I have implemented by adding it to

class="banner-items fade"
:

.fade {
  animation-name: fade;
  animation-duration: 1.5s;
}

@keyframes fade {
  from {opacity: .4}
  to {opacity: 1}
}

Additionally, I tried utilizing Svelte's transition:fade feature along with other techniques.

Here is the HTML component structure:

<div
    class="maestro-list"
    on:mouseenter={() => clearInterval(interval)} // pause and unpause
    on:mouseleave={() => {
        interval = setInterval(() => {
            current = (current + 1) % images.length
        }, delay)
    }}
>
    {#each images as image, index}
        <transition {index} {current} {delay}>
            <div class="banner-item">
                <span class="pic">
                    <img
                        src={image}
                        alt="dragon"
                        loading="lazy"
                        style="position:relative; display: {index === current ? 'block' : 'none'}"
                    />
                </span>
                <a class="banner_lnk" href="/">.</a>
            </div>
        </transition>
    {/each}
    <div class="num">
        {#each images as _, index}
            <span                      
                class="dot"
                tabindex="0"
                role="button"
                on:click={() => setcurrent(index)} //dot pagination
                class:active={index === current}
                on:keypress={(e) => {
                    if (e.key === "Enter") {
                        setcurrent(index)
                    }
                }}
            />
        {/each}
    </div>
</div>

TypeScript Script:

<script lang="ts">
    import { onMount, onDestroy } from "svelte"

    const images: string[] = ["/img-new-fixed.png", "/placeholder-9.png"]
    let current = 0
    let delay = 8000 // 8 seconds

    function setcurrent(index: number) {
        current = index
        clearInterval(interval)
        interval = setInterval(transition, delay)
    }

    function transition() {
        current = (current + 1) % images.length
    }

    let interval: NodeJS.Timeout

    onMount(() => {
        interval = setInterval(() => {
            current = (current + 1) % images.length
        }, delay)
    })

    onDestroy(() => {
        clearInterval(interval)
    })
</script>

One thing that comes to mind that I haven't explored yet is this example from Stack Overflow in the last answer given.

Furthermore, here's a reference where I drew inspiration for the Banner.

Answer №1

Check out this implementation using CSS Transitions and Svelte's class:directive

REPL

<script>
    import {urls} from './urls'
    import {onMount} from 'svelte'

    let index = 0
    let interval

    const start = () => interval = setInterval(() => index = (index + 1) % urls.length, 2500)
    const stop = () => clearInterval(interval)

    onMount(() => {
        start()
        return () => stop() //triggered when component is removed
    })

    function handleMarkerClick(i) {
        stop()
        index = i
    }
</script>

<div id="carousel">
    {#each urls as url, i}
    <img src={url} alt=""
             class:current-img={index === i}
             />
    {/each}
    <div id="carousel-nav">
        {#each urls as _, i}
        <svg height="20" width="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
            <circle cx="10" cy="10" r="10" 
                            class:current-marker="{index === i}"
                            on:click="{() => handleMarkerClick(i)}"
                            />
        </svg>
        {/each}
    </div>
</div>

<style>
    #carousel {
        position: relative;
        height: 500px;
    }
    img {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
        opacity: 0;
        transition: opacity 500ms ease-out;
    }
    .current-img {
        opacity: 1;
    }
    #carousel-nav {
        position: absolute;
        left: 50%;
        transform: translateX(-50%);
        bottom: 5%;
        display: grid;
        grid-auto-flow: column;
        gap: .5rem;
    }
    circle {
        fill: grey;
        transition: fill 500ms ease-out;
    }
    .current-marker {
        fill: white;
    }
</style>

Answer №2

Although I haven't worked with Svelte before, if I were to approach this using Vanilla HTML/CSS/JS, my focus would be on setting the animation-fill-mode to forwards for the animation. Additionally, I would manage the addition/removal of the .fade class based on button clicks while also resetting the opacity of elements accordingly.

In case it helps, here's how you could implement this in VanillaJS as an alternative way to visualize the concept:

const slides = Array.from(document.querySelectorAll(".slide"));
const buttonGroup = document.querySelector("#button-group");

buttonGroup.addEventListener("click", fadeSlides);

function fadeSlides(event) {
    const slideID = event.target.textContent;
    const slideSelector = `slide-${slideID}`;
    slides.forEach((el) => {
        if (el.id === slideSelector) {
            el.classList.add("fade");
        } else {
            el.classList.remove("fade");
            el.style.opacity = 0;
        }
    });
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Fade Example</title>
        <script defer src="app.js"></script>
        <style>
            #slideshow {
                width: 100px;
                height: 100px;
            }

            #button-group {
                margin-top: 12px;
            }

            .slide {
                width: 100px;
                height: 100px;
                position: absolute;
                top: 0;
                left: 0;
                opacity: 0;
            }

            #slide-1 {
                background-color: red;
                opacity: 1;
            }

            #slide-2 {
                background-color: green;
            }

            #slide-3 {
                background-color: blue;
            }
            .fade {
                animation-name: fade;
                animation-duration: 1.5s;
                animation-iteration-count: 1;
                animation-timing-function: ease-in;
                animation-fill-mode: forwards;
            }

            @keyframes fade {
                from {
                    opacity: 0;
                }
                to {
                    opacity: 1;
                }
            }
        </style>
    </head>
    <body>
        <div id="slideshow">
            <div class="slide" id="slide-1"></div>
            <div class="slide" id="slide-2"></div>
            <div class="slide" id="slide-3"></div>
        </div>
        <div id="button-group">
            <button id="button-1">1</button>
            <button id="button-2">2</button>
            <button id="button-3">3</button>
        </div>
    </body>
</html>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Challenges with Adjusting Background Opacity in CSS

My text has a white background with an opacity of .3, but it's affecting the foreground due to CSS repositioning. Even though the HTML is in a different division, I struggle with certain aspects of CSS and would appreciate guidance from those more exp ...

What is preventing me from iterating through a dictionary or an array of keys?

After trying to log the dictionary using console.log(JSON.stringify(this.idTitleDict)) as suggested by @Kobe, I noticed that it was showing empty curly braces. All the code related to this dictionary (including its declaration and population) can be found ...

Transforming CSS shorthand background properties into longhand representation

I have been working on a function to convert shorthand CSS background declarations into longhand. The function I created is functional, but it does not handle cases where the background-color property includes color values like black or yellow. It also doe ...

Excessive Spacing Below Picture

I am trying to position an image and a div directly beneath it, but I am encountering an issue with a visible margin between the two elements. You can view the code snippet here: http://jsfiddle.net/d3Mne/1/ Upon further investigation, I have noticed that ...

What is the best way to format this <li> element so that the second line of text starts directly below the beginning of the first line, rather than below the bullet point itself?

Is there a way to align the second row of a list item directly below the text and not below the bullet point? <ul class="arrow-list"> <li>Clear and consistent brand identity</li> <li>+47.08% Increase in website registration ...

Problem with responsive design on iPhone

I'm currently working on developing a responsive chatbot using CSS Bootstrap. However, I've encountered an issue where the header and footer are not fixed when I open the app on an iPhone. The keyboard header is also moving up the screen, which s ...

The image selection triggers the appearance of an icon

In my current project, I am working on implementing an icon that appears when selecting an image. The icon is currently positioned next to the beige image, but I am facing difficulties in making it disappear when no image is selected. Below are some image ...

Creating a default option in a Select tag with React when iterating over elements using the map method

After learning that each element in the dropdown must be given by the Option tag when using Select, I created an array of values for the dropdown: a = ['hai','hello','what'] To optimize my code, I wrote it in the following ...

React-bootstrap's Modal is glitching and only partially appearing on the screen

I am a beginner in frontend development and I've been struggling to position the modal at the center of the screen; it keeps appearing on the right side. I am currently using "bootstrap/dist/css/bootstrap.min.css" for my CSS. Should I create a new CSS ...

Display loader while waiting for file to be loaded

I am utilizing ajax to retrieve a file. The loading animation is functioning properly with the ajax request, however, the file size is notably large. I am interested in implementing a preloader that will display until the file has finished loading. ...

I'm encountering a 404 error on Next.js localhost:3000

Embarking on a fresh project in Next.js, my folder structure looks like this: https://i.stack.imgur.com/HhiJo.png However, upon navigating to localhost:3000, I am greeted with a 404 error screen. It seems there is an issue with the routing, but unfortuna ...

Restricting number input value in Vue using TypeScript

I have a component that looks like this: <input class="number-input py-1 primary--text font-weight-regular" :ref="'number-input-' + title" @keypress="onKeyPressed" :disabled="disabled& ...

Optimal approach for customizing the appearance of child components based on the parent component

I'm curious about the optimal method for styling child components based on their parent component. For instance, I want to design a list component that can be utilized in both a dropdown popup and a toolbar, each with its own unique style. There are ...

Hide the div once it goes off screen, ensuring that the user stays in the same position on the page

On my website, I implemented an effect similar to the Airbnb homepage where there is a "How it Works" button that toggles a Div element pushing down the entire page. However, when the user scrolls to the bottom of the toggled div (#slideDown) and it disapp ...

Limit the elements in an array within a specified range of dates

Currently, I am working on implementing a filter functionality for a data array used in a LineChart within my Angular application using TypeScript. The structure of the data array is as follows: var multi = [ { "name": "test1", "series": [ ...

Cannot close the Bootstrap dropdown after selecting an option

I am encountering an issue with a dropdown list that has a select feature using Bootstrap 3.4.1. The problem is that the dropdown remains open after selection and does not close unless I click outside of the list. Here is the HTML code: <div id="c ...

Is there a way to place two input fields from different forms side by side on the same line?

Here are two forms extracted from an html page: <form method="get" action="search/s" id="number"> <div style="text-align: center;"> <input type="text" id="regNo" name="regNo" size="30" maxLength="50" > or ...

"Utilizing Bootstrap to create a space-saving table layout with an

Using Bootstrap on a table causes an unexpected empty column to appear on the right side (as shown in the screenshot). This issue is strange because it works fine with another table using the same setup... but this particular table seems to have a mind of ...

What steps can I take to ensure my header appears perfectly aligned? (HTML/CSS)

My header on my website is all messed up with the links appearing incorrectly. I suspect it's an issue with style.css, so I attempted to modify the style.css file but had no luck. I have very limited experience with .css and cannot seem to figure out ...

Setting up TypeScript in Jest without the need for webpack

Currently, I'm developing an NPM module using TypeScript without the use of Webpack for compiling scripts. I need some guidance on configuring Jest to properly run tests with TypeScript files. Any recommendations? // test.spec.ts import {calc} from ...