Skip to content

Instantly share code, notes, and snippets.

@jasikpark
Created December 14, 2022 19:31
Show Gist options
  • Save jasikpark/4eec346e56f005cd9b17a8c11f0693aa to your computer and use it in GitHub Desktop.
Save jasikpark/4eec346e56f005cd9b17a8c11f0693aa to your computer and use it in GitHub Desktop.
Tool to generate a responsive `background-image: url("bg-hero.jpg");` for https://defined.net homepage
import { getPicture } from "@astrojs/image";
type BgHeroCSS = {
/** perfect for use w/ define:vars to inject */
cssProperty: string;
/** the source of the regular image */
imageSrc: string;
/** the sourceset used in the image-set */
imageSet: string;
/** the set useful for preloading
@example
<link
slot="head"
rel="preload"
as="image"
href={imageSrc}
imageSrcSet={imageSrcSet}
imageSizes="50vw"
/>
*/
imageSrcSet: string;
};
/** Returns the css rule for responsively setting `bg-hero.jpg` as a bg image
Since this is usually a hero image, it's recommended to preload the image */
export async function getBgHeroCSS(): Promise<BgHeroCSS> {
const originalWidth = 1740;
const { image: bgHeroImage, sources: bgHeroSources } = await getPicture({
src: import("./bg-hero.jpeg") as unknown as Promise<{ default: ImageMetadata }>,
alt: "",
formats: ["avif", "webp", "jpeg"],
widths: [originalWidth],
});
const imageSrc = (bgHeroImage as { src: string }).src;
const bgHeroSourcesRemapped = bgHeroSources.flatMap(({ type, srcset }) => {
const sources = srcset.split(",");
return sources.map((unparsedSource) => {
const [source, width] = unparsedSource.split(" ");
return { type, source, width };
});
});
const regularBgRule = `background-image: url('${imageSrc}');`;
const fullSupportImageSet = `
background-image: image-set(
${bgHeroSourcesRemapped
.map(({ type, source }) => {
return `url('${source}') type("${type}")`;
})
.join(",\n")}
);
`.trim();
const imageSrcSet = bgHeroSourcesRemapped
.map(({ source, width }) => {
const resolution = width === `${originalWidth}w` ? "2x" : "1x";
return `${source} ${resolution}`;
})
.join(", ");
return {
cssProperty: [regularBgRule, fullSupportImageSet].join(""),
imageSrc,
imageSet: fullSupportImageSet,
imageSrcSet,
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment