کار با گرافیک SVG در React — از صفر تا صد
در این مقاله به توضیح روش ایمپورت کردن SVG با استفاده از Webpack و انیمیت کردن آنها از طریق CSS و کامپوننتهای استایلدار میپردازیم. SVG اینک به یک ابزار استاندارد تصویرسازی تبدیل شده است. با ما همراه باشید تا روش کار با گرافیک SVG در React را بیاموزید. در ادامه این مقاله به بررسی ابزارهای استاندارد برای ایمپورت کردن SVG در پروژههای ریاکت میپردازیم و سپس برخی تکنیکها برای قالببندی و انیمیت کردن SVG با استفاده از CSS و کامپوننت استایلدار را مورد بررسی قرار میدهیم.
اینک SVG به طور گسترده از سوی مرورگرها پشتیبانی میشود و کاربردهای آنها با بهرهگیری از استایلبندی CSS برای کنترل گذارهای حالت و انیمیشن بهبود چشمگیری یافته است. وباپلیکیشنهای مدرن امروزه از SVG-ها برای طراحی اپلیکیشنهای واکنشگرا، کاهش اندازه فایلها و تعداد کاهش درخواستهای HTTP استفاده میکنند و بدین ترتیب تجربه کاربری بهتری نسبت به تصاویر مبتنی بر پیکسل ارائه میدهند.
در فریمورک ریاکت، SVG از طریق بارگذار Webpack پشتیبانی میشود. بدین ترتیب SVG-ها میتوانند به صورت کامپوننتهایی در ماژول ایمپورت شوند و در زمان build بهینهسازی شوند. ابزار Create React App از این بارگذار از نسخه 2 به بعد استفاده میکند و SVG-ها را ایمپورت کرده و آنها را در JSX جای میدهد:
1// importing a logo SVG and embedding it in JSX
2import { ReactComponent as Logo } from './logo.svg';
3const MyComponent = () => {
4 return (
5 ...
6 <Logo />
7 );
8}
پکیج استفادهشده در کد فوق SVGR نام دارد. این پکیج گستردهترین استفاده را برای تبدیل SVG-ها به کامپوننتهای ریاکت دارد.
SVGR یا SVG ریاکت
SVGR (+) فایلهای SVG اکسترنال را میگیرد و آنها را به کامپوننتهای ریاکت تبدیل میکند. این پکیج طیفی از ابزارهای کاربردی را میزبانی میکند که هر کدام راهحلهایی عرضه میکنند که بسته به چارچوب دستکاری SVG مورد نیاز هستند.
پراستفادهترین ابزار در این زمان Webpack loader (+) است که در حال حاضر 1.4 میلیون دانلود هفتگی دارد و نشان میدهد که جامعه توسعهدهندگان جاوا اسکریپت نسبت به رویکرد ایمپورت کردن SVG-ها در ریاکت توجه زیادی دارند.
Webpack loader یکی از سه راهحل اصلی است که SVGR ارائه میکند. بسته به این که علاقه دارید SVG-ها را در خط فرمان دستکاری کنید یا نه، یک اسکریپت خودکار سازی شده وجود دارد و همچنین میتوان آنها را در ماژولها نیز ایمپورت کرد:
- svgr/cli@: ابزار CLI دستورهای سادهای در اختیار ما قرار میدهد که با آنها میتوانیم فایلهای منفرد یا کل دایرکتوریهای فایلهای SVG را به فایلهای js. کامپوننتهای ریاکت تبدیل کنیم.
- svgr/core@: این پکیج مرکزی SVGR برای جاسازی درون برنامههای NodeJS طراحی شده است تا ابزارهای خودکاری برای پردازش SVG-ها درون کامپوننتها ایجاد شود.
- svgr/webpack@: پراستفادهترین راهحل و ابزاری عالی برای ایمپورت کردن SVG-ها به صورت کامپوننتهای ریاکت است.
- پلاگین Rollup یا Parcel: دو ابزار دیگر بستهبندی ماژول جاوا اسکریپت که کمتر شناخته شدهاند، اما از SVGR پشتیبانی میکنند.
استفاده همزمان از پکیجهای فوق مزیتهای زیادی دارد. CLI و API مربوط به Node و پکیجهای Webpack میتوانند در صورت نیاز درون گردشکار مدیریت SVG در پروژههای ریاکت استفاده شوند.
ما در این مقاله صرفاً روی Webpack loader متمرکز میشویم. در ادامه از آن برای نشان دادن یک مثال واقعی از یکپارچهسازی SVG در اپلیکیشنهای مدرن بهره خواهیم گرفت.
دستکاری SVG-ها از طریق CSS
چندین روش برای استفاده از CSS همراه با SVG-ها وجود دارد، اما از آنجا که تمرکز ما روی توسعه ریاکت است به پیادهسازی آن از طریق کامپوننتهای استایلدار علاقهمند هستیم.
برای تکمیل بودن بحث، مرور سریعی بر روشهای مختلف استفاده از CSS درون SVG-ها خواهیم داشت، چون نرمافزارهایی مانند ایلاستریتور بیشک SVG را با دستکم برخی از این تکنیکها اکسپورت میکنند. با درک دقیق شیوه انتساب استایل ها به SVG-ها، میتوانید آنها را بهینهسازی کرده و مواردی که دیگر لازم نیستند یا در جای دیگری در پروژه تعریف شدهاند، حذف کنید.
خصوصیتهای درونخطی
استایل ها به طور عمده روی XML خود SVG اعمال میشوند که شبیه به وضعیت زیر است:
1// CSS properties via attributes
2<svg>
3 ...
4 <path
5 fill="none"
6 stroke-linecap="round"
7 stroke-miterlimit="10"
8 stroke="#000"
9 stroke-width="15"
10 ...
11 />
12</svg>
نکته: برخی از این مشخصهها بیشک در سطح کامپوننت پروژهها نیز تعریف میشوند، اما بهتر است برخی مقادیر پیشفرض مانند stroke ،fill ،stroke-width و stroke-linecap برای پیشنمایش آسانتر درون خود SVG بمانند.
خصوصیت استایل
با این که این وضعیت عمومیت کمتری دارد، اما خصوصیت style درون یک SVG نیز پشتیبانی میشود:
1<path
2 style="stroke: #000; ..."
3 ...
4/>
استایلشیتهای درونخطی با تگ style
در مورد پکیجهای SVG یک روش معمول دیگر نیز این است که از تگ <style /> با کلاسهای CSS برای طیفی از مسیرها و شکلها استفاده میشود. تگ <style /> درون تگ <defs /> تعریف میشود:
1<svg>
2 <defs>
3 <style>
4 .cls-1 {
5 fill: none;
6 stroke-linecap: round;
7 stroke-miterlimit: 10;
8 stroke-width:15px
9 }
10 </style>
11 </defs>
12 <path
13 class="shine cls-1"
14 ...
15 />
16</svg>
استایل یا یک شکل کلی مانند یک circle است و یا کلاسهایی ایجاد میکند که به مسیرها و شکلها انتساب مییابند.
استایلشیتهای بیرونی
اینک با جداسازی CSS از فایل SVG و بردن آن به یک استایلشیت جداگانه، به یک الگوی طراحی ماژولار نزدیکتر شدهایم. این کار دستکاری را آسانتر میسازد و استایلشیت میتواند درون هدر صفحه وب قرار گیرد و یا در خود فایل SVG گنجانده شود:
1<?xml-stylesheet type="text/css" href="svg-stylesheet.css" ?>
2<svg>
3 <circle
4 cx="20"
5 cy="20"
6 r="10"
7 />
8</svg>
این رویکرد دوم برای یک فریمورک جاوا اسکریپت ایدهآل نیست، ما به جای آن عموماً دوست داریم که استایلها در سطح کامپوننت بدون وابستگی اکسترنال مانند استایلشیت های CSS تعریف شوند. از این رو اینک به استفاده از کامپوننتهای استایلدار همراه با SVG-ها برای ایجاد برخی انیمیشنهای جذاب و همزمان با قالببندی اپلیکیشن میپردازیم.
کامپوننتهای استایلدار و SVG-ها
داشتن امکان جاسازی مشخصههای SVG CSS درون کامپوننتهای ریاکت شاید مفیدترین ابزار برای استایلبندی یک SVG از طریق CSS باشد که مزیتهای زیادی دارد:
- میتوانیم کامپوننتهای با استایلبندی سراسری را اکسپورت کرده و سپس آنها را در طیفی از کامپوننتها که نیازمند یک استایل SVG یکسان هستند، ایمپورت کنیم.
- میتوانیم برعکس امکان فوق عمل کنیم، یعنی هر کامپوننت میتواند استایلبندی منحصر به فرد خود را روی یک SVG تعریف کند. خود SVG هیچ گونه استایل غیر ضروری را ایمپورت نمیکند و یا در این مسیر هیچ استایلشیت غیر لازمی را الصاق نمیکند.
- اینک اکوسیستم کامپوننت استایلدار را در اختیار داریم و میتوانیم به قابلیتهای props و قالببندی دسترسی داشته باشیم. به این ترتیب میتوان به سادگی یک کاتالوگ از SVG-ها را بر مبنای قالب کنونی اپلیکیشن ویرایش کرد.
داشتن امکان قالببندی SVG-ها شاید بهترین کاربرد ترکیب کامپوننتهای استایلدار و SVG-ها باشد. دیگر آن روزها که برای حفظ قالب یک وبسایت باید از تصاویر و یا دیگر asset-ها استفاده میکردیم گذشته است. اینک انجام این کار به سادگی با یک SVG و دسترسی به مشخصههای آن میسر است.
نکته: درصورتیکه SVG-ها را درون یک تگ <img /> جاسازی کنید، نمیتوانید به مشخصههای SVG دسترسی داشته باشید. با این که این کار به طور رایجی در پروژههای نه چندان مهم انجام میشود، اما قویاً پیشنهاد میکنیم که از رویکرد SVGR استفاده کنید.
بررسی انیمیشن Stroke با SVG تغییر قالب
یک نمونه عالی از آن چه در مورد راهحلهای تغییر قالب میتوان بررسی کرد را در ادامه میتوانید ببینید. در این مثال SVG-ها با انیمیشن CSS ترکیب شدهاند تا اثر زیر خلق شود:
انیمیشن تغییر قالب در مثال فوق به طور کامل مبتنی بر CSS (بدون جاوا اسکریپت) است و از چند مشخصه CSS برای دستکاری Stroke در SVG بهره میگیرد. کدنویسی این مثال را در ادامه بررسی خواهیم کرد. لوگوی JKRB Investments نیز یک SVG ایمپورت شده است که کاملاً قابلیت قالبپذیری دارد. این استایلبندی SVG به صورت کامل با کامپوننتهای استایلدار اپلیکیشن یکپارچه شده است. زمانی که روی دکمه کلیک کنید، حالت قالب یک رندر مجدد SVG را تحریک میکند و آنها را به استایلبندی قالب بهروز شده گذار میدهد.
اینک سؤال این است که کدام استایلها در عمل در اینجا دستکاری شدهاند؟ در ادامه مشخصههای اصلی پیش از بررسی جزئیتر در یک دید سطح بالا توضیح داده شدهاند:
مشخصه fill مربوط به لوگوی JKRB رنگ آن را تعیین میکند. خود مقدار fill از سوی قالب جاری تعیین میشود که در این مورد light یا dark است:
1// wrapping SVGs in theme-able components
2import styled from 'styled-components';
3import theme from 'styled-theming';
4export const backgroundColor = theme('mode', {
5 light: '#fafafa',
6 dark: '#0e0f11'
7});
8const LogoWrapper = styled.div`
9 svg {
10 fill: ${backgroundColor};
11 }
12`;
مشخصه stroke دکمه قالب، رنگ آن تعیین میکند که مقدار آن نیز از قالب کنونی نشأت میگیرد. مشخصههای stroke-dasharray و stroke-dashoffset انیمیشن Stroke یکسانی ارائه میکنند. همچنین stroke-width امکان تغییر دادن ضخامت Stroke را فراهم میسازد.
انیمیشن keyframe@ برای گذار Stroke استفاده میشود و همچنین شفافیت تابش آفتاب را تنظیم میکند. بدین ترتیب SVG-ها، استایلبندی CSS، انیمیشنهای کیفریم و کامپوننتهای استایلدار قالبپذیر را برای دستیابی به این اثر با هم ترکیب کردهایم.