export ready
parent
3ec0a3c486
commit
924faf2afd
|
@ -7,7 +7,9 @@
|
|||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"bradlc.vscode-tailwindcss"
|
||||
"bradlc.vscode-tailwindcss",
|
||||
"GitHub.copilot",
|
||||
"esbenp.prettier-vscode"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,9 +13,9 @@ const config = {
|
|||
*
|
||||
* @see https://github.com/vercel/next.js/issues/41980
|
||||
*/
|
||||
i18n: {
|
||||
locales: ["en"],
|
||||
defaultLocale: "en",
|
||||
output: 'export',
|
||||
images: {
|
||||
unoptimized: true,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { ChevronLeftIcon, ChevronRightIcon } from '@radix-ui/react-icons';
|
||||
import React, { useRef, useCallback } from 'react';
|
||||
import HTMLFlipBook from 'react-pageflip';
|
||||
import { ChevronLeftIcon, ChevronRightIcon } from "@radix-ui/react-icons";
|
||||
import React, { useRef, useCallback } from "react";
|
||||
import HTMLFlipBook from "react-pageflip";
|
||||
|
||||
interface FlipbookProps {
|
||||
children: React.ReactNode[];
|
||||
width: number;
|
||||
height: number;
|
||||
className?: React.ComponentProps<'div'>['className'];
|
||||
className?: React.ComponentProps<"div">["className"];
|
||||
}
|
||||
|
||||
interface PageFlip {
|
||||
|
@ -21,53 +21,64 @@ export default function Flipbook(props: FlipbookProps) {
|
|||
const flipbook = useRef<{ pageFlip(): PageFlip } | null>(null);
|
||||
|
||||
// Function to flip pages
|
||||
const flipPage = useCallback((direction: 'next' | 'prev') => {
|
||||
const flipbookCurrent = flipbook.current;
|
||||
if (flipbookCurrent) {
|
||||
const pageFlipObj = flipbookCurrent.pageFlip();
|
||||
const currentPageIndex = pageFlipObj.getCurrentPageIndex();
|
||||
const pageCount = pageFlipObj.getPageCount();
|
||||
const flipPage = useCallback(
|
||||
(direction: "next" | "prev") => {
|
||||
const flipbookCurrent = flipbook.current;
|
||||
if (flipbookCurrent) {
|
||||
const pageFlipObj = flipbookCurrent.pageFlip();
|
||||
const currentPageIndex = pageFlipObj.getCurrentPageIndex();
|
||||
const pageCount = pageFlipObj.getPageCount();
|
||||
|
||||
if (direction === 'next') {
|
||||
if (currentPageIndex + 2 === pageCount) {
|
||||
pageFlipObj.flip(0);
|
||||
} else {
|
||||
pageFlipObj.flipNext();
|
||||
}
|
||||
} else if (direction === 'prev') {
|
||||
if (currentPageIndex === 0) {
|
||||
pageFlipObj.flip(pageCount - 1);
|
||||
} else {
|
||||
pageFlipObj.flipPrev(); // Add this method to handle the previous page flip
|
||||
if (direction === "next") {
|
||||
if (currentPageIndex + 2 === pageCount) {
|
||||
pageFlipObj.flip(0);
|
||||
} else {
|
||||
pageFlipObj.flipNext();
|
||||
}
|
||||
} else if (direction === "prev") {
|
||||
if (currentPageIndex === 0) {
|
||||
pageFlipObj.flip(pageCount - 1);
|
||||
} else {
|
||||
pageFlipObj.flipPrev(); // Add this method to handle the previous page flip
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [flipbook]);
|
||||
},
|
||||
[flipbook],
|
||||
);
|
||||
|
||||
// Handler for the next button
|
||||
const nextButtonClick = useCallback(() => {
|
||||
flipPage('next');
|
||||
flipPage("next");
|
||||
}, [flipPage]);
|
||||
|
||||
// Handler for the previous button
|
||||
const prevButtonClick = useCallback(() => {
|
||||
flipPage('prev');
|
||||
flipPage("prev");
|
||||
}, [flipPage]);
|
||||
|
||||
return (
|
||||
<div className={`flex justify-center items-center ${props.className}`}>
|
||||
<button onClick={prevButtonClick}>
|
||||
<ChevronLeftIcon height={50} width={50}/>
|
||||
<div className={`flex items-center justify-center ${props.className}`}>
|
||||
<button onClick={prevButtonClick}>
|
||||
<ChevronLeftIcon
|
||||
height={50}
|
||||
width={50}
|
||||
className="max-h-[7vw] max-w-[7vw]"
|
||||
/>
|
||||
</button>
|
||||
<HTMLFlipBook
|
||||
usePortrait={false}
|
||||
className="text-black"
|
||||
width={props.width} height={props.height}
|
||||
width={props.width}
|
||||
height={props.height}
|
||||
size="fixed"
|
||||
style={{}}
|
||||
minHeight={100} maxHeight={500}
|
||||
minWidth={100} maxWidth={500}
|
||||
startPage={0} startZIndex={0}
|
||||
minHeight={100}
|
||||
maxHeight={500}
|
||||
minWidth={100}
|
||||
maxWidth={500}
|
||||
startPage={0}
|
||||
startZIndex={0}
|
||||
drawShadow
|
||||
flippingTime={1000}
|
||||
autoSize
|
||||
|
@ -84,7 +95,11 @@ export default function Flipbook(props: FlipbookProps) {
|
|||
{props.children}
|
||||
</HTMLFlipBook>
|
||||
<button onClick={nextButtonClick}>
|
||||
<ChevronRightIcon height={50} width={50}/>
|
||||
<ChevronRightIcon
|
||||
height={50}
|
||||
width={50}
|
||||
className="max-h-[7vw] max-w-[7vw]"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
import { ChevronLeftIcon, ChevronRightIcon } from "@radix-ui/react-icons";
|
||||
import { useKeenSlider } from "keen-slider/react";
|
||||
import { useState, type MouseEvent } from "react";
|
||||
|
||||
interface SliderProps {
|
||||
className?: React.ComponentProps<'div'>['className'];
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export default function Slider({ className, children }: SliderProps) {
|
||||
const [currentSlide, setCurrentSlide] = useState(0);
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
const [sliderRef, instanceRef] = useKeenSlider<HTMLDivElement>({
|
||||
initial: 0,
|
||||
slideChanged(slider) {
|
||||
setCurrentSlide(slider.track.details.rel);
|
||||
},
|
||||
created() {
|
||||
setLoaded(true);
|
||||
},
|
||||
});
|
||||
|
||||
const goPrev = (e: MouseEvent<unknown>) => {
|
||||
e.stopPropagation();
|
||||
if (currentSlide !== 0) {
|
||||
instanceRef.current?.prev();
|
||||
}
|
||||
};
|
||||
|
||||
const goNext = (e: MouseEvent<unknown>) => {
|
||||
e.stopPropagation();
|
||||
if (instanceRef.current && currentSlide !== instanceRef.current.track.details.slides.length - 1) {
|
||||
instanceRef.current.next();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`${className} relative`}>
|
||||
<div>
|
||||
<div ref={sliderRef} className="flex overflow-hidden relative w-full">
|
||||
{children}
|
||||
</div>
|
||||
{loaded && instanceRef.current && (
|
||||
<>
|
||||
<Arrow left onClick={goPrev} disabled={currentSlide === 0} />
|
||||
<Arrow onClick={goNext} disabled={instanceRef.current ? currentSlide === instanceRef.current.track.details.slides.length - 1 : true} />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
{loaded && instanceRef.current && (
|
||||
<div className="flex justify-center py-2">
|
||||
{Array.from({ length: instanceRef.current.track.details.slides.length }, (_, idx) => (
|
||||
<button
|
||||
key={idx}
|
||||
onClick={() => instanceRef.current?.moveToIdx(idx)}
|
||||
className={`w-2.5 h-2.5 bg-white rounded-full m-1 cursor-pointer ${currentSlide === idx ? "opacity-30" : ""}`}
|
||||
></button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface ArrowProps {
|
||||
disabled: boolean;
|
||||
left?: boolean;
|
||||
onClick: (e: MouseEvent<unknown>) => void;
|
||||
}
|
||||
|
||||
function Arrow({ disabled, left, onClick }: ArrowProps) {
|
||||
const Icon = left ? ChevronLeftIcon : ChevronRightIcon;
|
||||
const position = left ? '-left-10' : 'left-auto -right-10';
|
||||
|
||||
return (
|
||||
<Icon
|
||||
onClick={onClick}
|
||||
height={50}
|
||||
width={50}
|
||||
className={`absolute ${position} top-1/2 cursor-pointer -translate-y-1/2 ${disabled ? "opacity-30" : ""}`}
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -1,8 +1,18 @@
|
|||
import React, { useRef, useState, useEffect } from 'react';
|
||||
import Head from "next/head";
|
||||
import Image from "next/image";
|
||||
import Flipbook from "~/components/Flipbook";
|
||||
|
||||
export default function Home() {
|
||||
const mainRef = useRef<HTMLDivElement>(null);
|
||||
const [mainWidth, setMainWidth] = useState(350); // default value
|
||||
|
||||
useEffect(() => {
|
||||
if (mainRef.current) {
|
||||
setMainWidth(mainRef.current.offsetWidth/2.3);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
|
@ -10,22 +20,22 @@ export default function Home() {
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
<main className="">
|
||||
<Flipbook className="" width={350} height={460}>
|
||||
<div className="bg-gray-300">
|
||||
<div className="flex justify-center items-center h-full">
|
||||
<a href="/download/GabrielDalle_Magazine.pdf" target="_blank" className="border-my-red border-[3px] p-4 rounded-full flex gap-2 cursor-pointer hover:border-black hover:bg-white font-mono font-bold text-sm tracking-wide">
|
||||
PDF DOWNLOAD
|
||||
</a>
|
||||
<main className="" ref={mainRef}>
|
||||
<Flipbook className="" width={mainWidth} height={mainWidth*460/350}>
|
||||
<div className="bg-gray-300">
|
||||
<div className="flex justify-center items-center h-full">
|
||||
<a href="/download/GabrielDalle_Magazine.pdf" target="_blank" className="border-my-red border-[3px] p-4 rounded-full flex gap-2 cursor-pointer hover:border-black hover:bg-white font-mono font-bold text-sm tracking-wide">
|
||||
PDF DOWNLOAD
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{Array.from(Array(24), (_, i) => (
|
||||
<div className="bg-white" key={i}>
|
||||
<Image key={i} alt="pdf page" height={468} width={350} src={`/projects/fizik/pdf/page${i + 1}.png`} />
|
||||
</div>
|
||||
))}
|
||||
<div className="bg-gray-300" />
|
||||
</Flipbook>
|
||||
{Array.from(Array(24), (_, i) => (
|
||||
<div className="bg-white" key={i}>
|
||||
<Image key={i} alt="pdf page" height={468} width={mainWidth} src={`/projects/fizik/pdf/page${i + 1}.png`} />
|
||||
</div>
|
||||
))}
|
||||
<div className="bg-gray-300" />
|
||||
</Flipbook>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue