swap home banners, 3s autoplay, animated rec scroll thumb
This commit is contained in:
9
public/assets/ark-library/banners/README.md
Normal file
9
public/assets/ark-library/banners/README.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Home banner slider images
|
||||||
|
|
||||||
|
Drop banner images here as `banner-1.png`, `banner-2.png`, `banner-3.png`, `banner-4.png`.
|
||||||
|
|
||||||
|
- Used by `src/components/FigmaBanner.tsx` (home page slider on `/`)
|
||||||
|
- Recommended size: 780 × 400 px (2x of mobile 390 × 200)
|
||||||
|
- Format: PNG or WebP; PNG keeps the existing pipeline
|
||||||
|
- Filenames are fixed; replace the file to swap a slide
|
||||||
|
- To add more slides, append to `BANNER_SLIDES` in `FigmaBanner.tsx`
|
||||||
BIN
public/assets/ark-library/banners/banner-1.png
Normal file
BIN
public/assets/ark-library/banners/banner-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 MiB |
BIN
public/assets/ark-library/banners/banner-2.png
Normal file
BIN
public/assets/ark-library/banners/banner-2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
BIN
public/assets/ark-library/banners/banner-3.png
Normal file
BIN
public/assets/ark-library/banners/banner-3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 MiB |
BIN
public/assets/ark-library/banners/banner-4.png
Normal file
BIN
public/assets/ark-library/banners/banner-4.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 MiB |
@@ -23,22 +23,36 @@ type BannerSlide = {
|
|||||||
alt: string;
|
alt: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const BANNERS_BASE = "/assets/ark-library/banners";
|
||||||
|
|
||||||
const BANNER_SLIDES: BannerSlide[] = [
|
const BANNER_SLIDES: BannerSlide[] = [
|
||||||
{
|
{
|
||||||
id: "ark-banner-1",
|
id: "ark-banner-1",
|
||||||
mobile: `${FIGMA_ASSET_BASE}/banner-mobile-1.png`,
|
mobile: `${BANNERS_BASE}/banner-1.png`,
|
||||||
desktop: `${FIGMA_ASSET_BASE}/banner-desktop.png`,
|
desktop: `${BANNERS_BASE}/banner-1.png`,
|
||||||
alt: "",
|
alt: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "ark-banner-2",
|
id: "ark-banner-2",
|
||||||
mobile: `${FIGMA_ASSET_BASE}/banner-375.png`,
|
mobile: `${BANNERS_BASE}/banner-2.png`,
|
||||||
desktop: `${FIGMA_ASSET_BASE}/banner-wide.png`,
|
desktop: `${BANNERS_BASE}/banner-2.png`,
|
||||||
|
alt: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "ark-banner-3",
|
||||||
|
mobile: `${BANNERS_BASE}/banner-3.png`,
|
||||||
|
desktop: `${BANNERS_BASE}/banner-3.png`,
|
||||||
|
alt: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "ark-banner-4",
|
||||||
|
mobile: `${BANNERS_BASE}/banner-4.png`,
|
||||||
|
desktop: `${BANNERS_BASE}/banner-4.png`,
|
||||||
alt: "",
|
alt: "",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const AUTOPLAY_MS = 5000;
|
const AUTOPLAY_MS = 3000;
|
||||||
const RESUME_AFTER_INTERACTION_MS = 8000;
|
const RESUME_AFTER_INTERACTION_MS = 8000;
|
||||||
|
|
||||||
export function FigmaBanner() {
|
export function FigmaBanner() {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ export function Home() {
|
|||||||
const [err, setErr] = useState<string | null>(null);
|
const [err, setErr] = useState<string | null>(null);
|
||||||
const recRowRef = useRef<HTMLDivElement>(null);
|
const recRowRef = useRef<HTMLDivElement>(null);
|
||||||
const [canScrollRec, setCanScrollRec] = useState(false);
|
const [canScrollRec, setCanScrollRec] = useState(false);
|
||||||
|
const [recScroll, setRecScroll] = useState({ ratio: 1, progress: 0 });
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const langParam = encodeURIComponent(langQuery(lang));
|
const langParam = encodeURIComponent(langQuery(lang));
|
||||||
@@ -64,14 +65,26 @@ export function Home() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateCanScroll = () => {
|
const update = () => {
|
||||||
setCanScrollRec(row.scrollWidth > row.clientWidth + 1);
|
const overflow = row.scrollWidth > row.clientWidth + 1;
|
||||||
|
setCanScrollRec(overflow);
|
||||||
|
const ratio = overflow ? row.clientWidth / row.scrollWidth : 1;
|
||||||
|
const maxScroll = Math.max(1, row.scrollWidth - row.clientWidth);
|
||||||
|
const progress = overflow ? row.scrollLeft / maxScroll : 0;
|
||||||
|
setRecScroll({
|
||||||
|
ratio: Math.min(1, Math.max(0.15, ratio)),
|
||||||
|
progress: Math.min(1, Math.max(0, progress)),
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
updateCanScroll();
|
update();
|
||||||
const resizeObserver = new ResizeObserver(updateCanScroll);
|
const resizeObserver = new ResizeObserver(update);
|
||||||
resizeObserver.observe(row);
|
resizeObserver.observe(row);
|
||||||
return () => resizeObserver.disconnect();
|
row.addEventListener("scroll", update, { passive: true });
|
||||||
|
return () => {
|
||||||
|
resizeObserver.disconnect();
|
||||||
|
row.removeEventListener("scroll", update);
|
||||||
|
};
|
||||||
}, [rec.length]);
|
}, [rec.length]);
|
||||||
|
|
||||||
const scrollRec = (dir: 1 | -1) => {
|
const scrollRec = (dir: 1 | -1) => {
|
||||||
@@ -147,8 +160,14 @@ export function Home() {
|
|||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="h-1 rounded-full bg-black/80 md:hidden">
|
<div className="h-1 overflow-hidden rounded-full bg-black/80 md:hidden">
|
||||||
<div className="h-full w-24 rounded-full bg-[#353740]" />
|
<div
|
||||||
|
className="h-full rounded-full bg-ark-gold transition-transform duration-300 ease-out"
|
||||||
|
style={{
|
||||||
|
width: `${Math.round(recScroll.ratio * 100)}%`,
|
||||||
|
transform: `translateX(${recScroll.progress * (100 / recScroll.ratio - 100)}%)`,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
{canScrollRec ? (
|
{canScrollRec ? (
|
||||||
<button
|
<button
|
||||||
|
|||||||
Reference in New Issue
Block a user