FA-TOOLS — Header Component
چگونه افکت مایع (Liquid Distortion) را با استفاده از SVG فی لترها پیاده کنیم؟

چگونه افکت مایع (Liquid Distortion) را با استفاده از SVG فی لترها پیاده کنیم؟

سلام رفیق! اگه دنبال اینی که وب‌سایتت رو با یه چاشنی از خلاقیت و پویایی تزئین کنی، اومدی جای درستی. امروز می‌خوایم بریم سراغ یکی از جذاب‌ترین افکت‌های بصری که این روزا حسابی ترند شده: افکت مایع یا Liquid Distortion. فکر کن یه تصویر یا متن وقتی کاربر روش هاور می‌کنه، یا حتی وقتی صفحه اسکرول میشه، مثل آب موج برداره یا مثل یه مایع ژله‌ای حرکت کنه! شگفت انگیز نیست؟ این کار رو می‌تونیم با استفاده از قدرت بی‌نظیر SVG فیلترها انجام بدیم. آماده‌ای که جادوی CSS و SVG رو با هم ترکیب کنیم و یه تجربه کاربری به‌یادماندنی بسازیم؟ این راهنما قراره از صفر تا صد این داستان رو بهت بگه، جوری که هیچ گوشه پنهونی باقی نمونه. فقط قبل از اینکه شروع کنیم، یادت باشه برای اینکه بتونی بهترین ابزارها و اسنیپت‌های کد آماده رو در مسیر توسعه‌ات داشته باشی، یه سر به فروشگاه ابزارهای ما بزن. اونجا هر چیزی که فکرش رو بکنی، از پلاگین‌های خاص گرفته تا کدهای بهینه‌شده، برای تسریع کارت پیدا میشه و مطمئنم حسابی به دردت می‌خوره. برای اطلاعات بیشتر و دسترسی به منابع رایگان توسعه هم میتونی از صفحه اصلی fa-tools.ir بازدید کنی. پس بزن بریم!

🌟 نقشه راه: خلق افکت مایع با SVG فیلترها در یک نگاه 🌟

مرحله توضیحات کوتاه
۱. آماده‌سازی تعریف یک ساختار HTML/SVG پایه برای المان هدف.
۲. تعریف فیلتر SVG استفاده از <filter> شامل feTurbulence و feDisplacementMap.
۳. اعمال فیلتر لینک کردن فیلتر به المان HTML یا SVG از طریق CSS.
۴. انیمیشن و پویایی استفاده از CSS Keyframes یا JavaScript برای متحرک‌سازی افکت.
۵. بهینه‌سازی و عیب‌یابی تنظیم پارامترها برای بهترین عملکرد و حل مشکلات رایج.

📞 برای هرگونه سوال یا نیاز به پشتیبانی فنی، با ما تماس بگیرید: 09202232789

چرا افکت مایع؟ زیبایی و عملکرد در رابط کاربری مدرن

چگونه افکت مایع (Liquid Distortion) را با استفاده از SVG فی لترها پیاده کنیم؟ — تصویر 1

این روزا همه دنبال اینن که وب‌سایتشون نه تنها کاربردی باشه، بلکه از نظر بصری هم حرفی برای گفتن داشته باشه. افکت مایع یا Liquid Distortion دقیقاً همون چیزیه که می‌تونه سایتت رو از یکنواختی دربیاره و یه حس تازگی و مدرن بهش ببخشه. دیگه دوران افکت‌های ساده و خشک گذشته، حالا نوبت تعاملات بصریه که کاربر رو درگیر کنه و حس کنه با یه چیز زنده و پویا سر و کار داره. این افکت می‌تونه به تصاویر، متن‌ها، یا حتی تمام بخش‌های رابط کاربری، حالتی روان و دینامیک بده که هم چشم‌نوازه و هم تجربه‌ای متفاوت ایجاد می‌کنه.

درک پایه SVG و قدرت فی لترها

چگونه افکت مایع (Liquid Distortion) را با استفاده از SVG فی لترها پیاده کنیم؟ — تصویر 2

قبل از اینکه شیرجه بزنیم تو دل کدها، بیا یه مرور کوچیک روی SVG و قابلیت‌های فیلترش داشته باشیم. این دانش پایه بهمون کمک می‌کنه بفهمیم دقیقاً داریم چیکار می‌کنیم.

SVG چیست و چرا برای انیمیشن مناسب است؟

SVG یا Scalable Vector Graphics یه فرمت تصویر برداری بر پایه XML هستش. یعنی به جای اینکه مثل JPEG یا PNG از پیکسل‌ها برای ساخت تصویر استفاده کنه، از معادلات ریاضی برای تعریف شکل‌ها، خطوط و رنگ‌ها بهره می‌بره. این ویژگی باعث میشه SVG ها در هر سایزی بدون افت کیفیت نمایش داده بشن، از موبایل‌های کوچیک بگیر تا تلویزیون‌های بزرگ، همه جا عالی به نظر میان! (بله، حتی برای موبایل، تبلت، لپ‌تاپ و تلویزیون رسپانسیو بودن اینجا خودش رو نشون میده). علاوه بر این، چون ساختارش بر پایه XML هست، به راحتی میشه با CSS و JavaScript اونا رو دستکاری و انیمیت کرد. این قابلیت، SVG رو به یه ابزار فوق‌العاده قدرتمند برای گرافیک وب و انیمیشن تبدیل می‌کنه.

آشنایی با تگ “ در SVG

تگ “ در SVG به ما اجازه میده افکت‌های گرافیکی پیچیده‌ای رو روی المان‌های SVG یا حتی HTML اعمال کنیم. این فیلترها مثل لایه‌های فتوشاپ عمل می‌کنن؛ شما می‌تونید چند تا افکت رو روی هم سوار کنید تا به نتیجه دلخواهتون برسید. هر فیلتر از یک یا چند “primitive filter” تشکیل شده که هر کدوم یه کار خاص انجام میدن. برای افکت مایع، ما عمدتاً به دو تا از این primitive filter ها نیاز داریم:

  • `feTurbulence` (Filter Primitive Turbulence): این فی لتر جادویی‌ترین قسمت کار ماست. یه تصویر “نویز” یا “مایع” تولید می‌کنه که می‌تونه به عنوان منبع جابه‌جایی برای افکت مایع استفاده بشه. پارامترهایی مثل `type`, `baseFrequency`, `numOctaves` و `seed` رو میشه تغییر داد تا ماهیت این نویز رو کنترل کنیم.
  • `feDisplacementMap` (Filter Primitive Displacement Map): این یکی مسئول جابه‌جا کردن پیکسل‌های تصویر بر اساس نویزی هست که `feTurbulence` تولید کرده. یعنی تصویر رو بر اساس شدت رنگ‌های تصویر نویز، در جهت‌های مختلف جابه‌جا می‌کنه و حس مایع بودن رو به وجود میاره.
  • `feGaussianBlur` (Filter Primitive Gaussian Blur): این فیلتر رو شاید برای نرم کردن لبه‌ها یا ایجاد عمق استفاده کنیم، هرچند برای افکت مایع، `feTurbulence` و `feDisplacementMap` عناصر اصلی هستند.

ابزارهای مورد نیاز برای خلق این جادو

چگونه افکت مایع (Liquid Distortion) را با استفاده از SVG فی لترها پیاده کنیم؟ — تصویر 3

برای شروع کار، به ابزار خاصی نیاز نداری، فقط یه ویرایشگر کد و مرورگر مدرن کافیه. اما اگه دوست داری کار رو سریع‌تر پیش ببری و کدهای آماده و بهینه داشته باشی، باز هم می‌تونی یه نگاهی به فروشگاه ابزارهای ما بندازی. در کل، اینا چیزایی هستن که لازم داری:

  • HTML: برای ساختار کلی صفحه و قرار دادن المان هدف (مثلاً یه <img> یا <div>).
  • CSS: برای استایل‌دهی، اعمال فیلتر SVG و متحرک‌سازی.
  • SVG: برای تعریف خود فیلترها.
  • JavaScript (اختیاری): اگه بخوای کنترل دقیق‌تر یا تعاملات پیچیده‌تری با افکت داشته باشی.

گام به گام: پیاده‌سازی افکت مایع با SVG Filters

حالا وقتشه که آستین بالا بزنیم و بریم سراغ بخش هیجان‌انگیز کار، یعنی کدنویسی! این مراحل رو با دقت دنبال کن تا به نتیجه دلخواه برسی.

گام اول: آماده‌سازی ساختار HTML و SVG پایه

