ویژگی تصویر

افکت پخش نور روی تصویر با CSS

  /  CSS   /  افکت پخش نور روی تصویر با CSS
بنر تبلیغاتی الف

افکت پخش نور (light spread/glow) روی تصاویر یکی از روش‌های جذاب برای جلب توجه و افزایش حس عمق در طراحی وب است. این افکت می‌تواند به‌صورت نقطه‌ای (spotlight)، هاله‌ای نرم (glow)، یا نور متحرک اجرا شود. در این مقاله به روش‌های متفاوت پیاده‌سازی با CSS و ترکیب با SVG، بهینه‌سازی عملکرد و مثال‌های عملی می‌پردازیم.

چرا از افکت پخش نور استفاده کنیم؟

  • جذب توجه کاربر به بخش خاصی از تصویر یا کارت محتوا
  • افزایش حس سه‌بعدی و واقع‌گرایی
  • ایجاد تاکید در عناصر رابط کاربری مانند کارت‌ها، بنرها و کاورها

روش‌های اصلی پیاده‌سازی

  • پوشش با radial-gradient در عناصر شبه (::before / ::after)
  • استفاده از mix-blend-mode برای ترکیب نور با تصویر
  • فیلترها مانند filter: blur() و drop-shadow()
  • SVG filters (مثل feGaussianBlur، feMerge) برای کنترل دقیق‌تر و performance بهتر در بعضی موارد

مثال 1 — هاله نور ساده با pseudo-element و radial-gradient

<div class="card">
  <img src="photo.jpg" alt="">
</div>

.card {
  position: relative;
  display: inline-block;
  overflow: hidden;
}
.card img {
  display: block;
  width: 100%;
  height: auto;
}
.card::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 30%;
  width: 60%;
  height: 60%;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle at center, rgba(255,255,200,0.6), rgba(255,255,200,0.1) 40%, transparent 70%);
  pointer-events: none;
  mix-blend-mode: screen;
  filter: blur(8px);
}

توضیح: این کد یک عنصر pseudoelement (::before) ایجاد می‌کند که روی تصویر قرار می‌گیرد. از radial-gradient برای ساختن هاله نور استفاده شده و mix-blend-mode: screen باعث می‌شود هاله با تصویر به‌خوبی ترکیب شود. فیلتر blur نرم‌تر بودن لبه‌ها را تولید می‌کند. pointer-events: none مانع از تداخل با تعامل کاربران می‌شود.

مثال 2 — نور متحرک قابل کنترل با keyframes

<div class="cover">
  <img src="landscape.jpg" alt="">
</div>

.cover {
  position: relative;
  overflow: hidden;
}
.cover img {
  display: block;
  width: 100%;
  height: auto;
}
.cover::after {
  content: "";
  position: absolute;
  left: -30%;
  top: 50%;
  width: 40%;
  height: 120%;
  background: radial-gradient(circle at 30% 30%, rgba(255,255,220,0.6), transparent 50%);
  transform: translateY(-50%) rotate(20deg);
  filter: blur(18px);
  pointer-events: none;
  mix-blend-mode: screen;
  animation: sweep 4s infinite linear;
}
@keyframes sweep {
  0% { left: -50%; }
  50% { left: 60%; }
  100% { left: 120%; }
}

توضیح: این مثال یک نوار نور را به‌صورت متحرک روی تصویر می‌کشاند. استفاده از transform و animation باعث می‌شود حرکت نرم و قابل پیش‌بینی باشد. برای عملکرد بهتر، در ادامه نکات بهینه‌سازی را خواهیم گفت.

مثال 3 — نسخه بهینه‌تر: استفاده از transform و will-change

.cover::after {
  /* ... */  will-change: transform;
  backface-visibility: hidden;
  /* animation uses transform: translateX instead of left */}
@keyframes sweep {
  0% { transform: translateX(-200%) translateY(-50%) rotate(20deg); }
  100% { transform: translateX(200%) translateY(-50%) rotate(20deg); }
}

توضیح: به جای تغییر موقعیت با left که باعث repaint می‌شود، با تغییر transform تنها نیاز به composite در GPU است. will-change به مرورگر اطلاع می‌دهد که عنصر به زودی تغییر می‌کند و می‌تواند بهینه‌سازی‌هایی را اعمال کند.

