Last active
February 27, 2025 18:17
-
-
Save jwoyo/83b3a06acc6fb14c422977be5764810c to your computer and use it in GitHub Desktop.
Astro image component with zoom and astro-cloudinary
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
// This component is a wrapper around the Cloudinary Image component that adds a Photoswipe lightbox to the image. | |
// Only to be used for images in the documentation content to ensure good SEO results. Extend for other use cases as needed. | |
import { getCldOgImageUrl } from "astro-cloudinary/helpers"; | |
import { CldImage } from "astro-cloudinary"; | |
import "photoswipe/style.css"; | |
export type Props = { | |
id: string; | |
type: keyof typeof mediaTypes; | |
alt: string; | |
}; | |
const mediaTypes = { | |
screenshot: { | |
width: 3024, | |
height: 1964, | |
// 80vw should be 100vw on mobiles however, screenshots are useless on mobiles | |
sizes: "(max-width: 800px) 80vw, (max-width: 1152px) 66vw, 33vw", | |
}, | |
}; | |
const { id, type, alt } = Astro.props; | |
if (!id) { | |
throw new Error("Please provide an id for the image."); | |
} | |
if (!alt) { | |
throw new Error( | |
`The image ${id} is missing an alt attribute. This is important for SEO and people with disabilities.`, | |
); | |
} | |
if (mediaTypes[type] === undefined) { | |
throw new Error( | |
`This component currently only supports the following types: ${Object.keys( | |
mediaTypes, | |
).join(", ")}`, | |
); | |
} | |
const url = getCldOgImageUrl({ | |
src: id, | |
width: mediaTypes[type].width, | |
height: mediaTypes[type].height, | |
}); | |
--- | |
<div class="psi [.sl-steps_&]:mt-2"> | |
<a | |
data-pswp-width={mediaTypes[type].width} | |
data-pswp-height={mediaTypes[type].height} | |
href={url} | |
> | |
<CldImage | |
src={id} | |
alt={alt} | |
width={mediaTypes[type].width} | |
height={mediaTypes[type].height} | |
sizes={mediaTypes[type].sizes} | |
/> | |
</a> | |
</div> | |
<script> | |
import pswpModule from "photoswipe"; | |
import PhotoSwipeLightbox from "photoswipe/lightbox"; | |
window.addEventListener("load", () => { | |
const lightbox = new PhotoSwipeLightbox({ | |
pswpModule, | |
children: "a", | |
gallery: ".psi", | |
}); | |
lightbox.init(); | |
}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment