Improve image display for various aspect ratios
Introduce a SmartImage component that handles both landscape and portrait images, applying a blur-fill background for portrait images to better fit containers. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 517dfa7b-26ac-463d-a6e1-a58c6df97188 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: 96a59edb-4cef-4b27-9ac3-edfc811ef6fe Replit-Helium-Checkpoint-Created: true
This commit is contained in:
parent
8b884324ed
commit
739ec00bc3
BIN
attached_assets/image_1772312049653.png
Normal file
BIN
attached_assets/image_1772312049653.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 141 KiB |
@ -12,7 +12,35 @@ import { PhotoGalleryWidget } from "@/components/photo-gallery";
|
|||||||
import { HoroscopeWidget } from "@/components/horoscope-widget";
|
import { HoroscopeWidget } from "@/components/horoscope-widget";
|
||||||
import { RecipeWidget } from "@/components/recipe-widget";
|
import { RecipeWidget } from "@/components/recipe-widget";
|
||||||
import { NewsWidget } from "@/components/news-widget";
|
import { NewsWidget } from "@/components/news-widget";
|
||||||
import { useState, useEffect, useCallback } from "react";
|
import { useState, useEffect, useCallback, useRef } from "react";
|
||||||
|
|
||||||
|
function SmartImage({ src, alt, className = "" }: { src: string; alt: string; className?: string }) {
|
||||||
|
const imgRef = useRef<HTMLImageElement>(null);
|
||||||
|
const [isPortrait, setIsPortrait] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const img = new Image();
|
||||||
|
img.onload = () => {
|
||||||
|
if (img.naturalHeight > img.naturalWidth * 1.2) {
|
||||||
|
setIsPortrait(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
img.src = src;
|
||||||
|
}, [src]);
|
||||||
|
|
||||||
|
if (isPortrait) {
|
||||||
|
return (
|
||||||
|
<div className="absolute inset-0 overflow-hidden">
|
||||||
|
<img src={src} alt="" className="absolute inset-0 w-full h-full object-cover scale-150 blur-2xl brightness-50" aria-hidden="true" />
|
||||||
|
<img ref={imgRef} src={src} alt={alt} className={`relative w-full h-full object-contain z-[1] ${className}`} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<img ref={imgRef} src={src} alt={alt} className={`w-full h-full object-cover absolute inset-0 ${className}`} style={{ objectPosition: "center 40%" }} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
interface GalleryImage {
|
interface GalleryImage {
|
||||||
folder: string;
|
folder: string;
|
||||||
@ -43,8 +71,8 @@ function HeroCard({ article }: { article: Article }) {
|
|||||||
return (
|
return (
|
||||||
<Link href={`/article/${article.slug}`}>
|
<Link href={`/article/${article.slug}`}>
|
||||||
<div className="relative group cursor-pointer rounded-lg overflow-hidden h-full" data-testid={`card-hero-${article.id}`}>
|
<div className="relative group cursor-pointer rounded-lg overflow-hidden h-full" data-testid={`card-hero-${article.id}`}>
|
||||||
<div className="relative h-full min-h-[300px]">
|
<div className="relative h-full min-h-[280px]">
|
||||||
<img src={article.coverImage || "/images/article-1.png"} alt={article.title} className="w-full h-full object-cover absolute inset-0 transition-transform duration-700 group-hover:scale-105 object-center" loading="lazy" />
|
<SmartImage src={article.coverImage || "/images/article-1.png"} alt={article.title} className="transition-transform duration-700 group-hover:scale-105" />
|
||||||
{isVideo && (
|
{isVideo && (
|
||||||
<div className="absolute inset-0 flex items-center justify-center z-10">
|
<div className="absolute inset-0 flex items-center justify-center z-10">
|
||||||
<div className="w-14 h-14 rounded-full bg-primary/90 flex items-center justify-center group-hover:bg-primary transition-colors shadow-lg">
|
<div className="w-14 h-14 rounded-full bg-primary/90 flex items-center justify-center group-hover:bg-primary transition-colors shadow-lg">
|
||||||
@ -79,7 +107,7 @@ function GalleryHeroCard({ images }: { images: GalleryImage[] }) {
|
|||||||
<Link href="/gallery">
|
<Link href="/gallery">
|
||||||
<div className="relative group cursor-pointer rounded-lg overflow-hidden h-full" data-testid="card-hero-gallery">
|
<div className="relative group cursor-pointer rounded-lg overflow-hidden h-full" data-testid="card-hero-gallery">
|
||||||
<div className="relative h-full min-h-[300px]">
|
<div className="relative h-full min-h-[300px]">
|
||||||
<img src={images[idx].large || images[idx].thumb} alt={images[idx].fileName} className="w-full h-full object-cover object-center absolute inset-0 transition-opacity duration-1000" loading="lazy" />
|
<SmartImage src={images[idx].large || images[idx].thumb} alt={images[idx].fileName} className="transition-opacity duration-1000" />
|
||||||
<div className="absolute inset-0 bg-gradient-to-t from-black/90 via-black/30 to-transparent" />
|
<div className="absolute inset-0 bg-gradient-to-t from-black/90 via-black/30 to-transparent" />
|
||||||
<div className="absolute bottom-0 left-0 right-0 p-5">
|
<div className="absolute bottom-0 left-0 right-0 p-5">
|
||||||
<div className="flex items-center gap-2 mb-2">
|
<div className="flex items-center gap-2 mb-2">
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user