UNPKG

fakhr-khaleej-blog

Version:
119 lines (110 loc) 3.53 kB
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;