infinite scroll marquee almost done
This commit is contained in:
parent
3d615c4b5f
commit
eca995ca2c
7 changed files with 136 additions and 77 deletions
|
|
@ -2,6 +2,7 @@
|
|||
import matrixLogo from "@icons/matrix-logo.svg?raw";
|
||||
import discordLogo from "@icons/discord-logo.svg?raw";
|
||||
import gitLogo from "@icons/git-logo.svg?raw";
|
||||
import { ThemeSelect } from "./hooks/ThemeSwitch";
|
||||
|
||||
interface Props {
|
||||
class?: string;
|
||||
|
|
@ -18,6 +19,7 @@ const props = Astro.props;
|
|||
and our contributors
|
||||
</a>
|
||||
</div>
|
||||
<ThemeSelect client:load />
|
||||
<div class="socials-changelog">
|
||||
<section class="socials">
|
||||
<a href="https://matrix.to/#/#quickshell:outfoxxed.me" target="_blank" aria-label="Join our matrix space">
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import MarqueeContent from "./MarqueeContent.astro";
|
|||
marquee.style.setProperty("--mult", "1")
|
||||
|
||||
window.addEventListener("load", autoplayInit, false);
|
||||
const videos = document.getElementsByClassName("marquee-item-content") as HTMLCollectionOf<HTMLVideoElement>;
|
||||
let videos = document.getElementsByClassName("marquee-item-content") as HTMLCollectionOf<HTMLVideoElement>;
|
||||
const videoCount = videos.length;
|
||||
const lastVideoIndex = videos[videos.length - 1]
|
||||
let currentVideoIndex = 0;
|
||||
|
|
@ -38,6 +38,24 @@ import MarqueeContent from "./MarqueeContent.astro";
|
|||
}
|
||||
|
||||
currentVideoIndex = index;
|
||||
if (index === videos.length - 1) {
|
||||
console.log("shift")
|
||||
|
||||
const shifted = videos.item(0);
|
||||
marquee.firstElementChild.remove()
|
||||
const video_div = document.createElement("div");
|
||||
|
||||
video_div.classList.add("marquee-item");
|
||||
console.log("shift: ",video_div.classList.toString())
|
||||
|
||||
shifted.setAttribute("data-media-index", (index+1).toString())
|
||||
|
||||
video_div.appendChild(shifted);
|
||||
marquee.appendChild(video_div);
|
||||
videos = document.getElementsByClassName("marquee-item-content") as HTMLCollectionOf<HTMLVideoElement>;
|
||||
currentVideoIndex = index - 1;
|
||||
console.log("shift", marquee)
|
||||
}
|
||||
currentVideo = videos[currentVideoIndex];
|
||||
|
||||
currentVideo.currentTime = 0;
|
||||
|
|
@ -47,8 +65,8 @@ import MarqueeContent from "./MarqueeContent.astro";
|
|||
|
||||
function offsetCarousel(offset: number) {
|
||||
let nextIndex = currentVideoIndex + offset;
|
||||
if (nextIndex < 0) nextIndex += videoCount;
|
||||
nextIndex = nextIndex % videoCount;
|
||||
// if (nextIndex < 0) nextIndex += videoCount;
|
||||
// nextIndex = nextIndex % videoCount;
|
||||
setActiveVideo(nextIndex);
|
||||
}
|
||||
|
||||
|
|
@ -57,6 +75,7 @@ import MarqueeContent from "./MarqueeContent.astro";
|
|||
rootMargin: "0px",
|
||||
threshold: 0.1,
|
||||
};
|
||||
const mult = marquee.style.getPropertyValue("--mult") ?? 0;
|
||||
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach((entry) => {
|
||||
|
|
@ -86,28 +105,8 @@ import MarqueeContent from "./MarqueeContent.astro";
|
|||
video.style.animationPlayState = "running";
|
||||
video.style.animationDirection = "normal";
|
||||
}
|
||||
if (entry.isIntersecting && video === lastVideoIndex) {
|
||||
addNextVideo();
|
||||
}
|
||||
});
|
||||
}, intersectionOptions);
|
||||
function addNextVideo() {
|
||||
const firstVideo = videos[0];
|
||||
if (!firstVideo) return;
|
||||
|
||||
const newVideo = firstVideo.cloneNode(true) as HTMLVideoElement;
|
||||
|
||||
// IMPORTANT: Reset the state of the new video
|
||||
newVideo.pause();
|
||||
newVideo.currentTime = 0;
|
||||
newVideo.style.animationName = "none"; // Reset any lingering animation styles
|
||||
|
||||
// append to the marquee
|
||||
marquee.appendChild(newVideo);
|
||||
|
||||
// observe the new video
|
||||
observer.observe(newVideo);
|
||||
}
|
||||
|
||||
for (const video of videos) {
|
||||
observer.observe(video);
|
||||
|
|
|
|||
|
|
@ -35,24 +35,26 @@ const videos = [
|
|||
];
|
||||
---
|
||||
<div id="marquee-content" class="marquee-content" data-scroll="0" data-media-index="0">
|
||||
{videos.map(({ author, source, installable, path }, index) =>
|
||||
<div class="marquee-item">
|
||||
<video
|
||||
data-media-index={index}
|
||||
data-media-author={author}
|
||||
id="showcase-video"
|
||||
class="marquee-item-spacing marquee-item-content"
|
||||
muted
|
||||
controls
|
||||
playsinline
|
||||
preload="metadata"
|
||||
>
|
||||
<source src={path} type="video/mp4"/>
|
||||
{videos.map(({ author, source, installable, path }, index) => {
|
||||
return (
|
||||
<div class=`marquee-item`>
|
||||
<video
|
||||
data-media-index={index}
|
||||
data-media-author={author}
|
||||
id="showcase-video"
|
||||
class="marquee-item-spacing marquee-item-content"
|
||||
muted
|
||||
controls
|
||||
playsinline
|
||||
preload="metadata"
|
||||
>
|
||||
<source src={path} type="video/mp4"/>
|
||||
</video>
|
||||
<p>
|
||||
Configuration by <Fragment set:html={author}/>
|
||||
{source && !installable && <>(<a href={source}>source code</a>)</>}
|
||||
{source && installable && <>(<a href={source}>install</a>)</>}
|
||||
</p>
|
||||
</div>)}
|
||||
</div>
|
||||
)})}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -138,15 +138,20 @@
|
|||
}
|
||||
|
||||
@keyframes bounce {
|
||||
0%,
|
||||
100% {
|
||||
transform: translateY(-25%);
|
||||
animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
|
||||
0% {
|
||||
transform: none;
|
||||
animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: none;
|
||||
transform: translateY(-12%);
|
||||
animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
|
||||
color: hsla(var(--green) 100 69 / 0.75);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: none;
|
||||
animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -166,5 +171,6 @@
|
|||
--animate-spin: spin 1s linear infinite;
|
||||
--animate-ping: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;
|
||||
--animate-pulse: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||||
--animate-bounce: bounce 1s infinite;
|
||||
--animate-bounce: bounce 0.6s var(--ease-out) forwards;
|
||||
--animate-fade: fade 0.3s cubic-bezier(0.4, 0, 0.6, 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ html {
|
|||
position: relative;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
transition: all 0.3s var(--ease-in-out);
|
||||
}
|
||||
|
||||
body {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
pre.shiki {
|
||||
margin-block: 1.618rem;
|
||||
margin-block: var(--lg);
|
||||
}
|
||||
|
||||
:where(p, li):has(> code) code {
|
||||
padding-inline: 0.272rem;
|
||||
border-radius: 0.272rem;
|
||||
color: hsl(var(--blue) 100% 69%);
|
||||
background-color: hsl(var(--blue) 85% 35% / 0.1);
|
||||
padding-inline: var(--2xl);
|
||||
border-radius: var(--2xl);
|
||||
color: hsl(var(--blue) 100 69);
|
||||
background-color: hsla(var(--blue) 85 35 / 0.1);
|
||||
}
|
||||
|
||||
.shiki,
|
||||
|
|
@ -26,6 +26,9 @@ pre {
|
|||
border-radius: 0.618rem;
|
||||
overflow: hidden;
|
||||
text-wrap: wrap;
|
||||
transition:
|
||||
background-color 0.3s var(--ease-in-out),
|
||||
color 0.3s var(--ease-in-out);
|
||||
|
||||
& .copy-button {
|
||||
all: unset;
|
||||
|
|
@ -41,18 +44,29 @@ pre {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: hsl(var(--blue) 100% 69%);
|
||||
background-color: hsl(var(--blue) 85% 35% / 0.1);
|
||||
color: hsla(var(--blue) 100 69 / 0.33);
|
||||
background-color: hsla(var(--blue) 85 35 / 0.01);
|
||||
cursor: pointer;
|
||||
transition: color 0.25s;
|
||||
transition:
|
||||
background-color 0.3s var(--ease-in-out),
|
||||
color 0.3s var(--ease-in-out);
|
||||
z-index: 10;
|
||||
|
||||
&:hover {
|
||||
color: hsl(var(--blue) 100% 75%);
|
||||
color: hsla(var(--blue) 100 75 / 0.75);
|
||||
background-color: hsla(var(--blue) 85 35 / 0.1);
|
||||
}
|
||||
|
||||
&.copied {
|
||||
animation: pulseGreen 0.5s cubic-bezier(0, 1, 0.6, 1);
|
||||
animation: var(--animate-bounce);
|
||||
}
|
||||
}
|
||||
|
||||
&.shiki {
|
||||
box-shadow: var(--shadow-xl);
|
||||
|
||||
&:hover .copy-button {
|
||||
background-color: hsla(var(--blue) 85 35 / 0.07);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,17 @@
|
|||
transition: none !important;
|
||||
}
|
||||
|
||||
.theme-toggle {
|
||||
height: 24px;
|
||||
font-size: 1.614rem;
|
||||
color: hsla(var(--signal-color) / 0.7);
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
color: hsla(var(--signal-color) / 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* color styling */
|
||||
.header {
|
||||
background-color: hsl(var(--bg-400));
|
||||
|
|
@ -49,6 +60,14 @@ html.dark {
|
|||
background-color: hsl(var(--secondary-900));
|
||||
color: hsl(var(--secondary-500));
|
||||
}
|
||||
|
||||
& .theme-toggle {
|
||||
color: hsla(var(--func-color) / 0.7);
|
||||
|
||||
&:hover {
|
||||
color: hsla(var(--func-color) / 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* layout and positioning */
|
||||
|
|
@ -56,10 +75,12 @@ html.dark {
|
|||
width: 75%;
|
||||
height: 1px;
|
||||
margin-block: 0.618rem;
|
||||
background: linear-gradient(to right,
|
||||
transparent,
|
||||
hsl(var(--blue) 100% 59%),
|
||||
transparent);
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
transparent,
|
||||
hsl(var(--blue) 100% 59%),
|
||||
transparent
|
||||
);
|
||||
}
|
||||
|
||||
.unset {
|
||||
|
|
@ -130,15 +151,6 @@ body.overflow-toc {
|
|||
display: block;
|
||||
}
|
||||
|
||||
.theme-toggle {
|
||||
height: 24px;
|
||||
font-size: 1.614rem;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
|
@ -146,7 +158,6 @@ footer {
|
|||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 1rem 2rem;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
background: hsl(var(--footer-bkg));
|
||||
|
||||
|
|
@ -154,13 +165,38 @@ footer {
|
|||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -1rem;
|
||||
left: 0;
|
||||
right: 54%;
|
||||
height: 1px;
|
||||
width: calc(100% + 1rem);
|
||||
background: linear-gradient(90deg,
|
||||
transparent 0%,
|
||||
hsl(var(--footer-bkg-border)) 50%,
|
||||
transparent 100%);
|
||||
width: calc(48%);
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
transparent 0%,
|
||||
hsl(var(--footer-bkg-border)) 100%
|
||||
);
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 54%;
|
||||
height: 1px;
|
||||
width: calc(48% - 1rem);
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
hsl(var(--footer-bkg-border)) 0%,
|
||||
transparent 100%
|
||||
);
|
||||
}
|
||||
|
||||
& .theme-toggle {
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
left: 50%;
|
||||
width: max-content;
|
||||
height: max-content;
|
||||
}
|
||||
|
||||
& a {
|
||||
|
|
@ -199,12 +235,12 @@ footer {
|
|||
gap: 0.2rem;
|
||||
color: hsl(var(--text-dark));
|
||||
|
||||
&>p {
|
||||
& > p {
|
||||
margin-bottom: 0.2rem;
|
||||
color: hsl(0deg 0% 40%);
|
||||
}
|
||||
|
||||
&>a {
|
||||
& > a {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
|
@ -218,7 +254,6 @@ footer {
|
|||
gap: 0.373rem;
|
||||
align-items: flex-start;
|
||||
font-size: 2.5rem;
|
||||
|
||||
}
|
||||
|
||||
& .changelog {
|
||||
|
|
@ -235,7 +270,7 @@ footer {
|
|||
footer {
|
||||
padding-inline: 0.75rem;
|
||||
|
||||
& .credits>a {
|
||||
& .credits > a {
|
||||
padding: 0.2rem 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue