fakhr-khaleej-blog
Version:
Moving and relocation services blog
119 lines (110 loc) • 3.53 kB
JavaScript
import React, { useState, useEffect } from 'react';
import Image from 'next/image';
// تأثير التمويه للصور أثناء التحميل
const shimmer = (w, h) => `
<svg width="${w}" height="${h}" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="g">
<stop stop-color="#f6f7f8" offset="20%" />
<stop stop-color="#edeef1" offset="50%" />
<stop stop-color="#f6f7f8" offset="70%" />
</linearGradient>
</defs>
<rect width="${w}" height="${h}" fill="#f6f7f8" />
<rect id="r" width="${w}" height="${h}" fill="url(#g)" />
<animate xlink:href="#r" attributeName="x" from="-${w}" to="${w}" dur="1s" repeatCount="indefinite" />
</svg>`;
const toBase64 = (str) => typeof window === 'undefined'
? Buffer.from(str).toString('base64')
: window.btoa(str);
const ImageLoader = ({
src,
alt,
width = 800,
height = 600,
priority = false,
loading = "lazy",
className = '',
style = {},
sizes = "(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw",
objectFit = "cover",
objectPosition = "center",
quality = 80,
unoptimized = false,
decoding = "async",
lazyBoundary = "200px",
fetchpriority = null,
caption = "",
layout = 'responsive'
}) => {
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(false);
// معالجة المسار الصحيح للصورة
const imagePath = src.startsWith('/') ? src : `/${src}`;
// التصميم الافتراضي للصورة - يتم تطبيق objectFit و objectPosition بشكل صحيح
const imageStyle = {
transition: 'all 0.3s ease-in-out',
objectFit,
objectPosition,
...style
};
// إعداد وظائف معالجة الأحداث
const handleLoad = () => {
setIsLoading(false);
};
const handleError = () => {
setError(true);
setIsLoading(false);
};
// للصور في المجلد العام، يستخدم Next.js تحسينات أساسية
return (
<figure className={`relative ${isLoading ? 'pulse-animation' : ''}`}>
<div className={isLoading ? 'opacity-50' : 'opacity-100'}>
<Image
src={error ? '/images/placeholder.jpg' : imagePath}
alt={alt || 'صورة'}
title={alt}
width={width}
height={height}
priority={priority}
loading={priority ? "eager" : loading}
style={imageStyle}
className={`${className} ${isLoading ? 'blur-sm' : 'blur-0'}`}
quality={quality}
sizes={sizes}
placeholder="blur"
blurDataURL={`data:image/svg+xml;base64,${toBase64(shimmer(width, height))}`}
onLoad={handleLoad}
onError={handleError}
unoptimized={unoptimized}
decoding={decoding}
lazyBoundary={lazyBoundary}
fetchpriority={priority ? "high" : fetchpriority}
layout={layout}
/>
</div>
{caption && (
<figcaption className="text-sm font-tajawal text-gray-600 mt-2 text-center">
{caption}
</figcaption>
)}
<style jsx global>{`
.pulse-animation {
animation: pulse 1.5s infinite;
}
@keyframes pulse {
0% {
opacity: 1;
}
50% {
opacity: 0.8;
}
100% {
opacity: 1;
}
}
`}</style>
</figure>
);
};
export default ImageLoader;