add responsive image sizes
@ -51,7 +51,9 @@
|
|||||||
<link
|
<link
|
||||||
rel="preload"
|
rel="preload"
|
||||||
as="image"
|
as="image"
|
||||||
href="/blasse-seide-hero-product.webp"
|
href="/images/hero/768/blasse-seide-hero-product.webp"
|
||||||
|
imagesrcset="/images/hero/480/blasse-seide-hero-product.webp 480w, /images/hero/768/blasse-seide-hero-product.webp 768w, /images/hero/960/blasse-seide-hero-product.webp 960w, /blasse-seide-hero-product.webp 1078w"
|
||||||
|
imagesizes="(max-width: 760px) 92vw, (max-width: 1180px) 45vw, 768px"
|
||||||
fetchpriority="high"
|
fetchpriority="high"
|
||||||
/>
|
/>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 22 KiB |
@ -1,5 +1,11 @@
|
|||||||
import { Link } from "react-router";
|
import { Link } from "react-router";
|
||||||
import IntroOverlay from "./IntroOverlay";
|
import IntroOverlay from "./IntroOverlay";
|
||||||
|
import {
|
||||||
|
HERO_PRODUCT_IMAGE_SIZES,
|
||||||
|
buildPublicImageSrcSet,
|
||||||
|
} from "../../utils/responsiveImages";
|
||||||
|
|
||||||
|
const HERO_PRODUCT_IMAGE = "/blasse-seide-hero-product.webp";
|
||||||
|
|
||||||
function HeroSection({
|
function HeroSection({
|
||||||
heroImageWrapRef,
|
heroImageWrapRef,
|
||||||
@ -34,7 +40,13 @@ function HeroSection({
|
|||||||
<figure className="hero-product">
|
<figure className="hero-product">
|
||||||
<div className="hero-product__inner" ref={setDescriptionRef}>
|
<div className="hero-product__inner" ref={setDescriptionRef}>
|
||||||
<img
|
<img
|
||||||
src="/blasse-seide-hero-product.webp"
|
src={HERO_PRODUCT_IMAGE}
|
||||||
|
srcSet={buildPublicImageSrcSet(HERO_PRODUCT_IMAGE, {
|
||||||
|
folder: "/images/hero",
|
||||||
|
widths: [480, 768, 960],
|
||||||
|
originalWidth: 1078,
|
||||||
|
})}
|
||||||
|
sizes={HERO_PRODUCT_IMAGE_SIZES}
|
||||||
alt="Blasse Seide Parfumflakon auf einer dunklen Produktkarte"
|
alt="Blasse Seide Parfumflakon auf einer dunklen Produktkarte"
|
||||||
className="hero-product__image"
|
className="hero-product__image"
|
||||||
loading="eager"
|
loading="eager"
|
||||||
|
|||||||
@ -14,6 +14,10 @@ import SharedNavbar from "../components/SharedNavbar";
|
|||||||
import PageMeta from "../components/seo/PageMeta";
|
import PageMeta from "../components/seo/PageMeta";
|
||||||
import perfumes from "../data/perfumes";
|
import perfumes from "../data/perfumes";
|
||||||
import { useProductTransition } from "../transitions/ProductTransitionContext";
|
import { useProductTransition } from "../transitions/ProductTransitionContext";
|
||||||
|
import {
|
||||||
|
PRODUCT_CARD_IMAGE_SIZES,
|
||||||
|
buildPublicImageSrcSet,
|
||||||
|
} from "../utils/responsiveImages";
|
||||||
import "../pages/LandingPage.css";
|
import "../pages/LandingPage.css";
|
||||||
import "../style/navbar.css";
|
import "../style/navbar.css";
|
||||||
|
|
||||||
@ -504,6 +508,12 @@ function LandingPage() {
|
|||||||
<div className="product-image-wrap">
|
<div className="product-image-wrap">
|
||||||
<img
|
<img
|
||||||
src={item.image}
|
src={item.image}
|
||||||
|
srcSet={buildPublicImageSrcSet(item.image, {
|
||||||
|
folder: "/images/products",
|
||||||
|
widths: [540, 720],
|
||||||
|
originalWidth: 1080,
|
||||||
|
})}
|
||||||
|
sizes={PRODUCT_CARD_IMAGE_SIZES}
|
||||||
alt={item.name}
|
alt={item.name}
|
||||||
className="product-image"
|
className="product-image"
|
||||||
data-product-transition-source
|
data-product-transition-source
|
||||||
|
|||||||
14
parfum-shop/src/utils/responsiveImages.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
export const PRODUCT_CARD_IMAGE_SIZES =
|
||||||
|
"(min-width: 1280px) 520px, (min-width: 1024px) 31vw, (min-width: 768px) 46vw, 92vw";
|
||||||
|
|
||||||
|
export const HERO_PRODUCT_IMAGE_SIZES =
|
||||||
|
"(max-width: 760px) 92vw, (max-width: 1180px) 45vw, 768px";
|
||||||
|
|
||||||
|
export function buildPublicImageSrcSet(src, { folder, widths, originalWidth }) {
|
||||||
|
const fileName = src.replace(/^\//, "");
|
||||||
|
const variants = widths.map(
|
||||||
|
(width) => `${folder}/${width}/${fileName} ${width}w`
|
||||||
|
);
|
||||||
|
|
||||||
|
return [...variants, `${src} ${originalWidth}w`].join(", ");
|
||||||
|
}
|
||||||