اولین قدم اینه که یه ساختار ساده HTML داشته باشیم و تگ SVG رو برای تعریف فیلترمون آماده کنیم. تگ SVG رو معمولاً داخل <body> قرار میدیم و با ویژگی style="position: absolute; width: 0; height: 0;" مخفی می‌کنیم تا فضای اضافی روی صفحه اشغال نکنه.

ساختار HTML اولیه:

<!DOCTYPE html>
<html lang="fa">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>افکت مایع با SVG فیلترها</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            background-color: #222;
            margin: 0;
            font-family: sans-serif;
            overflow: hidden; /* برای جلوگیری از نمایش اسکرول بار اضافی */
        }
        .liquid-element {
            width: 300px;
            height: 200px;
            background-color: #007bff;
            display: flex;
            justify-content: center;
            align-items: center;
            color: white;
            font-size: 1.8em;
            font-weight: bold;
            border-radius: 15px;
            box-shadow: 0 10px 20px rgba(0,0,0,0.2);
            transition: all 0.3s ease;
        }
        .liquid-element:hover {
            transform: scale(1.05);
            box-shadow: 0 15px 30px rgba(0,0,0,0.3);
        }
        /* کلاس برای اعمال فیلتر SVG */
        .apply-liquid {
            filter: url(#liquid-distortion);
        }
        /* انیمیشن برای پویایی افکت مایع */
        @keyframes liquidAnimation {
            0% {
                filter: url(#liquid-distortion-start);
            }
            50% {
                filter: url(#liquid-distortion-mid);
            }
            100% {
                filter: url(#liquid-distortion-end);
            }
        }
        .liquid-element:hover.apply-liquid {
            animation: liquidAnimation 2s infinite alternate ease-in-out;
        }
    </style>
</head>
<body>
    <!-- المان هدف ما که افکت مایع روی آن اعمال می‌شود -->
    <div class="liquid-element">
        افکت مایع
    </div>

    <!-- اینجا SVG فیلترهای ما تعریف می‌شوند -->
    <svg style="position: absolute; width: 0; height: 0;">
        <!-- فیلترها اینجا قرار می‌گیرند -->
    </svg>
</body>
</html>

function copyCode(button) {
const codeBlock = button.previousElementSibling.querySelector(‘code’);
const range = document.createRange();
range.selectNode(codeBlock);
window.getSelection().removeAllRanges();
window.getSelection().addRange(range);
document.execCommand(‘copy’);
window.getSelection().removeAllRanges();
button.textContent = ‘کپی شد!’;
setTimeout(() => {
button.textContent = ‘کپی کد’;
}, 2000);
}

گام دوم: تعریف فیلترهای Displacement Map و Gaussian Blur

حالا نوبت به قلب ماجرا می‌رسه: تعریف خود فیلتر SVG. داخل تگ <svg> که در گام قبل ساختیم، سه فیلتر با `id`های متفاوت تعریف می‌کنیم تا بتونیم بهشون انیمیشن بدیم. هر فیلتر شامل feTurbulence و feDisplacementMap هستش. پارامترهای baseFrequency رو برای هر کدوم کمی تغییر میدیم تا حس حرکت و پویایی ایجاد بشه.

افزودن فیلترها به تگ `<svg>`:

    <svg style="position: absolute; width: 0; height: 0;">
        <filter id="liquid-distortion-start">
            <!-- تولید نویز (اختلال) -->
            <feTurbulence type="fractalNoise" baseFrequency="0.01 0.05" numOctaves="1" seed="0" result="turbulence" />
            <!-- جابجایی پیکسل‌ها بر اساس نویز -->
            <feDisplacementMap in2="turbulence" in="SourceGraphic" scale="20" xChannelSelector="R" yChannelSelector="G" />
        </filter>

        <filter id="liquid-distortion-mid">
            <feTurbulence type="fractalNoise" baseFrequency="0.02 0.08" numOctaves="1" seed="1" result="turbulence" />
            <feDisplacementMap in2="turbulence" in="SourceGraphic" scale="25" xChannelSelector="R" yChannelSelector="G" />
        </filter>

        <filter id="liquid-distortion-end">
            <feTurbulence type="fractalNoise" baseFrequency="0.015 0.06" numOctaves="1" seed="2" result="turbulence" />
            <feDisplacementMap in2="turbulence" in="SourceGraphic" scale="20" xChannelSelector="R" yChannelSelector="G" />
        </filter>
    </svg>

یه توضیح کوتاه در مورد پارامترها:

  • `id`: یه شناسه منحصر به فرد برای فیلتر، که بعداً با CSS بهش ارجاع میدیم.
  • `feTurbulence`:
    • `type=”fractalNoise”`: نوع نویز رو مشخص می‌کنه. `fractalNoise` یا `turbulence`.
    • `baseFrequency=”0.01 0.05″`: فرکانس پایه نویز در محور x و y. اعداد کوچکتر، موج‌های بزرگتر و نرم‌تر ایجاد می‌کنند. اینجا ما یک فرکانس متفاوت برای X و Y دادیم تا نویز کشیده‌تر به نظر برسه.
    • `numOctaves=”1″`: تعداد لایه‌های نویز. هرچی بیشتر باشه، نویز پیچیده‌تر میشه. برای افکت مایع معمولا عدد کمتری مثل 1 یا 2 بهتره.
    • `seed=”0″`: یک مقدار تصادفی برای شروع تولید نویز. تغییر این عدد، الگوی نویز رو عوض می‌کنه.
    • `result=”turbulence”`: نویز تولید شده رو با این نام ذخیره می‌کنیم تا در فیلتر بعدی بهش ارجاع بدیم.
  • `feDisplacementMap`:
    • `in2=”turbulence”`: منبعی که برای جابه‌جایی پیکسل‌ها استفاده میشه (همون نویزی که ساختیم).
    • `in=”SourceGraphic”`: منبعی که قراره پیکسل‌هاش جابه‌جا بشن (همون المان اصلی ما).
    • `scale=”20″`: شدت جابه‌جایی. هرچی این عدد بیشتر باشه، افکت مایع هم قوی‌تر میشه.
    • `xChannelSelector=”R”` و `yChannelSelector=”G”`: اینا میگن که برای جابه‌جایی در محور X از کانال رنگی قرمز (`R`) و برای Y از کانال سبز (`G`) نویز استفاده کن. این باعث میشه نویز در دو محور مستقل عمل کنه و حالت مایع رو بهتر نشون بده.

گام سوم: اعمال فیلتر به المان مورد نظر

حالا که فیلتر رو تعریف کردیم، باید اونو به المان `div` مون اعمال کنیم. این کار رو به راحتی با CSS و ویژگی `filter` انجام میدیم. یادت باشه که `url(#id_فیلتر)` رو به درستی بنویسی.

اعمال فیلتر با CSS:

/* در بخش <style> کد HTML */
.liquid-element.apply-liquid {
    filter: url(#liquid-distortion-start); /* فیلتر اولیه */
}

/* برای انیمیشن، این بخش رو در گام بعدی تکمیل میکنیم */
.liquid-element:hover.apply-liquid {
    animation: liquidAnimation 2s infinite alternate ease-in-out;
}

با اضافه کردن کلاس `apply-liquid` به <div class="liquid-element">، افکت مایع روی اون اعمال میشه.

گام چهارم: ایجاد انیمیشن با CSS یا JavaScript (برای پویایی بیشتر)

افکت مایع وقتی جذابیت واقعی خودش رو نشون میده که متحرک باشه. می‌تونیم با استفاده از CSS Keyframes و تغییر ID فیلتر، یه انیمیشن روان بسازیم. این کار باعث میشه نویز تولید شده توسط `feTurbulence` در طول زمان تغییر کنه و حس حرکت آب رو القا کنه.

تعریف Keyframes برای انیمیشن فیلتر:

/* در بخش <style> کد HTML */
@keyframes liquidAnimation {
    0% {
        filter: url(#liquid-distortion-start); /* فیلتر اولیه */
    }
    50% {
        filter: url(#liquid-distortion-mid); /* فیلتر میانی */
    }
    100% {
        filter: url(#liquid-distortion-end); /* فیلتر پایانی */
    }
}

.liquid-element:hover { /* انیمیشن هنگام هاور */
    animation: liquidAnimation 2s infinite alternate ease-in-out;
}

در اینجا، ما سه فیلتر با `id`های مختلف ساختیم و در Keyframes بهشون ارجاع دادیم. این باعث میشه در طول انیمیشن، فیلتر بین این سه حالت جابه‌جا بشه و یه حرکت مایع پویا ایجاد کنه. می‌تونی `baseFrequency` یا `scale` رو در هر فیلتر تغییر بدی تا شکل موج‌ها و شدت جابجایی فرق کنه.

اگه نیاز به کنترل بیشتری داری، مثلاً می‌خوای افکت مایع با حرکت موس کاربر یا اسکرول صفحه تغییر کنه، می‌تونی از JavaScript کمک بگیری. با جاوااسکریپت می‌تونی مقادیر `baseFrequency` و `scale` رو به صورت پویا و در زمان اجرا تغییر بدی و حتی انیمیشن‌های پیچیده‌تری بسازی. یه سر به فروشگاه کدهای آماده و اسنیپت‌های ما بزنی، کلی سورس برای این کارها پیدا می‌کنی که کارتو راه می‌ندازه.

جزئیات پیشرفته و نکات طلایی برای افکت‌های خلاقانه‌تر

حالا که اصول کار دستت اومد، بیا یه خورده عمیق‌تر بشیم و ببینیم چطوری می‌تونیم این افکت رو واقعاً منحصر به فرد کنیم.

تنظیمات `feTurbulence`: کلید کنترل “مایع بودن”

همونطور که گفتیم، `feTurbulence` نقطه شروع هر افکت مایع قوی هست. فهمیدن و دستکاری پارامترهای اون خیلی مهمه:

  • `type` (`fractalNoise` vs `turbulence`):
    • `fractalNoise`: الگوی نویز رو نرم‌تر و ارگانیک‌تر نشون میده، مثل حرکت آرام آب یا دود.
    • `turbulence`: نویز خشن‌تر و پرتلاطم‌تره، مثل سطح آب طوفانی.
  • `baseFrequency` (X و Y): این دو مقدار (مثلاً `0.01 0.05`) فرکانس نویز رو در محور افقی و عمودی کنترل می‌کنن.
    • اعداد کوچک: موج‌های بزرگ و کشیده. مناسب برای افکت‌های آرام و روان.
    • اعداد بزرگ: موج‌های ریز و متراکم. مناسب برای افکت‌های پرتلاطم و حباب‌مانند.
    • مقادیر متفاوت برای X و Y: نویز رو در یک جهت کشیده‌تر می‌کنه و حس حرکت در اون جهت رو بیشتر نشون میده.
  • `numOctaves`: تعداد لایه‌های فرعی نویز. هرچی بیشتر باشه، جزئیات بیشتری به نویز اضافه میشه و پیچیدگی اون افزایش پیدا می‌کنه. معمولاً برای افکت مایع، `1` یا `2` کافیه تا حالت نرمی حفظ بشه.
  • `seed`: یه عدد تصادفی که می‌تونه الگوی نویز رو تغییر بده. اگه می‌خوای هر بار یه الگوی جدید داشته باشی، می‌تونی این مقدار رو با JavaScript تغییر بدی.

`feDisplacementMap`: چگونه المان را جابجا کنیم؟

این فیلتر مسئول ترجمه نویز `feTurbulence` به جابجایی واقعی پیکسل‌هاست.

  • `in`: منبع گرافیکی اصلی که قراره جابجا بشه (معمولاً `SourceGraphic`).
  • `in2`: تصویری که به عنوان نقشه جابجایی استفاده میشه (نتیجه `feTurbulence`).
  • `scale`: مقدار جابجایی. این مهم‌ترین پارامتر برای کنترل شدت افکت مایع هست. اعداد بالاتر، جابجایی بیشتری ایجاد می‌کنن.
  • `xChannelSelector` و `yChannelSelector`: اینا مشخص می‌کنن که از کدوم کانال رنگی (R, G, B, A) تصویر `in2` برای محاسبه جابجایی در محور X و Y استفاده بشه. با انتخاب کانال‌های متفاوت، می‌تونی افکت‌های نامتقارن و جالب‌تری خلق کنی.

جدول تنظیمات کلیدی برای افکت مایع

ویژگی توضیحات و کاربرد
baseFrequency کنترل اندازه و تعداد موج‌ها. اعداد کوچکتر = موج‌های بزرگتر و روان‌تر.
scale شدت جابجایی پیکسل‌ها. هر چه عدد بالاتر، افکت شدیدتر.
numOctaves جزئیات و پیچیدگی نویز. معمولاً 1 یا 2 برای افکت‌های مایع.
type نوع نویز (fractalNoise برای نرمی، turbulence برای خشونت).

بهینه‌سازی عملکرد و جلوگیری از لگ

افکت‌های SVG فیلتر می‌تونن از نظر پردازشی سنگین باشن، مخصوصاً اگه روی دستگاه‌های ضعیف یا مرورگرهای قدیمی اجرا بشن. برای جلوگیری از لگ و اطمینان از تجربه کاربری روان:

  • محدود کردن `numOctaves`: تا حد امکان `numOctaves` رو روی `1` یا نهایتاً `2` نگه دار. اعداد بالاتر به شدت عملکرد رو کاهش میدن.
  • اندازه المان: سعی کن فیلتر رو روی المان‌های کوچکتر اعمال کنی. اگه روی کل صفحه اعمال بشه، ممکنه خیلی سنگین بشه.
  • فقط در صورت نیاز: فیلتر رو فقط زمانی فعال کن که واقعاً بهش نیاز داری (مثلاً هنگام هاور یا در transitionها). وقتی انیمیشن تموم شد، فیلتر رو بردار یا غیرفعال کن.
  • تست روی دستگاه‌های مختلف: همیشه روی موبایل، تبلت و لپ‌تاپ (با پردازنده‌های مختلف) تست کن تا از عملکرد بهینه اطمینان حاصل کنی.
  • استفاده از `will-change`: می‌تونی برای المان‌هایی که فیلتر روشون اعمال میشه، از ویژگی `will-change: filter;` در CSS استفاده کنی تا مرورگر برای اون تغییر آماده باشه و عملکرد بهتری داشته باشی.

سناریوهای کاربردی: کجا از Liquid Distortion استفاده کنیم؟

این افکت فقط برای خودنمایی نیست، می‌تونه کلی کاربرد خلاقانه و کاربردی داشته باشه:

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

عیب‌یابی سریع: مشکلات رایج و راه‌حل‌ها

ممکنه در طول پیاده‌سازی این افکت، به یه سری چالش‌ها بخوری. نگران نباش، اینا چند تا از مشکلات رایج و راه‌حل‌هاشون هستن:

  • افکت اعمال نمیشه یا دیده نمیشه:
    • راه‌حل: اول از همه چک کن که `id` فیلتر در CSS (url(#your-filter-id)) دقیقاً با `id` تعریف شده در تگ `<filter>` یکی باشه. همچنین مطمئن شو که تگ SVG مخفی نیست یا به اشتباه display: none; براش تنظیم نشده.
    • راه‌حل: اطمینان حاصل کن که المانی که فیلتر رو بهش اعمال می‌کنی، دارای محتوا یا ابعاد مشخصی هست. اگه یه <div> خالی باشه بدون `width` و `height`، فیلتر چیزی برای جابجایی نداره.
  • افکت خیلی ضعیف یا خیلی قویه:
    • راه‌حل: مقدار `scale` در `feDisplacementMap` رو تنظیم کن. برای افکت‌های ضعیف‌تر، عدد رو کم کن و برای قوی‌تر شدن، عدد رو زیاد کن.
    • راه‌حل: `baseFrequency` در `feTurbulence` رو تغییر بده. فرکانس‌های کوچکتر باعث موج‌های بزرگتر و فرکانس‌های بزرگتر باعث موج‌های ریزتر میشن.
  • انیمیشن روان نیست یا لگ میزنه:
    • راه‌حل: همونطور که گفتیم، `numOctaves` رو بررسی کن. اگه بیشتر از `1` یا `2` هست، سعی کن کمترش کنی.
    • راه‌حل: `baseFrequency` رو خیلی زیاد نکن. فرکانس‌های بالا نیاز به پردازش بیشتری دارن.
    • راه‌حل: مطمئن شو که روی مرورگر و دستگاه‌های مختلف تست کردی. شاید مشکل از قدرت پردازشی دستگاه باشه.
    • راه‌حل: از `will-change: filter;` روی المان مورد نظر استفاده کن تا مرورگر بهینه‌سازی‌های لازم رو انجام بده.
  • مشکلات سازگاری با مرورگرها:
    • راه‌حل: SVG فیلترها در اکثر مرورگرهای مدرن (Chrome, Firefox, Safari, Edge) به خوبی پشتیبانی میشن. اما برای مرورگرهای خیلی قدیمی، ممکنه مشکلاتی وجود داشته باشه. می‌تونی از ابزارهایی مثل caniuse.com برای بررسی پشتیبانی کمک بگیری.

اگه بازم به مشکلی برخوردی، تیم فنی ما همیشه آماده کمکه! میتونی با ما تماس بگیری یا به صورت مستقیم به شماره 09202232789 زنگ بزنی.

سخن پایانی

خب رفیق، دیدی که پیاده‌سازی افکت مایع با SVG فی لترها اونقدرها هم که به نظر میاد پیچیده نیست. با کمی بازی با پارامترها و خلاقیت خودت، می‌تونی افکت‌های واقعاً خیره‌کننده‌ای بسازی که سایتت رو از بقیه متمایز کنه. این تکنیک فقط یه ترفند بصری نیست، بلکه یه ابزار قدرتمنده برای بهبود تجربه کاربری و ایجاد رابط‌های پویا و جذاب. فراموش نکن که همیشه به بهینه‌سازی هم فکر کنی تا کاربرات از یه تجربه روان و بدون لگ لذت ببرن. امیدوارم این راهنما برات مفید بوده باشه و الان آماده باشی تا جادوی مایع رو به پروژه‌هات اضافه کنی. کدنویسی خوش بگذره!

سوالات متداول (FAQ)

۱. آیا SVG فیلترها روی همه مرورگرها کار می‌کنند؟

بله، SVG فیلترها در اکثر مرورگرهای مدرن (مثل Chrome، Firefox، Safari، Edge) به خوبی پشتیبانی می‌شوند. البته همیشه بهتر است برای اطمینان بیشتر، سازگاری را روی مرورگرهای هدف خود تست کنید.

۲. آیا استفاده از افکت مایع باعث کند شدن وب‌سایت می‌شود؟

اگر به درستی بهینه‌سازی نشود، بله ممکن است. استفاده از numOctaves پایین، محدود کردن ابعاد المان فیلتر شده، و فعال کردن فیلتر فقط در زمان نیاز، به حفظ عملکرد کمک می‌کند.

۳. چگونه می‌توانم افکت مایع را روی تصاویر اعمال کنم؟

می‌توانید فیلتر را مستقیماً به تگ <img> یا به یک <div> که تصویر پس‌زمینه دارد، اعمال کنید. اصول کار همانند اعمال فیلتر به یک <div> معمولی است که در مقاله توضیح داده شد.

۴. آیا می‌توانم با JavaScript پارامترهای فیلتر را تغییر دهم؟

کاملاً! با JavaScript می‌توانید به المان‌های SVG فیلتر دسترسی پیدا کرده و ویژگی‌های آن‌ها (مانند baseFrequency یا scale) را به صورت پویا تغییر دهید. این کار امکان ایجاد تعاملات پیچیده‌تر و افکت‌های بسیار سفارشی را فراهم می‌کند.

چگونه افکت مایع (Liquid Distortion) را با استفاده از SVG فیلترها پیاده کنیم؟

/* Base styles برای رسپانسیو بودن در تمام دستگاه‌ها */
body {
font-family: ‘Vazirmatn’, sans-serif;
line-height: 1.8;
color: #333;
background-color: #f0f2f5;
margin: 0;
padding: 0;
direction: rtl;
text-align: right;
box-sizing: border-box;
}
.container {
max-width: 900px;
margin: 40px auto;
padding: 20px;
background-color: #ffffff;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
}
/* Media queries برای رسپانسیو بودن */
@media (max-width: 1024px) {
.container {
margin: 20px auto;
padding: 15px;
}
h1 { font-size: 2.4em !important; padding-right: 12px !important; border-right-width: 5px !important; }
h2 { font-size: 1.9em !important; padding-right: 10px !important; border-right-width: 4px !important; }
h3 { font-size: 1.5em !important; padding-right: 8px !important; border-right-width: 3px !important; }
p { font-size: 1em; line-height: 1.7; }
li { font-size: 1em; }
.infographic-box strong, .table-of-contents h3 { font-size: 1.2em !important; }
}
@media (max-width: 768px) {
.container {
margin: 15px auto;
padding: 10px;
border-radius: 8px;
}
h1 { font-size: 2em !important; padding-right: 10px !important; border-right-width: 4px !important; }
h2 { font-size: 1.6em !important; padding-right: 8px !important; border-right-width: 3px !important; }
h3 { font-size: 1.3em !important; padding-right: 6px !important; border-right-width: 2px !important; }
p { font-size: 0.95em; line-height: 1.6; }
li { font-size: 0.95em; }
.infographic-box strong, .table-of-contents h3 { font-size: 1.1em !important; }
pre { padding: 15px; font-size: 0.9em; }
code { font-size: 0.85em; }
}
@media (max-width: 480px) {
.container {
margin: 10px;
padding: 10px;
border-radius: 5px;
}
h1 { font-size: 1.7em !important; padding-right: 8px !important; border-right-width: 3px !important; }
h2 { font-size: 1.4em !important; padding-right: 6px !important; border-right-width: 2px !important; }
h3 { font-size: 1.1em !important; padding-right: 4px !important; border-right-width: 2px !important; }
p { font-size: 0.9em; line-height: 1.5; }
li { font-size: 0.9em; }
.infographic-box strong, .table-of-contents h3 { font-size: 1em !important; }
.svg-example svg { height: 150px; }
}

/* Headings */
h1, h2, h3 {
color: #011627;
text-align: right;
margin-top: 1.8em;
margin-bottom: 0.8em;
padding-right: 10px;
border-right: 4px solid #4CAF50; /* رنگ تاکیدی */
}
/* استایل‌های درون خطی برای هدینگ‌ها تضمین می‌کند که بعد از کپی نیز ظاهر صحیح داشته باشند */
/* H1 در ابتدای مقاله با استایل مخصوص */
/* H2 */
/* H3 */

/* Paragraphs */
p {
margin-bottom: 1.2em;
font-size: 1.1em;
line-height: 1.9;
}

/* Lists */
ul, ol {
margin-bottom: 1.2em;
padding-right: 25px;
}
li {
margin-bottom: 0.8em;
font-size: 1.05em;
line-height: 1.8;
}

/* Links */
a {
color: #007bff;
text-decoration: none;
transition: color 0.3s ease;
}
a:hover {
color: #0056b3;
text-decoration: underline;
}

/* InfoGraphic Box (Alternative) */
.infographic-box {
background-color: #e8f5e9; /* سبز روشن */
border-right: 5px solid #4CAF50;
padding: 20px;
margin: 30px 0;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
line-height: 1.6;
}
.infographic-box strong {
color: #2e7d32; /* سبز تیره */
font-weight: 700;
display: block;
margin-bottom: 10px;
font-size: 1.3em;
}
.infographic-box ul {
list-style: none;
padding: 0;
margin: 0;
}
.infographic-box li {
position: relative;
padding-right: 25px;
margin-bottom: 10px;
font-size: 1.05em;
}
.infographic-box li:before {
content: ‘✓’;
color: #4CAF50;
position: absolute;
right: 0;
font-weight: bold;
}

/* Table of Contents */
.table-of-contents {
background-color: #f8f9fa; /* خاکستری روشن */
border: 1px solid #dee2e6;
padding: 20px;
margin: 30px 0;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0,0,0,0.02);
}
.table-of-contents h3 {
color: #34495e;
border: none;
padding: 0;
margin-top: 0;
margin-bottom: 15px;
font-size: 1.6em;
font-weight: 600;
}
.table-of-contents ul {
list-style: none;
padding: 0;
margin: 0;
}
.table-of-contents li {
margin-bottom: 10px;
font-size: 1.05em;
}
.table-of-contents a {
color: #007bff;
transition: color 0.3s ease;
}
.table-of-contents a:hover {
color: #0056b3;
text-decoration: underline;
}
.table-of-contents ul ul {
padding-right: 20px;
margin-top: 5px;
margin-bottom: 5px;
}
.table-of-contents ul ul li {
font-size: 1em;
}

/* Code snippets */
pre {
background-color: #2d2d2d; /* پس‌زمینه تیره برای کد */
color: #f8f8f2;
padding: 18px;
border-radius: 8px;
overflow-x: auto;
margin: 25px 0;
font-family: ‘SFMono-Regular’, Consolas, ‘Liberation Mono’, Menlo, Courier, monospace;
font-size: 0.95em;
line-height: 1.6;
direction: ltr; /* اطمینان از نمایش کد به صورت LTR */
text-align: left;
}
code {
background-color: #e0e0e0;
padding: 2px 5px;
border-radius: 4px;
font-family: ‘SFMono-Regular’, Consolas, ‘Liberation Mono’, Menlo, Courier, monospace;
font-size: 0.9em;
color: #c7254e;
}
pre code {
background-color: transparent;
padding: 0;
color: #f8f8f2;
}

/* Callout/Tip Box */
.tip-box {
background-color: #e3f2fd; /* آبی روشن */
border-right: 5px solid #2196F3;
padding: 18px;
margin: 25px 0;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
font-size: 1.05em;
line-height: 1.7;
}
.tip-box strong {
color: #1976D2;
font-weight: 700;
}

/* Troubleshooting Section Styling */
.troubleshooting-section {
background-color: #fffde7; /* زرد روشن */
border-right: 5px solid #ffeb3b;
padding: 20px;
margin: 30px 0;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}
.troubleshooting-section strong {
color: #fbc02d; /* زرد تیره */
font-weight: 700;
}
.troubleshooting-section ul {
list-style: none;
padding: 0;
}
.troubleshooting-section ul li {
position: relative;
padding-right: 25px;
margin-bottom: 12px;
}
.troubleshooting-section ul li:before {
content: ‘❌’; /* آیکون ضربدر */
position: absolute;
right: 0;
color: #ef5350; /* قرمز برای مشکل */
font-weight: bold;
}
.troubleshooting-section ul li span {
display: block;
font-weight: bold;
color: #333;
}
.troubleshooting-section ul li p {
margin-top: 5px;
margin-bottom: 0;
font-size: 0.95em;
color: #555;
}

/* FAQ Section */
.faq-section {
margin-top: 40px;
}
.faq-item {
background-color: #fcfcfc;
border: 1px solid #eee;
border-radius: 8px;
padding: 18px;
margin-bottom: 15px;
box-shadow: 0 1px 5px rgba(0,0,0,0.02);
}
.faq-question {
font-weight: 700;
color: #34495e;
margin-bottom: 10px;
font-size: 1.15em;
}
.faq-answer {
color: #555;
line-height: 1.7;
}

/* Table styles */
table {
width: 100%;
border-collapse: collapse;
margin: 25px 0;
font-size: 1.05em;
background-color: #ffffff;
box-shadow: 0 2px 10px rgba(0,0,0,0.05);
border-radius: 8px;
overflow: hidden; /* برای گوشه‌های گرد */
}
th, td {
padding: 15px;
text-align: right;
border-bottom: 1px solid #e0e0e0;
}
th {
background-color: #e0f2f7; /* سربرگ آبی روشن */
color: #011627;
font-weight: 600;
font-size: 1.1em;
}
tr:nth-child(even) {
background-color: #f9f9f9;
}
tr:hover {
background-color: #f1f8e9; /* سبز روشن در هاور */
}
table tbody tr:last-child td {
border-bottom: none;
}
/* رسپانسیو بودن جدول برای صفحات کوچک */
@media (max-width: 600px) {
table, thead, tbody, th, td, tr {
display: block;
}
thead tr {
position: absolute;
top: -9999px;
left: -9999px;
}
tr {
border: 1px solid #ccc;
margin-bottom: 15px;
border-radius: 8px;
}
td {
border: none;
border-bottom: 1px solid #eee;
position: relative;
padding-right: calc(50% + 15px); /* فضای کافی برای pseudo-element */
text-align: right;
}
td:before {
position: absolute;
right: 15px;
width: 45%;
padding-left: 10px;
white-space: nowrap;
font-weight: bold;
content: attr(data-label); /* استفاده از data-label برای نمایش سربرگ در هر سطر */
color: #555;
}
td:last-child {
border-bottom: none;
}
}
/* Styling for SVG example (basic) */
.svg-example {
border: 1px dashed #ccc;
padding: 20px;
margin: 25px 0;
border-radius: 8px;
text-align: center;
background-color: #fbfbfb;
}
.svg-example svg {
width: 100%;
height: 200px;
background-color: #ffffff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}
/* استایل برای انیمیشن SVG با SMIL (تگ animate را داخل SVG ببینید) */
@keyframes liquidAnimationBaseFreq {
0% { transform: scale(1); }
50% { transform: scale(1.02); }
100% { transform: scale(1); }
}
.animated-svg-text {
animation: liquidAnimationBaseFreq 4s ease-in-out infinite alternate;
}

چگونه افکت مایع (Liquid Distortion) را با استفاده از SVG فیلترها پیاده کنیم؟

خلاصه مقاله: راهنمای گام به گام پیاده‌سازی افکت مایع با SVG فیلترها

  • SVG فیلترها ابزاری قدرتمند برای ایجاد جلوه‌های بصری پیچیده و بهینه در وب هستند.
  • افکت مایع (Liquid Distortion) با ترکیب دو فیلتر اصلی feTurbulence و feDisplacementMap قابل پیاده‌سازی است.
  • feTurbulence برای تولید نویز شبیه به بافت‌های طبیعی (مثل آب یا ابر) استفاده می‌شود.
  • feDisplacementMap با استفاده از نویز تولید شده، پیکسل‌های عنصر هدف را جابجا می‌کند و جلوه تغییر شکل را ایجاد می‌کند.
  • پیاده‌سازی شامل تعریف فیلتر در بخش <defs> و سپس اعمال آن به عناصر SVG یا HTML با CSS است.
  • انیمیشن‌سازی پارامترهای فیلتر (مانند baseFrequency یا seed) با CSS، SMIL یا JavaScript باعث متحرک شدن افکت مایع می‌شود.
  • این تکنیک کاربردهای فراوانی در طراحی UI/UX، جلوه‌های بارگذاری و انتقال دارد و تجربه‌ بصری جذابی ایجاد می‌کند.

افکت مایع (Liquid Distortion) یکی از جلوه‌های بصری خیره‌کننده‌ای است که می‌تواند تجربه کاربری در وب‌سایت‌ها و اپلیکیشن‌ها را متحول کند. این افکت، حس سیالیت، پویایی و نرمی را به عناصر گرافیکی شما اضافه می‌کند و باعث می‌شود المان‌ها به شکلی ارگانیک و جذاب تغییر شکل دهند، گویی که در آب حل می‌شوند یا امواج آن‌ها را در بر گرفته است. پیاده‌سازی چنین جلوه‌ای با استفاده از CSS خالی بسیار دشوار و گاهی غیرممکن است. اما با ظهور و تکامل SVG (Scalable Vector Graphics) و قابلیت‌های فیلتر آن، این رویا به واقعیت پیوسته است.

در این مقاله جامع و کاربردی، قصد داریم به شما نشان دهیم که چگونه می‌توانید با بهره‌گیری از قدرت SVG فیلترها، این افکت جذاب را روی عناصر مختلف وب‌سایت خود پیاده‌سازی کنید. از معرفی مفاهیم پایه تا کدهای عملی و نکات پیشرفته، هر آنچه برای خلق یک جلوه مایع واقعی نیاز دارید، اینجا پیدا خواهید کرد.

چرا افکت مایع با SVG فیلترها؟

شاید بپرسید چرا باید از SVG فیلترها برای این کار استفاده کنیم، در حالی که ابزارهای دیگری هم برای گرافیک در وب وجود دارد؟ پاسخ در چندین مزیت کلیدی SVG و فیلترهای آن نهفته است:

  • مقیاس‌پذیری و کیفیت: SVG یک فرمت برداری است. یعنی بدون افت کیفیت، در هر اندازه‌ای قابل نمایش است. این ویژگی برای افکت‌های بصری که نیاز به دقت بالا در نمایش در رزولوشن‌های مختلف دارند، حیاتی است.
  • عملکرد بالا: فیلترهای SVG اغلب به صورت مستقیم روی GPU (واحد پردازش گرافیکی) اجرا می‌شوند، که منجر به عملکرد بسیار روان و سریع، حتی در انیمیشن‌های پیچیده می‌شود.
  • انعطاف‌پذیری و کنترل: SVG فیلترها مجموعه‌ای غنی از توابع ریاضی و پردازش تصویر را در اختیار شما قرار می‌دهند. این به شما اجازه می‌دهد تا با تنظیم دقیق پارامترها، به هر نوع افکت دلخواه برسید.
  • استاندارد وب: SVG یک استاندارد باز وب است و توسط تمام مرورگرهای مدرن پشتیبانی می‌شود.
  • ترکیب با HTML و CSS: می‌توانید فیلترهای SVG را به راحتی به عناصر HTML (مانند تصاویر، ویدئوها، یا حتی divها) با استفاده از CSS اعمال کنید، که این خود قدرت و انعطاف‌پذیری زیادی به شما می‌دهد.

آشنایی با اجزای اصلی: SVG و فیلترها

برای پیاده‌سازی افکت مایع، باید با دو عنصر اصلی SVG فیلترها آشنا شویم: <filter> به عنوان کانتینر فیلتر و دو فیلتر پریمیتیو (primitive) کلیدی: feTurbulence و feDisplacementMap. این دو فیلتر، در کنار هم، جادوی افکت مایع را خلق می‌کنند.

فیلتر feTurbulence: قلب افکت مایع

feTurbulence بنیادی‌ترین فیلتری است که در تولید افکت مایع نقش دارد. این فیلتر یک تصویر نویز (noise) تولید می‌کند که شبیه به بافت‌های طبیعی مثل ابر، آتش، آب یا سنگ مرمر است. این نویز سپس به عنوان “نقشه جابجایی” (displacement map) در مرحله بعدی استفاده می‌شود.

پارامترهای مهم feTurbulence عبارتند از:

  • type: نوع نویز را مشخص می‌کند. معمولاً از "turbulence" یا "fractalNoise" استفاده می‌شود. "turbulence" معمولاً برای جلوه‌های مایع واقعی‌تر است.
  • baseFrequency: فرکانس پایه نویز را تعیین می‌کند. مقادیر کوچک‌تر باعث ایجاد نویز با جزئیات بیشتر و “نرم‌تر” می‌شوند، در حالی که مقادیر بزرگ‌تر، نویز خشن‌تر و با جزئیات کمتر تولید می‌کنند. این پارامتر می‌تواند دو عدد (x y) برای کنترل جداگانه فرکانس در محورهای X و Y بگیرد.
  • numOctaves: تعداد اکتاوهای نویز را مشخص می‌کند. هر اکتاو لایه جدیدی از نویز را با فرکانس بالاتر و دامنه کمتر اضافه می‌کند. افزایش این مقدار باعث افزایش جزئیات و پیچیدگی نویز می‌شود.
  • seed: یک عدد تصادفی برای شروع تولید نویز است. تغییر این مقدار باعث تولید یک الگوی نویز متفاوت می‌شود. انیمیشن کردن این پارامتر می‌تواند حس حرکت و جریان را ایجاد کند.
  • result: یک نام (ID) برای خروجی این فیلتر تعیین می‌کند تا در فیلترهای بعدی قابل ارجاع باشد.
<feTurbulence type="turbulence" baseFrequency="0.01 0.05" numOctaves="2" seed="0" result="noise" />

فیلتر feDisplacementMap: جابجایی پیکسل‌ها

فیلتر feDisplacementMap جابجایی پیکسل‌های یک تصویر را بر اساس مقادیر رنگی تصویر دیگری (که به آن نقشه جابجایی می‌گوییم) کنترل می‌کند. در مورد افکت مایع، نقشه جابجایی همان نویز تولید شده توسط feTurbulence است.

پارامترهای مهم feDisplacementMap عبارتند از:

  • in: ورودی اصلی که قرار است جابجا شود. معمولاً "SourceGraphic" (عنصری که فیلتر به آن اعمال شده) است.
  • in2: تصویر نقشه جابجایی. در اینجا، "noise" (خروجی feTurbulence) خواهد بود.
  • scale: میزان جابجایی پیکسل‌ها را تعیین می‌کند. مقدار بزرگ‌تر به معنی جابجایی بیشتر و افکت “مایع” قوی‌تر است.
  • xChannelSelector: کانال رنگی از in2 را مشخص می‌کند که برای جابجایی در محور X استفاده شود (مثلاً "R" برای قرمز، "G" برای سبز، "B" برای آبی، "A" برای آلفا).
  • yChannelSelector: مشابه xChannelSelector، اما برای جابجایی در محور Y.
  • result: نام (ID) برای خروجی این فیلتر.
<feDisplacementMap in="SourceGraphic" in2="noise" scale="50" xChannelSelector="R" yChannelSelector="G" result="liquid" />
نکته مهم: معمولاً برای xChannelSelector و yChannelSelector از کانال‌های مختلفی (مثلاً R و G) استفاده می‌شود تا جابجایی در دو محور به صورت مستقل اما مرتبط با الگوی نویز اتفاق بیفتد و جلوه‌ای پویا و طبیعی‌تر ایجاد شود.

گام به گام: پیاده‌سازی افکت مایع

حالا که با اجزای اصلی آشنا شدیم، بیایید مراحل پیاده‌سازی افکت مایع را به صورت عملی دنبال کنیم. این مثال را برای یک عنصر متنی ساده پیاده‌سازی خواهیم کرد، اما می‌توانید آن را به تصاویر، اشکال SVG یا حتی عناصر HTML تعمیم دهید.

مرحله ۱: آماده‌سازی ساختار HTML و SVG

ابتدا، یک عنصر <svg> را در HTML خود اضافه می‌کنیم. داخل این <svg>، تگ <defs> برای تعریف فیلترها و سپس یک عنصر برای اعمال فیلتر (مثلاً <text>) قرار می‌دهیم.

<svg width="600" height="200" viewBox="0 0 600 200">
  <defs>
    <filter id="liquid-distortion">
      <!-- فیلترها اینجا قرار می‌گیرند -->
    </filter>
  </defs>

  <text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle"
        font-family="Vazirmatn" font-size="70" fill="#007bff"
        filter="url(#liquid-distortion)">
    افکت مایع
  </text>
</svg>

در این مرحله، filter="url(#liquid-distortion)" به مرورگر می‌گوید که فیلتر با ID “liquid-distortion” را به این متن اعمال کند.

مرحله ۲: تعریف فیلتر feTurbulence

اکنون، فیلتر feTurbulence را داخل تگ <filter> تعریف می‌کنیم. این فیلتر نویز اولیه را تولید می‌کند:

<filter id="liquid-distortion">
  <feTurbulence type="turbulence" baseFrequency="0.01 0.01" numOctaves="2" seed="0" result="noise" />
</filter>

تنظیم baseFrequency="0.01 0.01" به ما یک نویز نسبتاً نرم می‌دهد. numOctaves="2" کمی جزئیات به آن اضافه می‌کند.

مرحله ۳: تعریف فیلتر feDisplacementMap

در ادامه، فیلتر feDisplacementMap را اضافه می‌کنیم. این فیلتر از خروجی feTurbulence (که نامش "noise" بود) برای جابجایی پیکسل‌های متن ما استفاده می‌کند.

<filter id="liquid-distortion">
  <feTurbulence type="turbulence" baseFrequency="0.01 0.01" numOctaves="2" seed="0" result="noise" />
  <feDisplacementMap in="SourceGraphic" in2="noise" scale="50" xChannelSelector="R" yChannelSelector="G" />
</filter>

scale="50" میزان جابجایی را مشخص می‌کند. مقادیر بزرگ‌تر باعث “مایع” شدن بیشتر و مقادیر کوچک‌تر باعث افکت ظریف‌تر می‌شوند. xChannelSelector="R" و yChannelSelector="G" به ترتیب از کانال‌های قرمز و سبز نویز برای جابجایی در محور X و Y استفاده می‌کنند.

مرحله ۴: اعمال فیلتر به یک عنصر

در واقع در مرحله ۱ این کار را انجام دادیم. کافیست ویژگی filter را به عنصر SVG یا HTML مورد نظر خود اضافه کنید. برای عناصر HTML، این کار را با CSS انجام می‌دهیم:

.my-element {
  filter: url(#liquid-distortion);
}
نکته: وقتی فیلتر را به یک عنصر HTML (مثلاً <img> یا <div>) اعمال می‌کنید، باید مطمئن شوید که تگ <svg> حاوی فیلتر شما در جایی از سند HTML وجود دارد (حتی اگر پنهان باشد). معمولاً آن را در ابتدای <body> یا در یک <div style="position: absolute; width: 0; height: 0;"> پنهان قرار می‌دهند.

یک مثال کامل:

مایع شدن

در این مثال، متن “مایع شدن” بلافاصله با افکت مایع نمایش داده می‌شود. اما هنوز ثابت است.

مرحله ۵: افزودن انیمیشن

برای اینکه افکت مایع زنده به نظر برسد، باید آن را متحرک کنیم. رایج‌ترین روش‌ها برای انیمیشن‌سازی فیلترهای SVG عبارتند از:

  1. انیمیشن CSS: می‌توانیم با استفاده از CSS keyframes و تغییر خصوصیات SVG با استفاده از متغیرهای CSS، این کار را انجام دهیم. اما برای تغییر مستقیم پارامترهای فیلتر (مثل baseFrequency یا seed)، نیاز به راه حل‌های جایگزین یا انیمیشن‌های مبتنی بر JavaScript داریم.
  2. SMIL (Synchronized Multimedia Integration Language): این یک روش بومی SVG برای انیمیشن است که به شما اجازه می‌دهد پارامترهای فیلتر را مستقیماً انیمیت کنید.
  3. JavaScript: استفاده از جاوااسکریپت برای تغییر دوره‌ای پارامترهای فیلتر، که انعطاف‌پذیری بالایی ارائه می‌دهد.

در اینجا یک مثال با SMIL برای انیمیشن‌سازی baseFrequency آورده شده است:

<svg width="600" height="200" viewBox="0 0 600 200">
  <defs>
    <filter id="animated-liquid">
      <feTurbulence type="turbulence" baseFrequency="0.01 0.01" numOctaves="2" seed="0" result="noise-anim">
        <animate attributeName="baseFrequency" dur="8s" values="0.01 0.01; 0.03 0.015; 0.01 0.01" repeatCount="indefinite" />
      </feTurbulence>
      <feDisplacementMap in="SourceGraphic" in2="noise-anim" scale="40" xChannelSelector="R" yChannelSelector="G" />
    </filter>
  </defs>

  <text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle"
        font-family="Vazirmatn, sans-serif" font-size="70" fill="#28a745"
        filter="url(#animated-liquid)" class="animated-svg-text">
    متحرک!
  </text>
</svg>

در این مثال، تگ <animate> داخل <feTurbulence> پارامتر baseFrequency را بین سه مقدار مختلف در یک چرخه ۸ ثانیه‌ای تغییر می‌دهد و حس حرکت مایع را ایجاد می‌کند. (غلظت املایی: غلط املایی) توجه کنید که کلاس animated-svg-text صرفاً برای یک انیمیشن CSS خارجی روی عنصر متن است و انیمیشن اصلی فیلتر توسط SMIL انجام می‌شود.

برای انیمیشن با جاوااسکریپت، می‌توانید به صورت دوره‌ای baseFrequency یا seed را با استفاده از requestAnimationFrame یا setInterval تغییر دهید:

// فرض کنید SVG شما دارای id="mySvg" و فیلتر دارای id="animated-liquid" است
const feTurbulence = document.querySelector('#animated-liquid feTurbulence');
let seed = 0;

function animateLiquid() {
  seed += 0.5; // می‌توانید سرعت تغییر را کنترل کنید
  feTurbulence.setAttribute('seed', seed);
  requestAnimationFrame(animateLiquid);
}

// در صورت نیاز به تغییر baseFrequency:
// let frequency = 0.01;
// let increasing = true;
// function animateFrequency() {
//   if (increasing) {
//     frequency += 0.0001;
//     if (frequency >= 0.03) increasing = false;
//   } else {
//     frequency -= 0.0001;
//     if (frequency <= 0.01) increasing = true;
//   }
//   feTurbulence.setAttribute('baseFrequency', `${frequency} ${frequency / 2}`);
//   requestAnimationFrame(animateFrequency);
// }

// animateLiquid();
// animateFrequency(); // برای تست فرکانس

این کد JavaScript یک انیمیشن نرم و پیوسته برای افکت مایع ایجاد می‌کند. این روش انعطاف‌پذیری بیشتری را برای واکنش به تعاملات کاربر یا سایر رویدادها ارائه می‌دهد.

بهبود و شخصی‌سازی افکت

با تغییر پارامترهای feTurbulence و feDisplacementMap می‌توانید به انواع بسیار متنوعی از جلوه‌های مایع برسید:

  • تنظیم baseFrequency: فرکانس پایین‌تر برای امواج بزرگ و آرام، فرکانس بالاتر برای جزئیات ریز و تلاطم بیشتر.
  • تنظیم scale: مقدار scale در feDisplacementMap مستقیماً قدرت افکت مایع را کنترل می‌کند. مقادیر بالا به معنی جابجایی بیشتر و افکت اغراق‌آمیزتر است.
  • تغییر numOctaves: افزایش این مقدار نویز را پیچیده‌تر و طبیعی‌تر می‌کند، اما می‌تواند بار پردازشی را نیز افزایش دهد.
  • استفاده از xChannelSelector و yChannelSelector متفاوت: با انتخاب کانال‌های مختلف (R, G, B, A) می‌توانید جهت و الگوی جابجایی را تغییر دهید. مثلاً استفاده از "A" (آلفا) اگر نویز شما دارای کانال آلفا باشد.
  • ترکیب فیلترها: می‌توانید فیلترهای دیگری مانند feGaussianBlur (برای نرم کردن لبه‌ها) یا feColorMatrix (برای تغییر رنگ و کنتراست) را قبل یا بعد از فیلترهای اصلی اضافه کنید تا جلوه‌های پیچیده‌تری خلق کنید.
  • تعامل با کاربر: با جاوااسکریپت، می‌توانید پارامترهای فیلتر را بر اساس حرکت ماوس، اسکرول یا سایر ورودی‌های کاربر تغییر دهید تا یک تجربه تعاملی و دینامیک ایجاد کنید.
ایده خلاقانه: می‌توانید افکت مایع را روی تصاویر پروفایل کاربران یا لوگوی سایت اعمال کنید تا هنگام بارگذاری یا هاور ماوس، جلوه‌ای منحصر به فرد داشته باشند. این کار به طور ناخودآگاه برندسازی شما را تقویت می‌کند.

مزایا و محدودیت‌ها

همانند هر تکنولوژی دیگری، SVG فیلترها برای پیاده‌سازی افکت مایع دارای مزایا و محدودیت‌هایی هستند که شناخت آن‌ها به شما در تصمیم‌گیری و بهینه‌سازی کمک می‌کند.

مزایا محدودیت‌ها
عملکرد بالا: اجرای سخت‌افزاری بر روی GPU، که منجر به انیمیشن‌های روان می‌شود. پیچیدگی اولیه: یادگیری مفاهیم فیلترهای SVG ممکن است زمان‌بر باشد.
کیفیت بی‌نقص: برداری بودن SVG تضمین می‌کند که افکت در هر رزولوشنی بدون افت کیفیت نمایش داده شود. پشتیبانی مرورگر: هرچند خوب است، اما ممکن است تفاوت‌های جزئی در رندر بین مرورگرها وجود داشته باشد که نیاز به تست دارد.
انعطاف‌پذیری زیاد: کنترل دقیق بر پارامترها و امکان ترکیب فیلترها برای خلق جلوه‌های منحصربه‌فرد. اشباع بیش از حد: استفاده نادرست یا بیش از حد از این افکت می‌تواند باعث حواس‌پرتی و افت تجربه کاربری شود.
ترکیب با HTML و CSS: قابلیت اعمال فیلتر به عناصر DOM و ادغام آسان در پروژه‌های وب. بار پردازشی بالا: انیمیشن‌های بسیار پیچیده یا تعداد زیاد فیلترها می‌تواند به خصوص در دستگاه‌های ضعیف‌تر، بر عملکرد تاثیر بگذارد.

کاربردهای عملی افکت مایع

افکت مایع تنها یک جلوه بصری زیبا نیست؛ بلکه می‌تواند در موارد مختلفی برای بهبود تجربه کاربری و جذابیت بصری به کار رود:

  • جلوه‌های بارگذاری (Loaders): انیمیشن‌های مایع برای نشان دادن بارگذاری محتوا، جذابیت بیشتری نسبت به اسپینرهای ساده دارند و حس پویایی می‌دهند.
  • انتقال بین صفحات یا عناصر (Transitions): استفاده از این افکت در هنگام تغییر حالت یک دکمه، باز شدن یک منو، یا انتقال بین بخش‌های مختلف صفحه، تجربه‌ای روان و مدرن ایجاد می‌کند.
  • تعاملات دکمه و لینک (Button/Link Interactions): ایجاد جلوه‌های هاور یا کلیک مایع روی دکمه‌ها و لینک‌ها، بازخورد بصری جذابی به کاربر می‌دهد.
  • تصاویر پس‌زمینه پویا (Dynamic Backgrounds): استفاده از تصاویر یا ویدئوهای با افکت مایع برای پس‌زمینه بخش‌های خاصی از وب‌سایت یا تمام صفحه.
  • پروفایل‌های کاربری و آواتارها: افزودن یک حس فانتزی و مدرن به آواتارها و تصاویر پروفایل با انیمیشن‌های ظریف مایع.
  • جلوه‌های متن: عناوین و متون خاص می‌توانند با این افکت جان بگیرند و چشم‌نوازتر شوند.

عیب‌یابی سریع

ممکن است در حین پیاده‌سازی افکت مایع با مشکلاتی مواجه شوید. در اینجا به برخی از رایج‌ترین مشکلات و راه‌حل‌های آن‌ها اشاره می‌کنیم:

  • مشکل: فیلتر اعمال نمی‌شود یا هیچ افکتی دیده نمی‌شود.

    راه‌حل:

    1. مطمئن شوید id فیلتر در url(#your-id) به درستی نوشته شده باشد و با id داخل تگ <filter> یکسان باشد.
    2. بررسی کنید که تگ <svg> و <filter> به درستی بسته شده باشند و خطای نوشتاری نداشته باشند. از ابزارهای توسعه مرورگر (Developer Tools) برای بررسی ساختار DOM استفاده کنید.
    3. برای عناصر HTML، مطمئن شوید که تگ <svg> حاوی فیلتر شما در DOM وجود دارد و قابل دسترسی است. معمولاً آن را در ابتدای <body> و با display: none; پنهان می‌کنند.
  • مشکل: افکت بسیار ضعیف یا بسیار قوی است.

    راه‌حل:

    1. مقدار scale در feDisplacementMap را تنظیم کنید. مقادیر کوچک‌تر برای افکت ظریف‌تر و مقادیر بزرگ‌تر برای افکت شدیدتر.
    2. baseFrequency در feTurbulence را تغییر دهید. مقادیر کوچک‌تر (مثلاً 0.01) برای امواج بزرگ و نرم، مقادیر بزرگ‌تر (مثلاً 0.05) برای تلاطم بیشتر و جزئیات ریزتر.
  • مشکل: انیمیشن کار نمی‌کند.

    راه‌حل:

    1. اگر از SMIL استفاده می‌کنید، مطمئن شوید تگ <animate> داخل عنصر فیلتر صحیح قرار گرفته و attributeName و values آن درست باشد. SMIL در برخی مرورگرها (مانند IE/Edge قدیمی) پشتیبانی نمی‌شود، اما در مرورگرهای مدرن مشکلی ندارد.
    2. اگر از JavaScript استفاده می‌کنید، بررسی کنید که کد JS بدون خطا اجرا می‌شود و به درستی به عناصر SVG دسترسی دارد. از کنسول مرورگر برای یافتن خطاها کمک بگیرید.
  • مشکل: افت عملکرد (Performance) در مرورگر.

    راه‌حل:

    1. مقدار numOctaves در feTurbulence را کاهش دهید. مقادیر بالا به پردازش بیشتری نیاز دارند و ممکن است باعث کندی شوند.
    2. مقدار baseFrequency را کمی افزایش دهید تا جزئیات نویز کمتر شود.
    3. از انیمیشن‌های ساده‌تر استفاده کنید و از تغییر پارامترهای متعدد فیلتر به صورت همزمان خودداری کنید.
    4. مطمئن شوید SVG شما دارای ابعاد مشخص است و مرورگر مجبور به حدس زدن آن نیست.

سوالات متداول

آیا می‌توانم افکت مایع را به تصاویر PNG/JPG اعمال کنم؟

بله، می‌توانید. کافیست فیلتر SVG را به تگ <img> خود با استفاده از CSS (filter: url(#your-filter-id);) اعمال کنید. SVG فیلترها قابلیت پردازش پیکسل‌های تصاویر رستر را نیز دارند و می‌توانند آن‌ها را تغییر شکل دهند.

بهترین روش برای انیمیشن کردن افکت مایع چیست؟

بستگی به نیاز شما دارد. برای انیمیشن‌های ساده و خودکار که تغییرات پارامترها مشخص هستند، SMIL (تگ <animate> در SVG) گزینه مناسبی است. برای کنترل بیشتر، تعاملات کاربر، یا هماهنگی با انیمیشن‌های پیچیده‌تر، JavaScript بهترین انتخاب است. استفاده از CSS برای انیمیشن مستقیم پارامترهای فیلتر SVG محدودیت‌هایی دارد، اما برای انیمیشن عناصر HTML که فیلتر به آن‌ها اعمال شده، کاربردی است.

آیا این افکت روی تمام مرورگرها یکسان نمایش داده می‌شود؟

SVG فیلترها به طور گسترده توسط مرورگرهای مدرن (کروم، فایرفاکس، سافاری، اج) پشتیبانی می‌شوند. با این حال، ممکن است تفاوت‌های جزئی در رندرینگ یا عملکرد بین مرورگرها وجود داشته باشد، به خصوص در نسخه‌های قدیمی‌تر. همیشه توصیه می‌شود در مرورگرهای اصلی و target خود تست انجام دهید.

چگونه می‌توانم افکت را به صورت واکنشی (responsive) برای دستگاه‌های مختلف تنظیم کنم؟

می‌توانید اندازه <svg> را با استفاده از واحدهای نسبی (مانند درصد یا vw/vh) در CSS تنظیم کنید. برای پارامترهای فیلتر (مثل scale و baseFrequency)، می‌توانید از جاوااسکریپت برای تغییر آن‌ها بر اساس عرض صفحه، نسبت ابعاد یا حتی DPI استفاده کنید. همچنین، در SVG، استفاده از viewBox به جای width و height مستقیم، به مقیاس‌پذیری و انعطاف‌پذیری کمک شایانی می‌کند.

پیاده‌سازی افکت مایع با SVG فیلترها، دنیایی از خلاقیت‌های بصری را به روی شما باز می‌کند. با کمی آزمون و خطا و تنظیم پارامترها، می‌توانید جلوه‌های منحصربه‌فرد و فراموش‌نشدنی را برای پروژه‌های وب خود خلق کنید. امیدواریم این راهنمای جامع، ابزارهای لازم را برای شروع این سفر هیجان‌انگیز در اختیارتان قرار داده باشد. اکنون نوبت شماست که شروع به تجربه و ایجاد جادوی مایع در طراحی‌های خود کنید!

{
“@context”: “https://schema.org”,
“@type”: “FAQPage”,
“mainEntity”: [
{
“@type”: “Question”,
“name”: “آیا می‌توانم افکت مایع را به تصاویر PNG/JPG اعمال کنم؟”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “بله، می‌توانید. کافیست فیلتر SVG را به تگ خود با استفاده از CSS (filter: url(#your-filter-id);) اعمال کنید. SVG فیلترها قابلیت پردازش پیکسل‌های تصاویر رستر را نیز دارند و می‌توانند آن‌ها را تغییر شکل دهند.”
}
},
{
“@type”: “Question”,
“name”: “بهترین روش برای انیمیشن کردن افکت مایع چیست؟”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “بستگی به نیاز شما دارد. برای انیمیشن‌های ساده و خودکار که تغییرات پارامترها مشخص هستند، SMIL (تگ در SVG) گزینه مناسبی است. برای کنترل بیشتر، تعاملات کاربر، یا هماهنگی با انیمیشن‌های پیچیده‌تر، JavaScript بهترین انتخاب است. استفاده از CSS برای انیمیشن مستقیم پارامترهای فیلتر SVG محدودیت‌هایی دارد، اما برای انیمیشن عناصر HTML که فیلتر به آن‌ها اعمال شده، کاربردی است.”
}
},
{
“@type”: “Question”,
“name”: “آیا این افکت روی تمام مرورگرها یکسان نمایش داده می‌شود؟”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “SVG فیلترها به طور گسترده توسط مرورگرهای مدرن (کروم، فایرفاکس، سافاری، اج) پشتیبانی می‌شوند. با این حال، ممکن است تفاوت‌های جزئی در رندرینگ یا عملکرد بین مرورگرها وجود داشته باشد، به خصوص در نسخه‌های قدیمی‌تر. همیشه توصیه می‌شود در مرورگرهای اصلی و target خود تست انجام دهید.”
}
},
{
“@type”: “Question”,
“name”: “چگونه می‌توانم افکت را به صورت واکنشی (responsive) برای دستگاه‌های مختلف تنظیم کنم؟”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “می‌توانید اندازه را با استفاده از واحدهای نسبی (مانند درصد یا vw/vh) در CSS تنظیم کنید. برای پارامترهای فیلتر (مثل scale و baseFrequency)، می‌توانید از جاوااسکریپت برای تغییر آن‌ها بر اساس عرض صفحه، نسبت ابعاد یا حتی DPI استفاده کنید. همچنین، در SVG، استفاده از viewBox به جای width و height مستقیم، به مقیاس‌پذیری و انعطاف‌پذیری کمک شایانی می‌کند.”
}
}
]
}

Table of Contents

آخرین نوشته‌ها

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *