Skip to content

Instantly share code, notes, and snippets.

@leomp12
Created March 24, 2023 00:27
Show Gist options
  • Select an option

  • Save leomp12/43722b7be985187d07e7c9dcbbd271a0 to your computer and use it in GitHub Desktop.

Select an option

Save leomp12/43722b7be985187d07e7c9dcbbd271a0 to your computer and use it in GitHub Desktop.
Astro <Picture> with width/height automatically set
---
import { Picture } from '@astrojs/image/components';
import { resolve as resolvePath } from 'node:path';
import imageSize from 'image-size';
type PictureProps = Parameters<typeof Picture>[0];
export type Props = Omit<PictureProps, 'aspectRatio'> & {
aspectRatio?: PictureProps['aspectRatio'],
fetchpriority?: 'high' | 'low' | 'auto',
};
const tryImageSize = (src: string) => {
let dimensions: { width?: number, height?: number } = {};
if (typeof src === 'string' && src.startsWith('/')) {
try {
dimensions = imageSize(resolvePath(process.cwd(), `public${src}`));
} catch (e) {
dimensions = {};
}
}
return dimensions;
};
const getAspectRatio = (src: string | { width?: number, height?: number }) => {
if (typeof src === 'string') {
src = tryImageSize(src);
}
if (src.width) {
return src.height ? src.width / src.height : 1;
}
return 0;
};
const props = Astro.props as PictureProps;
if (
(!props.width || !props.height)
&& !props.aspectRatio
&& typeof props.src === 'string'
) {
const { width, height } = tryImageSize(props.src);
if (height) {
props.aspectRatio = getAspectRatio({ width, height });
props.width = width;
props.height = height;
}
}
---
<Picture {...props} />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment