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 * 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 = (
props: {
@ -12,6 +41,12 @@ const Image = (
style?: CSS.HtmlAttributes;
},
) => {
const responsiveAttributes: ResponsiveAttributes = isLocalImage(props.src)
? generateResponsiveAttributes(props.src, widths, "/api/images")
: { srcset: "", sizes: "" };
console.log({ src: props.src, responsiveAttributes });
return (
<span
style={{
@ -28,6 +63,8 @@ const Image = (
loading="lazy"
alt={props.alt}
style={props.style}
srcset={responsiveAttributes.srcset}
sizes={responsiveAttributes.sizes}
src={asset(props.src)}
width={props.width}
height={props.height}

View File

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