diff --git a/src/assets/style/global.css b/src/assets/style/global.css index 5e78d63..91bc0eb 100644 --- a/src/assets/style/global.css +++ b/src/assets/style/global.css @@ -67,6 +67,18 @@ video { height: auto; } +img.respect-width, +video.respect-width { + max-width: 100%; + height: auto; +} + +img.respect-height, +video.respect-height { + max-height: 100%; + width: auto; +} + li:not(:last-child) { margin-bottom: var(--prj-spacing-1); } diff --git a/src/components/Carousel/Carousel.module.css b/src/components/Carousel/Carousel.module.css new file mode 100644 index 0000000..8e75332 --- /dev/null +++ b/src/components/Carousel/Carousel.module.css @@ -0,0 +1,49 @@ +.carousel { + height: 100%; + max-width: 90%; + margin: auto; + position: relative; + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; +} + +.container { + height: 100%; + overflow: hidden; +} + +.content { + height: 100%; + display: flex; + flex-wrap: nowrap; + transition: transform 0.6s ease; +} + +.item { + height: 100%; + width: 100%; + flex: 0 0 100%; +} + +.itemContent { + height: 100%; + display: flex; + justify-content: center; + align-items: center; +} + +.btnPrev, +.btnNext { + top: 50%; + z-index: 10; +} + +.btnPrev { + left: 0; +} + +.btnNext { + right: 0; +} diff --git a/src/components/Carousel/Carousel.tsx b/src/components/Carousel/Carousel.tsx new file mode 100644 index 0000000..4c0da5d --- /dev/null +++ b/src/components/Carousel/Carousel.tsx @@ -0,0 +1,66 @@ +import React, { Children, useEffect, useRef, useState } from 'react'; +import classes from './Carousel.module.css'; + +interface Props { + children: React.ReactNode; +} + +export default function Carousel({ children }: Props): JSX.Element { + const [activeItem, setActiveItem] = useState(0); + const content = useRef(null); + const maxItems = Children.count(children) - 1; + + useEffect(() => { + if (content.current == null) return; + + const offset = content.current.clientWidth * activeItem; + // const offset = 100 * activeItem; + // + console.log(offset, activeItem, content.current.clientWidth); + + content.current.style.transform = `translate3d(-${offset}px, 0px, 0px)`; + }, [activeItem]); + + const offsetActiveItem = (offset: number): void => { + setActiveItem((prev) => { + const newActiveItem = prev + offset; + + // Wrap on end in both sides + if (newActiveItem < 0) { + return maxItems; + } + + if (newActiveItem > maxItems) { + return 0; + } + + return newActiveItem; + }); + }; + + return ( +
+ +
+
+ {children} +
+
+ +
+ ); +} diff --git a/src/components/Carousel/CarouselItem.tsx b/src/components/Carousel/CarouselItem.tsx new file mode 100644 index 0000000..bbdb373 --- /dev/null +++ b/src/components/Carousel/CarouselItem.tsx @@ -0,0 +1,15 @@ +import React from 'react'; + +import classes from './Carousel.module.css'; + +interface Props { + children: JSX.Element | JSX.Element[]; +} + +export default function CarouselItem({ children }: Props): JSX.Element { + return ( +
+
{children}
+
+ ); +} diff --git a/src/components/MediaGallery/Gallery.tsx b/src/components/MediaGallery/Gallery.tsx index ed4ff33..dee560f 100644 --- a/src/components/MediaGallery/Gallery.tsx +++ b/src/components/MediaGallery/Gallery.tsx @@ -1,95 +1,29 @@ import React from 'react'; -import { MediaType, type Media } from './types'; +import { type Media } from './types'; import classes from './Gallery.module.css'; - -import LightGallery from 'lightgallery/react'; - -// import styles -import 'lightgallery/css/lightgallery.css'; -import 'lightgallery/css/lg-zoom.css'; -import 'lightgallery/css/lg-thumbnail.css'; - -// import plugins if you need -import lgThumbnail from 'lightgallery/plugins/thumbnail'; -import lgZoom from 'lightgallery/plugins/zoom'; -import lgVideo from 'lightgallery/plugins/video'; +import Carousel from '@components/Carousel/Carousel'; +import CarouselItem from '@components/Carousel/CarouselItem'; interface Props { items: Media[]; + height: number; } -// TODO: Replace the external library for custom module -export default function Gallery({ items }: Props): JSX.Element { - const getUrlFromGoogleDrive = ( - originalUrl: string, - type: MediaType, - ): string => { - // get the file id from the "share" link of google drive - const googleFileId = originalUrl.split('/').at(5); - - if (googleFileId == null) { - return originalUrl; - } - - switch (type) { - case MediaType.Image: - return `https://drive.google.com/uc?export=preview&id=${googleFileId}`; - case MediaType.Video: - return `https://drive.google.com/file/d/${googleFileId}/preview`; - default: - return ''; - } - }; - - const renderItem = (item: Media, index: number): JSX.Element => { - // get the file id from the "share" link of google drive - const url = getUrlFromGoogleDrive(item.url, item.type); - let thumbnail; - - if (item.thumbnail !== undefined) { - thumbnail = getUrlFromGoogleDrive(item.thumbnail, MediaType.Image); - } else { - thumbnail = url; - } - - switch (item.type) { - case MediaType.Image: - return ( - - {item.alt} - - ); - case MediaType.Video: - return ( -
- {item.alt} -
- ); - - default: - break; - } - - return <>; - }; - +export default function Gallery({ items, height = 500 }: Props): JSX.Element { return ( -
- - {items.map(renderItem)} - +
+ + {items.map((item, idx) => ( + + {item.alt} + + ))} +
); } diff --git a/src/content/portafolio/Observacion de clases.md b/src/content/portafolio/Observacion de clases.md index 9e7bfd8..abd87e2 100644 --- a/src/content/portafolio/Observacion de clases.md +++ b/src/content/portafolio/Observacion de clases.md @@ -6,6 +6,9 @@ media: - type: image url: /images/portafolio/observacion_clases/1696878771763.jpg alt: this an image + - type: image + url: /images/portafolio/observacion_clases/1696878771763.jpg + alt: this an image technologies: - React - NodeJS