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
<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>