summaryrefslogtreecommitdiff
path: root/packages/integrations/image/components/Image.astro
diff options
context:
space:
mode:
Diffstat (limited to 'packages/integrations/image/components/Image.astro')
-rw-r--r--packages/integrations/image/components/Image.astro112
1 files changed, 9 insertions, 103 deletions
diff --git a/packages/integrations/image/components/Image.astro b/packages/integrations/image/components/Image.astro
index 51d4182a2..326c1bc6c 100644
--- a/packages/integrations/image/components/Image.astro
+++ b/packages/integrations/image/components/Image.astro
@@ -4,7 +4,7 @@ import loader from 'virtual:image-loader';
import { getImage } from '../src/index.js';
import type { ImageAttributes, ImageMetadata, TransformOptions, OutputFormat } from '../src/types.js';
-export interface LocalImageProps extends Omit<TransformOptions, 'src'>, Omit<ImageAttributes, 'src'> {
+export interface LocalImageProps extends Omit<TransformOptions, 'src'>, Omit<ImageAttributes, 'src' | 'width' | 'height'> {
src: ImageMetadata | Promise<{ default: ImageMetadata }>;
}
@@ -17,109 +17,15 @@ export interface RemoteImageProps extends TransformOptions, ImageAttributes {
export type Props = LocalImageProps | RemoteImageProps;
-function isLocalImage(props: Props): props is LocalImageProps {
- // vite-plugin-astro-image resolves ESM imported images
- // to a metadata object
- return typeof props.src !== 'string';
-}
-
-function parseAspectRatio(aspectRatio: TransformOptions['aspectRatio']) {
- if (!aspectRatio) {
- return undefined;
- }
-
- // parse aspect ratio strings, if required (ex: "16:9")
- if (typeof aspectRatio === 'number') {
- aspectRatio = aspectRatio;
- } else {
- const [width, height] = aspectRatio.split(':');
- aspectRatio = parseInt(width) / parseInt(height);
- }
-}
-
-async function resolveProps(props: Props): Promise<TransformOptions> {
- // For remote images, just check the width/height provided
- if (!isLocalImage(props)) {
- return calculateSize(props);
- }
+const { loading = "lazy", decoding = "async", ...props } = Astro.props as Props;
- let { width, height, aspectRatio, format, ...rest } = props;
-
- // if a Promise<ImageMetadata> was provided, unwrap it first
- const { src, ...metadata } = 'then' in props.src ? (await props.src).default : props.src;
-
- if (!width && !height) {
- // neither dimension was provided, use the file metadata
- width = metadata.width;
- height = metadata.height;
- } else if (width) {
- // one dimension was provided, calculate the other
- let ratio = parseAspectRatio(aspectRatio) || metadata.width / metadata.height;
- height = height || width / ratio;
- } else if (height) {
- // one dimension was provided, calculate the other
- let ratio = parseAspectRatio(aspectRatio) || metadata.width / metadata.height;
- width = width || height * ratio;
- }
-
- return {
- ...rest,
- width,
- height,
- aspectRatio,
- src,
- format: format || metadata.format as OutputFormat,
- }
-}
-
-function calculateSize(transform: TransformOptions): TransformOptions {
- // keep width & height as provided
- if (transform.width && transform.height) {
- return transform;
- }
-
- if (!transform.width && !transform.height) {
- throw new Error(`"width" and "height" cannot both be undefined`);
- }
-
- if (!transform.aspectRatio) {
- throw new Error(`"aspectRatio" must be included if only "${transform.width ? "width": "height"}" is provided`)
- }
-
- let aspectRatio: number;
+const attrs = await getImage(loader, props);
+---
- // parse aspect ratio strings, if required (ex: "16:9")
- if (typeof transform.aspectRatio === 'number') {
- aspectRatio = transform.aspectRatio;
- } else {
- const [width, height] = transform.aspectRatio.split(':');
- aspectRatio = parseInt(width) / parseInt(height);
- }
+<img {...attrs} {loading} {decoding} />
- if (transform.width) {
- // only width was provided, calculate height
- return {
- ...transform,
- width: transform.width,
- height: transform.width / aspectRatio
- };
- } else if (transform.height) {
- // only height was provided, calculate width
- return {
- ...transform,
- width: transform.height * aspectRatio,
- height: transform.height
- }
+<style>
+ img {
+ content-visibility: auto;
}
-
- return transform;
-}
-
-const props = Astro.props as Props;
-
-const imageProps = await resolveProps(props);
-
-const attrs = await getImage(loader, imageProps);
----
-
-<img {...attrs} />
+</style>