export ready

main
psoubrie 2023-10-31 19:46:35 +00:00
parent 3ec0a3c486
commit 924faf2afd
5 changed files with 79 additions and 135 deletions

View File

@ -7,7 +7,9 @@
"customizations": {
"vscode": {
"extensions": [
"bradlc.vscode-tailwindcss"
"bradlc.vscode-tailwindcss",
"GitHub.copilot",
"esbenp.prettier-vscode"
]
}
}

View File

@ -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,
},
};

View File

@ -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>
);

View File

@ -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" : ""}`}
/>
);
}

View File

@ -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>
</>
);