From fab698d676d43a46b0fd5df592915ca12111dbcb Mon Sep 17 00:00:00 2001 From: Michael Hunteman Date: Fri, 1 Nov 2024 14:10:11 -0700 Subject: Blurry load --- client/src/blurry-load.css | 8 +++++++ client/src/components/AdminLogin.tsx | 2 +- client/src/components/BlurryLoadDiv.tsx | 21 ++++++++++++++++++ client/src/components/BlurryLoadImg.tsx | 15 +++++++++++++ client/src/components/Home.tsx | 28 ++++++++++++++---------- client/src/components/Schedule.tsx | 11 ++++++---- client/src/useBlurryLoad.ts | 38 +++++++++++++++++++++++++++++++++ 7 files changed, 107 insertions(+), 16 deletions(-) create mode 100644 client/src/blurry-load.css create mode 100644 client/src/components/BlurryLoadDiv.tsx create mode 100644 client/src/components/BlurryLoadImg.tsx create mode 100644 client/src/useBlurryLoad.ts (limited to 'client/src') diff --git a/client/src/blurry-load.css b/client/src/blurry-load.css new file mode 100644 index 0000000..df1dd09 --- /dev/null +++ b/client/src/blurry-load.css @@ -0,0 +1,8 @@ +.blurry-load { + filter: blur(6px); + transition: all .6s ease-in; +} + +.blur-out { + filter: none!important +} \ No newline at end of file diff --git a/client/src/components/AdminLogin.tsx b/client/src/components/AdminLogin.tsx index f1f676f..4d722e8 100644 --- a/client/src/components/AdminLogin.tsx +++ b/client/src/components/AdminLogin.tsx @@ -107,7 +107,7 @@ function GuestLogin() { endAdornment: ( - {showPassword ? : } + {showPassword ? : } ), diff --git a/client/src/components/BlurryLoadDiv.tsx b/client/src/components/BlurryLoadDiv.tsx new file mode 100644 index 0000000..1dfe07e --- /dev/null +++ b/client/src/components/BlurryLoadDiv.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { ClassAttributes, ImgHTMLAttributes } from 'react'; +import { JSX } from 'react/jsx-runtime'; +import { useBlurryLoad } from '../useBlurryLoad.ts'; +import { useMediaQuery } from '@mui/material'; + +export const BlurryLoadDiv = ( + props: JSX.IntrinsicAttributes & + ClassAttributes & + ImgHTMLAttributes & { 'data-large': string } +) => { + const isMobile = useMediaQuery('(max-width: 768px)'); + let blurry = ''; + if (!isMobile) { + useBlurryLoad(); + blurry = 'blurry-load'; + } + return ( +
+ ); +}; diff --git a/client/src/components/BlurryLoadImg.tsx b/client/src/components/BlurryLoadImg.tsx new file mode 100644 index 0000000..c28aa45 --- /dev/null +++ b/client/src/components/BlurryLoadImg.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { ClassAttributes, ImgHTMLAttributes } from 'react'; +import { JSX } from 'react/jsx-runtime'; +import { useBlurryLoad } from '../useBlurryLoad.ts'; + +export const BlurryLoadImg = ( + props: JSX.IntrinsicAttributes & + ClassAttributes & + ImgHTMLAttributes & { 'data-large': string } +) => { + useBlurryLoad(); + return ( + + ); +}; diff --git a/client/src/components/Home.tsx b/client/src/components/Home.tsx index f735195..79743a5 100644 --- a/client/src/components/Home.tsx +++ b/client/src/components/Home.tsx @@ -1,30 +1,33 @@ import React from 'react'; import { useEffect, useState } from 'react'; import './Carousel.css'; -import p0 from '/EngagmentSession_06.23.2024-131.jpg'; -import p1 from '/EngagmentSession_06.23.2024-161.jpg'; -import p2 from '/EngagmentSession_06.23.2024-164.jpg'; -import p3 from '/EngagmentSession_06.23.2024-259.jpg'; -import p4 from '/EngagmentSession_06.23.2024-267.jpg'; -import p5 from '/EngagmentSession_06.23.2024-284.jpg'; +import { BlurryLoadImg } from './BlurryLoadImg'; + +const images = [ + { small: '/small/engagement1.webp', full: '/full/engagement1.jpg' }, + { small: '/small/engagement2.webp', full: '/full/engagement2.jpg' }, + { small: '/small/engagement3.webp', full: '/full/engagement3.jpg' }, + { small: '/small/engagement4.webp', full: '/full/engagement4.jpg' }, + { small: '/small/engagement5.webp', full: '/full/engagement5.jpg' }, + { small: '/small/engagement6.webp', full: '/full/engagement6.jpg' }, +]; function Home() { const [currentIndex, setIndex] = useState(0); - const photos = [p0, p1, p2, p3, p4, p5]; useEffect(() => { const interval = setInterval(() => { setIndex((prevIndex) => - prevIndex === photos.length - 1 ? 0 : prevIndex + 1 + prevIndex === images.length - 1 ? 0 : prevIndex + 1 ); }, 3000); return () => clearInterval(interval); - }, [photos.length]); + }, [images.length]); return (
- {photos.map((photo, index) => ( + {images.map((image, index) => (
- +
))}
diff --git a/client/src/components/Schedule.tsx b/client/src/components/Schedule.tsx index 64140e4..dfe4a30 100644 --- a/client/src/components/Schedule.tsx +++ b/client/src/components/Schedule.tsx @@ -6,10 +6,10 @@ import { useMediaQuery, useTheme, } from '@mui/material'; -import divineShepherd from '/divine-shepherd.jpg'; import InsertInvitationIcon from '@mui/icons-material/InsertInvitation'; import { useAppDispatch } from '../hooks'; import { showDialog } from '../slices/uiSlice'; +import { BlurryLoadDiv } from './BlurryLoadDiv'; function Schedule() { const dispatch = useAppDispatch(); @@ -21,15 +21,18 @@ function Schedule() { }; return ( -
-
+ ); } diff --git a/client/src/useBlurryLoad.ts b/client/src/useBlurryLoad.ts new file mode 100644 index 0000000..59069d2 --- /dev/null +++ b/client/src/useBlurryLoad.ts @@ -0,0 +1,38 @@ +import { useEffect } from 'react'; +import './blurry-load.css'; + +export interface UseBlurryLoadProps { + toBlurImages?: Element[]; +} + +export const useBlurryLoad = (props?: UseBlurryLoadProps) => { + const { toBlurImages = [] } = props ?? {}; + + useEffect(() => { + const images: Element[] = [...toBlurImages]; + if (toBlurImages.length === 0) { + images.push(...document.querySelectorAll('.blurry-load')); + } + + const lazyImageObserver = new IntersectionObserver(function (entries) { + entries.forEach(function (entry) { + if (!entry.isIntersecting) return; + + const image = entry.target; + const currentImage = new Image(); + currentImage.setAttribute( + 'src', + image.getAttribute('data-large') ?? '' + ); + + currentImage.onload = () => { + image.setAttribute('src', currentImage.src); + image.classList.add('blur-out'); + }; + lazyImageObserver.unobserve(image); + }); + }); + + images.forEach((img) => lazyImageObserver.observe(img)); + }, [toBlurImages]); +}; -- cgit v1.2.3