177 lines
5.3 KiB
Text
177 lines
5.3 KiB
Text
---
|
|
import { Icon } from "astro-icon/components";
|
|
|
|
const videos = [
|
|
{
|
|
author: "outfoxxed",
|
|
authorlink: "https://outfoxxed.me",
|
|
path: "/assets/showcase/outfoxxed.mp4",
|
|
},
|
|
{
|
|
author: "flicko",
|
|
authorlink: "https://github.com/flick0",
|
|
path: "/assets/showcase/flicko.mp4",
|
|
},
|
|
{
|
|
author: "vaxry",
|
|
authorlink: "https://vaxry.net",
|
|
path: "/assets/showcase/vaxry.mp4",
|
|
},
|
|
];
|
|
---
|
|
<div class="marquee">
|
|
<div class="marquee-scroll">
|
|
<div class="marquee-item-spacing">
|
|
<div id="marquee-scroll-left" class="marquee-scroll-arrow">
|
|
<div><Icon name="caret-left"/></div>
|
|
</div>
|
|
<div id="marquee-scroll-right" class="marquee-scroll-arrow">
|
|
<div><Icon name="caret-right"/></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="marquee-content" class="marquee-content" data-scroll="0" data-media-index="0">
|
|
{videos.map(({ author, authorlink, path }, index) => <div class="marquee-item">
|
|
<div>
|
|
<video
|
|
data-media-index={index}
|
|
data-media-author={author}
|
|
id="showcase-video"
|
|
class="marquee-item-spacing marquee-item-content"
|
|
muted
|
|
controls
|
|
playsinline
|
|
>
|
|
<source src={path} type="video/mp4"/>
|
|
</video>
|
|
<p>Configuration by <a href={authorlink}>{author}</a></p>
|
|
</div>
|
|
</div>)}
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// marquee
|
|
const dataNum = 2; // last array index
|
|
const marquee = document.getElementById("marquee-content")!;
|
|
marquee.style.setProperty("--scroll", "0")
|
|
|
|
// autoplay
|
|
window.addEventListener("load", autoplayInit,false);
|
|
const videos = document.getElementsByClassName("marquee-item-content") as HTMLCollectionOf<HTMLVideoElement>;
|
|
|
|
function autoplayInit() {
|
|
videos[0].play();
|
|
videos[0].setAttribute("data-active", "");
|
|
};
|
|
|
|
const intersectionOptions = {
|
|
root: marquee,
|
|
rootMargin: "0px",
|
|
threshold: 0.0,
|
|
};
|
|
|
|
const observer = new IntersectionObserver((entries) => {
|
|
entries.forEach((entry) => {
|
|
const video = entry.target as HTMLVideoElement;
|
|
if (!entry.isIntersecting) {
|
|
video.pause();
|
|
video.removeAttribute("autoplay")
|
|
video.removeAttribute("data-active")
|
|
video.currentTime = 0;
|
|
} else {
|
|
video.play();
|
|
video.setAttribute("data-active","")
|
|
}
|
|
});
|
|
},intersectionOptions);
|
|
|
|
for (const video of videos) {
|
|
observer.observe(video);
|
|
video.addEventListener("ended", onVideoEnded)
|
|
}
|
|
|
|
const onVisibilityChange = () => {
|
|
for(const video of videos){
|
|
if(document.hidden){
|
|
video.pause();
|
|
} else {
|
|
video.play();
|
|
}
|
|
}
|
|
}
|
|
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
|
|
|
|
function onVideoEnded() {
|
|
const currentIndex = marquee.getAttribute("data-media-index");
|
|
const currentIndexNum = Number(currentIndex);
|
|
if(currentIndexNum !== dataNum){
|
|
const newIndex = currentIndexNum + 1;
|
|
marquee.setAttribute("data-media-index", `${newIndex}`);
|
|
marquee.style.setProperty("--scroll", `-${newIndex*100}%`)
|
|
} else {
|
|
marquee.setAttribute("data-media-index", "0");
|
|
marquee.style.setProperty("--scroll", "0")
|
|
}
|
|
}
|
|
|
|
// left-right buttons
|
|
const scrollLeft = document.getElementById("marquee-scroll-left")!;
|
|
const scrollRight = document.getElementById("marquee-scroll-right")!;
|
|
const scrollMaxPercent = dataNum*100;
|
|
|
|
scrollLeft.addEventListener("mousedown", () => {
|
|
const dataScroll = marquee.getAttribute("data-scroll")!;
|
|
const hashMap = {
|
|
"first": () => {
|
|
const scrollToLast = `-${scrollMaxPercent}%`;
|
|
marquee.setAttribute("data-scroll", scrollToLast);
|
|
},
|
|
"lt0": () => {
|
|
const oldDataScroll = marquee.getAttribute("data-scroll")!.slice(1, -1);
|
|
const oldNumScroll = Number(oldDataScroll)
|
|
const newScroll = oldNumScroll - 100;
|
|
newScroll <= scrollMaxPercent && newScroll > 0 ?
|
|
marquee.setAttribute("data-scroll",`-${newScroll.toString()}%`)
|
|
: marquee.setAttribute("data-scroll", "0")
|
|
}
|
|
}
|
|
|
|
hashMap[dataScroll === "0" ?
|
|
"first"
|
|
: "lt0"
|
|
]()
|
|
const updatedScroll = marquee.getAttribute("data-scroll")!;
|
|
const mediaIndex = updatedScroll.indexOf("%") !== -1 ? updatedScroll.slice(1, -3) : "0";
|
|
marquee.setAttribute("data-media-index", mediaIndex);
|
|
marquee.style.setProperty("--scroll", updatedScroll)
|
|
})
|
|
|
|
scrollRight.addEventListener("mousedown", () => {
|
|
const dataScroll = marquee.getAttribute("data-scroll")!;
|
|
const hashMap = {
|
|
"last": () => {
|
|
const scrollToFirst = "0";
|
|
marquee.setAttribute("data-scroll", scrollToFirst);
|
|
},
|
|
"mt0": () => {
|
|
const oldDataScroll = marquee.getAttribute("data-scroll")!.slice(1, -1);
|
|
const oldNumScroll = Number(oldDataScroll)
|
|
const newScroll = oldNumScroll + 100;
|
|
newScroll <= scrollMaxPercent ?
|
|
marquee.setAttribute("data-scroll",`-${newScroll.toString()}%`)
|
|
: marquee.setAttribute("data-scroll", "0")
|
|
}
|
|
}
|
|
|
|
hashMap[dataScroll === `${scrollMaxPercent}` ?
|
|
"last"
|
|
: "mt0"
|
|
]()
|
|
const updatedScroll = marquee.getAttribute("data-scroll")!;
|
|
const mediaIndex = updatedScroll.indexOf("%") !== -1 ? updatedScroll.slice(1, -3) : "0";
|
|
marquee.setAttribute("data-media-index", mediaIndex);
|
|
marquee.style.setProperty("--scroll", updatedScroll);
|
|
})
|
|
</script>
|