I'm a bit new with svelte
, and I'm building a survay for AmazonTurk
with it to have video-like player embeded in the webpage.
To do that, I am building an image carousel, and need to simulate an automatic image change to make it look as if it is a video player.
I have the setup, but can't figure out how to simulate the "next" button click until "pause" is pressed, in which case the transision should stop until "play" button is pressed etc.
My code is the following:
<script lang="ts">
import { slide } from "svelte/transition";
export let imageDir: string;
export let startIndex = 0;
export let endIndex = 0;
let images = new Array(
endIndex - startIndex).fill(0).map((_, i) =>
imageDir + "/frame_" + (i + startIndex) + ".jpg"
);
let videoPaused = false;
const nextImage = () => {
currentSlideItem = (currentSlideItem + 1) % images.length;
}
const prevImage = () => {
if (currentSlideItem != 0){
currentSlideItem = (currentSlideItem - 1) % images.length;
} else {
currentSlideItem = images.length - 1;
}
}
const play = () => {
if (videoPaused){
videoPaused = false;
}
}
const pause = () => {
if (!videoPaused){
videoPaused = true;
}
}
</script>
<main>
{#each [images[currentSlideItem]] as image, index}
<img transition:slide="{{delay:200}}" src={image} alt='Blank' width="1080"/>
{/each}
<div class="carousel-buttons">
<button id="play" on:click={() => play()}>⏯</button>
<button id="pause" on:click={() => pause()}>⏸</button>
<button id="prev" on:click={() => prevImage()}>⏪</button>
<button id="next" on:click={() => nextImage()}>⏩</button>
</div>
</main>
What I've Tried so Far:
<script></script>
close inside the <main></main>
close with the desired functionality as follows:<main>
{#each [images[currentSlideItem]] as image, index}
<img transition:slide="{{delay:200}}" src={image} alt='Blank' width="1080"/>
{/each}
<div class="carousel-buttons">
<button id="play" on:click={() => play()}>⏯</button>
<button id="pause" on:click={() => pause()}>⏸</button>
<button id="prev" on:click={() => prevImage()}>⏪</button>
<button id="next" on:click={() => nextImage()}>⏩</button>
</div>
<script>
prevBtn = document.getElementById("prev")
playBtn = document.getElementById("play")
pauseBtn = document.getElementById("pause")
nextBtn = document.getElementById("next")
while !videoPaused{
triggerClick(nextBtn);
}
</script>
</main>
but it seems this code is not being even executed.
<script></script>
close as follows:<script lang="ts">
import { slide } from "svelte/transition";
export let imageDir: string;
export let startIndex = 0;
export let endIndex = 0;
let images = new Array(
endIndex - startIndex).fill(0).map((_, i) =>
imageDir + "/frame_" + (i + startIndex) + ".jpg"
);
let videoPaused = false;
const nextImage = () => {
currentSlideItem = (currentSlideItem + 1) % images.length;
}
const prevImage = () => {
if (currentSlideItem != 0){
currentSlideItem = (currentSlideItem - 1) % images.length;
} else {
currentSlideItem = images.length - 1;
}
}
const play = () => {
if (videoPaused){
videoPaused = false;
}
}
const pause = () => {
if (!videoPaused){
videoPaused = true;
}
}
const nextBtn = document.getElementById("next")
for(let i = 0; i < 50; i++){
videoPaused = true;
nextBtn?.click();
}
</script>
but again without luck.
What do I do wrong?
Here is the repo of the entire app
Thanks in advance.
The way I solved it is actually quite simple:
We already have a function to show the next image so we can just call it repeatedly. JavaScript already has a (somewhat reliable) function to do this: setInterval
In the end, my code looks like this and it works like a video player. You can adjust the speed by adjusting the delay in the setInterval
function.
<script lang="ts">
import { slide } from "svelte/transition";
export let imageDir: string;
export let startIndex = 0;
export let endIndex = 0;
let images = new Array(endIndex - startIndex)
.fill(0)
.map((_, i) => imageDir + "/frame_" + (i + startIndex) + ".jpg");
let currentSlideItem = 0;
let videoPaused = false;
console.log({ videoPaused });
const nextImage = () => {
currentSlideItem = (currentSlideItem + 1) % images.length;
};
const prevImage = () => {
if (currentSlideItem != 0) {
currentSlideItem = (currentSlideItem - 1) % images.length;
} else {
currentSlideItem = images.length - 1;
}
};
const play = () => {
videoPaused = false;
};
const pause = () => {
videoPaused = true;
};
setInterval(() => {
if (!videoPaused) {
nextImage();
}
}, 50);
</script>
<main>
{#each [images[currentSlideItem]] as image, index}
<img
transition:slide={{ delay: 200 }}
src={image}
alt="Blank"
width="1080"
/>
{/each}
<div class="carousel-buttons">
<button id="play" on:click={() => play()}>⏯</button>
<button id="pause" on:click={() => pause()}>⏸</button>
<button id="prev" on:click={() => prevImage()}>⏪</button>
<button id="next" on:click={() => nextImage()}>⏩</button>
</div>
</main>
Extra: In your github, you published the node_modules
folder, which actually gives people cloning your repo a problem: They can't rum npm run dev
. It is just as simple as removing the folder, but it does make for some inconvenience!