Blur loader I used throughout this website.
Inspired by Colby Fayock Blog Post.
CloudinaryImg Component
import { buildUrl } from 'cloudinary-build-url';
import clsx from 'clsx';
import Image from 'next/image';
import * as React from 'react';
import Lightbox from 'react-image-lightbox';
import 'react-image-lightbox/style.css';
type CloudinaryImgType = {
publicId: string,
height: string | number,
width: string | number,
alt: string,
title?: string,
className?: string,
preview?: boolean,
noStyle?: boolean,
aspect?: {
width: number,
height: number,
},
mdx?: boolean,
} & React.ComponentPropsWithoutRef<'figure'>;
export default function CloudinaryImg({
publicId,
height,
width,
alt,
title,
className,
preview = true,
noStyle = false,
mdx = false,
style,
aspect,
...rest
}: CloudinaryImgType) {
const [isOpen, setIsOpen] = React.useState < boolean > false;
const urlBlurred = buildUrl(publicId, {
cloud: {
cloudName: 'theodorusclarence',
},
transformations: {
effect: {
name: 'blur:1000',
},
quality: 1,
rawTransformation: aspect
? `c_fill,ar_${aspect.width}:${aspect.height},w_${width}`
: undefined,
},
});
const url = buildUrl(publicId, {
cloud: {
cloudName: 'theodorusclarence',
},
transformations: {
rawTransformation: aspect
? `c_fill,ar_${aspect.width}:${aspect.height},w_${width}`
: undefined,
},
});
const aspectRatio = aspect ? aspect.height / aspect.width : undefined;
return (
<figure
className={clsx(className, {
'overflow-hidden rounded shadow-sm dark:shadow-none': !noStyle,
'mx-auto': mdx && width <= 800,
})}
style={{
...(mdx && width <= 800 ? { maxWidth: width } : {}),
...style,
}}
{...rest}
>
<div
style={{
position: 'relative',
height: 0,
paddingTop: aspectRatio
? `${aspectRatio * 100}%`
: `${(+height / +width) * 100}%`,
cursor: preview ? 'zoom-in' : 'default',
}}
className='img-blur'
onClick={preview ? () => setIsOpen(true) : undefined}
>
<style jsx>{`
.img-blur::before {
content: '';
position: absolute;
inset: 0;
filter: blur(20px);
z-index: 0;
background-image: url(${urlBlurred});
background-position: center center;
background-size: 100%;
}
`}</style>
<div className='absolute top-0 left-0'>
<Image
width={width}
height={height}
src={url}
alt={alt}
title={title || alt}
/>
</div>
</div>
{isOpen && (
<Lightbox mainSrc={url} onCloseRequest={() => setIsOpen(false)} />
)}
</figure>
);
}
jsx
Usage
1. For full width
<figure className='overflow-hidden rounded-sm shadow-md dark:shadow-none'>
<CloudinaryImg
publicId='theodorusclarence/cloudinaryId.jpg'
width='1440'
height='792'
alt='Your alt text'
/>
</figure>
jsx
2. For specified width and centered
If not using jit or in mdx, width can be replaced by using inline-style
<figure className='w-[210px] mx-auto shadow-md dark:shadow-none'>
<CloudinaryImg
publicId='theodorusclarence/cloudinaryId.png'
width='210'
height='149'
alt='Your alt text'
/>
</figure>
jsx