مثال 4 — استفاده از SVG filters برای bloom/soft glow

<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0">
  <filter id="bloom">
    <feGaussianBlur stdDeviation="8" result="blur"/>
    <feMerge>
      <feMergeNode in="blur"/>
      <feMergeNode in="SourceGraphic"/>
    </feMerge>
  </filter>
</svg>

.img-with-bloom {
  filter: url(#bloom);
}

توضیح: فیلترهای SVG کنترل بیشتری روی ترتیب ترکیب و شدت بلور می‌دهند. در این مثال ابتدا تصویر بلور می‌شود و سپس با تصویر اصلی merge می‌گردد تا افکت bloom حاصل شود. این روش در برخی مرورگرها عملکرد بهتری نسبت به CSS filter دارد و می‌توان فیلترهای پیچیده‌تر (مثل feSpecularLighting) نیز استفاده کرد.

نکات بهینه‌سازی عملکرد

  • از transform برای حرکت استفاده کنید نه left/top (بیشتر از composite GPU استفاده می‌کند).
  • فیلترهای blur سنگین روی عناصر بزرگ هزینه‌بر هستند؛ اندازه تصویر یا مقدار blur را کاهش دهید.
  • will-change را هوشمندانه به کار ببرید و پس از اتمام انیمیشن مقدار را حذف کنید.
  • در موبایل از افکت‌های سبک‌تر یا تصاویر پیش‌پردازش‌شده با هاله استفاده کنید تا مصرف باتری و CPU کاهش یابد.
  • در صورت نیاز به چند افکت همزمان، تلاش کنید از یک تصویر overlay استفاده کنید تا تعداد لایه‌ها کم شود.

جدول کوتاه از پراپرتی‌های مفید

پراپرتیکاربردنکته
radial-gradientساخت هاله نورقابل استفاده در pseudo-elements
mix-blend-modeترکیب رنگ‌ها با تصویرscreen و overlay پرکاربرد
filter: blur()نرم کردن لبه‌هاهزینه بالا برای عناصر بزرگ
SVG filtersکنترل پیشرفته بر افکتقابل استفاده در برخی مرورگرها بهتر

موارد استفاده واقعی و نکات طراحی

  • روی کاور صفحه اصلی برای جلب توجه به عنوان یا CTA
  • در کارت‌های محصول برای برجسته کردن کالاهای ویژه
  • به‌عنوان افکت hover که نور به سمت مکان موس حرکت می‌کند (با JS برای دنبال کردن موس)

نمونه ترکیب با جاوااسکریپت (ایده)

// idea: move spotlight to mouse position
document.querySelector('.card').addEventListener('mousemove', e => {
  const rect = e.currentTarget.getBoundingClientRect();
  const x = ((e.clientX - rect.left) / rect.width) * 100;
  const y = ((e.clientY - rect.top) / rect.height) * 100;
  e.currentTarget.style.setProperty('--mx', x + '%');
  e.currentTarget.style.setProperty('--my', y + '%');
});

توضیح: این قطعه JS مختصر موقعیت موس را محاسبه و به CSS به‌صورت custom property منتقل می‌کند. سپس می‌توان در radial-gradient از var(–mx) و var(–my) برای جا‌به‌جایی مرکز نور استفاده کرد. این روش نسبت به اعمال تغییرات مستقیم سبک بهتر و پاسخگوتر است.

جمع‌بندی و نکته نهایی

افکت پخش نور روی تصویر با CSS می‌تواند ظاهری حرفه‌ای و جذاب به رابط شما بدهد. بسته به نیاز، می‌توانید از روش ساده با radial-gradient تا فیلترهای پیشرفته SVG استفاده کنید. همیشه عملکرد را در نظر بگیرید: از transform به‌جای موقعیت‌دهی سنتی استفاده کنید، مقدار blur را معقول نگه دارید و از will-change به‌طور محدود بهره ببرید. ترکیب هوشمندانه این تکنیک‌ها، تجربه بصری قابل‌قبولی ایجاد می‌کند بدون تحمیل بار سنگین روی دستگاه کاربر.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: