Home > Net >  Im try to get the fade in and out to work in my slideshow
Im try to get the fade in and out to work in my slideshow

Time:12-29

My problem is that the fading only works on the first time the page loads and only on the first image the rest the fading the doesn't work on any image

this is what i have done in css and add it to

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

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

and other things with svelte transition:fade.

Here is mode html is compoment

<div
    
    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 >
                <span >
                    <img
                        src={image}
                        alt="dragon"
                        loading="lazy"
                        style="position:relative; display: {index === current ? 'block' : 'none'}"
                    />
                </span>
                <a  href="/">.</a>
            </div>
        </transition>
    {/each}
    <div >
        {#each images as _, index}
            <span                      
                
                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>

Script Typescript

<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 come to mind that i haven't done is is this example from stackoverflow the last answer

heres a reference where i got it the idea for the Banner

CodePudding user response:

Here's one way making use of 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() //executed when component is destroyed
    })

    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>

CodePudding user response:

I'm not familiar with Svelte, but if I were to do this in Vanilla HTML/CSS/JS, I'd want to have the animation-fill-mode set to forwards on the animation and I'd also want to attach/remove the .fade class as the buttons are clicked from the appropriate elements and reset the opacity.

Here's a VanillaJS implementation, maybe that'll help you to see what you're missing using this framework?

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  id="slide-1"></div>
            <div  id="slide-2"></div>
            <div  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>

  • Related