feat: use srcset/sizes for all images

This commit is contained in:
max_richter 2023-08-11 16:37:54 +02:00
parent 0acbbd6905
commit 0eb8ebdd16
4 changed files with 47 additions and 16 deletions

View File

@ -1,5 +1,34 @@
import { asset } from "$fresh/runtime.ts"; import { asset } from "$fresh/runtime.ts";
import * as CSS from "https://esm.sh/csstype@3.1.2"; import * as CSS from "https://esm.sh/csstype@3.1.2";
import { isLocalImage } from "@lib/string.ts";
interface ResponsiveAttributes {
srcset: string;
sizes: string;
}
function generateResponsiveAttributes(
imageUrl: string,
widths: number[],
baseApiUrl: string,
sizes = "100vw",
): ResponsiveAttributes {
const srcsets: string[] = [];
for (const width of widths) {
const apiUrl = `${baseApiUrl}?image=${imageUrl}&width=${width}`;
srcsets.push(`${apiUrl} ${width}w`);
}
const srcset = srcsets.join(", ");
return {
srcset,
sizes,
};
}
const widths = [320, 640, 960, 1280]; // List of widths for srcset
const Image = ( const Image = (
props: { props: {
@ -12,6 +41,12 @@ const Image = (
style?: CSS.HtmlAttributes; style?: CSS.HtmlAttributes;
}, },
) => { ) => {
const responsiveAttributes: ResponsiveAttributes = isLocalImage(props.src)
? generateResponsiveAttributes(props.src, widths, "/api/images")
: { srcset: "", sizes: "" };
console.log({ src: props.src, responsiveAttributes });
return ( return (
<span <span
style={{ style={{
@ -28,6 +63,8 @@ const Image = (
loading="lazy" loading="lazy"
alt={props.alt} alt={props.alt}
style={props.style} style={props.style}
srcset={responsiveAttributes.srcset}
sizes={responsiveAttributes.sizes}
src={asset(props.src)} src={asset(props.src)}
width={props.width} width={props.width}
height={props.height} height={props.height}

View File

@ -4,7 +4,6 @@ import {
IconEdit, IconEdit,
IconExternalLink, IconExternalLink,
} from "@components/icons.tsx"; } from "@components/icons.tsx";
import { isLocalImage } from "@lib/string.ts";
import Image from "@components/Image.tsx"; import Image from "@components/Image.tsx";
export function RecipeHero( export function RecipeHero(
@ -20,20 +19,16 @@ export function RecipeHero(
) { ) {
const { meta: { image } = {} } = data; const { meta: { image } = {} } = data;
const imageUrl = (image && isLocalImage(image))
? `/api/images?image=${image}&width=800`
: image;
return ( return (
<div <div
class={`flex justify-between flex-col relative w-full min-h-[${ class={`flex justify-between flex-col relative w-full min-h-[${
imageUrl ? 400 : 200 image ? 400 : 200
}px] rounded-3xl overflow-hidden`} }px] rounded-3xl overflow-hidden`}
> >
{imageUrl && {image &&
( (
<Image <Image
src={imageUrl} src={image}
thumbnail={data.meta?.thumbnail} thumbnail={data.meta?.thumbnail}
alt="Recipe Banner" alt="Recipe Banner"
style={{ objectPosition: "0% 25%" }} style={{ objectPosition: "0% 25%" }}
@ -52,7 +47,7 @@ export function RecipeHero(
( (
<a <a
class={`px-4 py-2 ${ class={`px-4 py-2 ${
imageUrl ? "bg-gray-300 text-gray-800" : "text-gray-200" image ? "bg-gray-300 text-gray-800" : "text-gray-200"
} rounded-lg flex gap-1 items-center`} } rounded-lg flex gap-1 items-center`}
href={editLink} href={editLink}
> >
@ -62,18 +57,16 @@ export function RecipeHero(
</div> </div>
<div <div
class={`relative inset-x-0 py-4 px-8 ${imageUrl ? "py-8" : ""} `} class={`relative inset-x-0 py-4 px-8 ${image ? "py-8" : ""} `}
> >
<div <div
class={`${ class={`${
imageUrl ? "noisy-gradient" : "" image ? "noisy-gradient" : ""
} after:opacity-90 flex gap-4 items-center ${ } after:opacity-90 flex gap-4 items-center ${image ? "pt-12" : ""}`}
imageUrl ? "pt-12" : ""
}`}
> >
<h2 <h2
class="relative text-4xl font-bold z-10" class="relative text-4xl font-bold z-10"
style={{ color: imageUrl ? "#1F1F1F" : "white" }} style={{ color: image ? "#1F1F1F" : "white" }}
> >
{data.name} {data.name}
{data.meta?.link && {data.meta?.link &&
@ -95,7 +88,7 @@ export function RecipeHero(
( (
<div <div
class={`relative z-50 flex gap-5 font-sm text-light mt-3`} class={`relative z-50 flex gap-5 font-sm text-light mt-3`}
style={{ color: imageUrl ? "#1F1F1F" : "white" }} style={{ color: image ? "#1F1F1F" : "white" }}
> >
{subline.filter((s) => s && s?.length > 1).map((s) => { {subline.filter((s) => s && s?.length > 1).map((s) => {
return <span>{s}</span>; return <span>{s}</span>;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 936 KiB

After

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because one or more lines are too long