با نسخه Chrome 88 ، پشتیبانی از آن را دریافت کردیم clip-path: path(). این یعنی اکنون پشتیبانی می کند در “بیشتر” مرورگرهای اصلی!

با path()، ما می توانیم از تعاریف مسیر برای a استفاده کنیم clip-path. (شما به چه رسیدید clip-path است اینجا) این رشته های تعریف مسیر همان رشته هایی هستند که می توانیم با آنها استفاده کنیم عنصر مسیر SVG. نکته جالب در این مورد این است که راهی برای ایجاد اشکال فراهم می کند که احتمالاً قبل از آن استفاده از SVG بوده است. ما حتی می توانیم مسیرهایی ایجاد کنیم که بدون نیاز به هیچ گونه ترفندی از بین بروند.

با افزایش پشتیبانی ، فرصتی پیش آمد تا با آن چیز سرگرم کننده ای امتحان کنم! بیایید “پرتره های Squeaky” را بسازیم! استفاده از آن سرگرم کننده است clip-path: path() تا ناحیه قابل مشاهده یک عنصر را در این حلاجی های “Nickelodeon-esque” کلیپ کنید.

ایجاد یک مسیر

در مرحله اول ، ما به رشته تعریف مسیر SVG خودمان نیاز داریم. و در این مورد ، بیش از یک. چیز شسته و رفته با clip-path این است که ما می توانیم آنها را با CSS انتقال دهیم. تا زمانی که clip-path عملکرد و تعداد گره ها سازگار است ، ما می توانیم انتقال دهیم.

برای ایجاد برخی مسیرها ، می توانیم به هر ویرایشگر گرافیکی برداری برویم. در این حالت ، من استفاده می کنم فیگما. و به جای ایجاد مسیرها از ابتدا ، می توانیم از “splat” دلخواه به عنوان پایه استفاده کنیم. این یکی خوب به نظر می رسد!

نمونه Splat به صورت آنلاین یافت شد

نمونه Splat به صورت آنلاین یافت شد

ترفند در اینجا ایجاد splats بیشتر بر اساس splat Foundation است. و ما باید این کار را بدون معرفی و حذف گره انجام دهیم. این سه اسپلاتی است که من به آنها رسیدم. اما به شرطی که به این قانون پایبند باشید می توانید هر شکلی را که دوست دارید ایجاد کنید!

سه اسپلت مختلف ساخته شده از یک Splat

سه اسپلت مختلف ساخته شده از یک Splat

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

اما آیا من نگفتم که آنها به تعداد ثابت امتیاز نیاز دارند؟ انجام می دهند. و این چیزی است که ما در اینجا داریم! این دو حباب برای هر چلپ چلوپ ظاهر می شود. اما ترفند این است که در صورت عدم نیاز می توانیم آنها را در پس مانده مسیر حرکت دهیم.

Figma نشان دهنده دو حباب در پشت مسیر اصلی است

Figma نشان دهنده دو حباب در پشت مسیر اصلی است

هنگامی که splats خود را پیدا کردیم ، می توانیم آنها را صادر کنیم و رشته های تعریف مسیر را بدست آوریم:

قلم را ببینید
1. SVG Splats
توسط SitePoint (SitePoint)
بر CodePen.

استفاده از Splats

برای اعمال splats ، ما قصد داریم متغیرهایی برای هر مسیر ایجاد کنیم:

.portrait {
  --splat: "M161 188.375C170 193.5 177.919 193.854 186 188.375C197.919 180.294...";
  --splattier: "M161 188.375C170 193.5 177.919 193.854 186 188.375C197.919...";
  --splatted: "M232.5 256C225 251 209.5 262.5 224 281.5C232.736 292.948...";
}

این مسیرهایی است که ما مستقیماً از SVG صادر شده برداشته ایم.

ما با نام های “splat” ، “splattier” و “splatted” می رویم. نام بردن از کارها سخت است. هان اما برای مثال SVG “پاشیده” را در نظر بگیرید:

<svg width="300" height="300" viewBox="0 0 300 300" fill="none" xmlns="http://www.w3.org/2000/svg">
  <path d="M232.5 256C225 251 209.5 262.5 224 281.5C232.736 292.948 238.561 297.756 251 290.5C257 287 256.114 271.924 250 264.5C243.886 257.076 240 261 232.5 256ZM147 92.5C118.738 94.6708 118 17 93 44C68 71 123.543 76.5 108 101.5C90.5 115 70.81 98.3664 64 115C56.7766 132.643 91.1967 136.948 90.5 156C89.4406 184.974 19.1766 161.499 24.5 190C29.9178 219.006 78.6461 172.635 100 193C130.207 221.808 1 248.5 58.5 291.5C94.5576 318.465 114.991 206.551 140.5 211C183.5 218.5 134.5 294 186.5 279.5C207.5 273 174.638 224.658 196 204C223.117 177.777 275.916 253 291.5 218.5C311.375 174.5 228.698 194.565 224 160C219.553 127.282 291.5 123.5 267.5 87.5C238.5 57 247 125.5 196 105.5C147 92.5 229.5 13.5 173.5 2.5C140.5 2.49999 183.532 89.694 147 92.5ZM45 92.5C36.8766 80.3149 14.1234 75.3149 6.00001 87.5C0.584412 95.6234 2.00001 120.357 14.5 115C27.9606 109.231 36.8766 124.685 45 112.5C50.4156 104.377 50.4156 100.623 45 92.5Z" fill="#A91CFF"/>
</svg>

ما داریم بلند می کنیم d صفت از path عناصر و ایجاد متغیرهای CSS برای آنها. بعد ، ما به عنصری نیاز داریم که این موارد را در آن اعمال کنیم. بیایید با کلاس “portrait” یک عنصر ایجاد کنیم:

<div class="portrait"></div>

در مرحله بعدی ، برخی از سبک ها را روی آن اعمال کنید:

.portrait {
  --splat: "M161 188.375C170 193.5 177.919 193.854 186 188.375C197.919 180.294...";
  --splattier: "M161 188.375C170 193.5 177.919 193.854 186 188.375C197.919...";
  --splatted: "M232.5 256C225 251 209.5 262.5 224 281.5C232.736 292.948...";
  --none: "";
  height: 300px;
  width: 300px;
  background: #daa3f5;
  clip-path: path(var(--clip, var(--none)));
  transition: clip-path 0.2s;
}

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

قلم را ببینید
2. استفاده از Clip Splat
توسط SitePoint (SitePoint)
بر CodePen.

توجه داشته باشید که چگونه شکل بین سه شکل splat جابجا می شود. اما ، همچنین توجه داشته باشید که چگونه به عنصر خود ارتفاع و عرض مشخصی داده ایم. این اندازه با ابعاد صادرات SVG ما مطابقت دارد. این هست مهم. این یکی از اشکالات استفاده از آن است clip-path: path(). پاسخگو نیست تعریف مسیر نسبت به ابعاد عنصر شماست. این همان مشکلی است که مسیرهای حرکت CSS با آن روبرو هستند.

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

اثر متقابل

برای نسخه ی نمایشی ما ، ما می خواهیم splat تعاملی باشد. ما می توانیم این کار را فقط با CSS انجام دهیم. ما می توانیم از یک متغیر CSS scoped استفاده کنیم – --clip – برای کنترل کلیپ فعلی. و سپس می توانیم آن متغیر را روی هر دو به روز کنیم :hover و :active. --active هنگامی که نشانگر خود را فشار می دهیم حالت فعال می شود:

.portrait {
  clip-path: path(var(--clip, var(--splat)));
}
.portrait:hover {
  --clip: var(--splattier);
}
.portrait:active {
  --clip: var(--splatted);
}

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

قلم را ببینید
3. Splat تعاملی
توسط SitePoint (SitePoint)
بر CodePen.

اضافه کردن برخی از نویسه ها

اکنون که می توانیم اسپات را انتقال دهیم ، به کمی چیز اضافی نیاز دارد. اگر ما آن را در آن حالت ها نیز تبدیل کنیم چه می کنیم؟

.portrait {
  transition: clip-path 0.2s, transform 0.2s;
  transform: scale(var(--scale, 1)) rotate(var(--rotate, 0deg));
}
.portrait:hover {
  --scale: 1.15;
  --rotate: 30deg;
}
.portrait:active {
  --scale: 0.85;
  --rotate: -10deg;
}

استفاده از متغیرهای CSS محدود برای اعمال a transform، ما می توانیم چیزی اضافه کنیم. در اینجا ما scale و rotation از تفاله ما ما می توانیم با مقادیر مختلف آزمایش کنیم و با جلوه های مختلف در اینجا بازی کنیم. کمی ترجمه عنصر می تواند خوب به نظر برسد؟

قلم را ببینید
4. اضافه کردن برخی از شخصیت ها
توسط SitePoint (SitePoint)
بر CodePen.

افزودن پرتره

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

سه ژست احمقانه

سه ژست احمقانه

سپس باید آنها را در پرتره قرار دهیم:

<div class="portrait">
  <img class="portrait__img" src="/me--standing.png" alt="Me"/>
  <img class="portrait__img" src="/me--noticing.png" alt="Me"/>
  <img class="portrait__img" src="/me--falling.png" alt="Me"/>
</div>

عالی به نظر نمی رسد آنها به برخی از سبک ها نیاز دارند:

.portrait {
  position: relative;
}
.portrait__img {
  height: 100%;
  width: 100%;
  position: absolute;
  top: 0;
  left: 0;
}

تقریباً آنجا:

قلم را ببینید
5. قرار دادن پرتره ها در جای خود
توسط SitePoint (SitePoint)
بر CodePen.

چگونه می توانیم آنها را نشان دهیم و پنهان کنیم :hover و :active. این کمی لفظی است ، اما ما می توانیم استفاده کنیم nth-of-type با display: none:

.portrait__img {
  display: none;
}
.portrait__img:nth-of-type(1) {
  display: block;
}
.portrait:hover .portrait__img:nth-of-type(1),
.portrait:hover .portrait__img:nth-of-type(3) {
  display: none;
}
.portrait:hover .portrait__img:nth-of-type(2) {
  display: block;
}
.portrait:active .portrait__img:nth-of-type(1),
.portrait:active .portrait__img:nth-of-type(2) {
  display: none;
}
.portrait:active .portrait__img:nth-of-type(3) {
  display: block;
}

چرا آن سبک ها را refactor نمی کنیم و آنها را گروه بندی نمی کنیم؟ آبشار وارد خواهد شد و ما اثر مورد نظر خود را نخواهیم گرفت.

قلم را ببینید
6. نمایش / پنهان کردن پرتره ها
توسط SitePoint (SitePoint)
بر CodePen.

نمادهای اختلاف منظر

ما به آنجا می رسیم ، اما به نظر می رسد کمی لکه دار است. اگر یک نماد را بکشیم ، می توانیم یک اثر اختلاف منظر ابتدایی ایجاد کنیم. بیا با این یکی بریم

نمادی که براکت های زاویه ای را در اطراف یک اسلش رو به جلو نشان می دهد

ترفند در اینجا این است که از یک تصویر به عنوان پس زمینه برای عنصر خود استفاده کنید اما اندازه آن را طوری بگیرید که با کاشی کاری شود background-repeat:

.portrait {
  background-image: url("/code-icon.svg");
  background-color: hsl(10, 80%, 70%);
}

شسته و رفته

قلم را ببینید
7. نمادهای BG
توسط SitePoint (SitePoint)
بر CodePen.

اما ما اختلاف منظر می خواهیم! برای به دست آوردن این اثر اختلاف منظر ، می توانیم background-position در پاسخ به حرکت اشاره گر. و می توانیم موقعیت نشانگر را در برابر محدودیتی که تعریف می کنیم ترسیم کنیم.

بیایید با ایجاد یک برنامه کاربردی که یک تابع نقشه برداری برای ما تولید می کند شروع کنیم. تابع بازگشتی به ما نتیجه یک مقدار در یک محدوده ترسیم شده روی دامنه دیگر را می دهد:

const genMapper = (inputLower, inputUpper, outputLower, outputUpper) => {
  const inputRange = inputUpper - inputLower
  const outputRange = outputUpper - outputLower
  const MAP = input => outputLower + (((input - inputLower) / inputRange) * outputRange || 0)
  return MAP
}

لحظه ای وقت بگذارید تا بفهمید اینجا چه اتفاقی می افتد. به عنوان مثال ، اگر محدوده ورودی ما بود 0 به 500 و دامنه خروجی ما بود 0 به 100، نتیجه فراخوانی عملکرد برگشتی با چه نتیجه ای خواهد بود 250؟ می شود 50:


genMapper(0, 500, 0, 100)

const inputRange = 500
const outputRange = 100
const MAP => input => 0 + (((input - 0) / 500) * 100)

(250 / 500) * 100
0.5 * 100

50

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

const LIMIT = 25 
const getX = genMapper(0, window.innerWidth, -LIMIT, LIMIT)
const getY = genMapper(0, window.innerHeight, -LIMIT, LIMIT)

قسمت آخر گره زدن آن با شنوندگان رویداد است. ما ساختار را از بین می بریم x و y مقدار از رویداد و تنظیم متغیرهای CSS بر روی عنصر پرتره. ارزش از عبور می رسد x و y به توابع نقشه برداری مربوطه:

const PORTRAIT = document.querySelector('.portrait')
document.addEventListener('pointermove', ({ x, y }) => {
  PORTRAIT.style.setProperty('--x', getX(x))
  PORTRAIT.style.setProperty('--y', getY(y))
})

و اکنون آیکون های اختلاف منظر داریم!

قلم را ببینید
8. نمادهای اختلاف منظر
توسط SitePoint (SitePoint)
بر CodePen.

Squeak

آخرین لمس در عنوان است. ما به چند جیر جیر نیاز داریم. من معمولاً بایت های صوتی را در سایت هایی مانند freesound.org. هرچند می توانید آنها را در انواع مکان ها تهیه کنید و در صورت تمایل حتی خودتان آنها را ضبط کنید.

ایده بدی نیست که شیئی را ایجاد کنید که بتوانید به آن مراجعه کنید Audio:

const AUDIO = {
  IN: new Audio('/squeak-in.mp3'),
  OUT: new Audio('/squeak-out.mp3'),
}

سپس ، برای پخش یک کلیپ صوتی ، تنها کاری که باید انجام دهیم این است:

AUDIO.IN.play()

ما باید این را با تصویر خود تلفیق کنیم. ما می توانیم از pointerdown و pointerup وقایع اینجا – ایده این است که وقتی فشار می دهیم یک صدای جیر جیر و دیگری هنگام آزادی بازی می کنیم.

اگر کاربر به سرعت پشت سر هم پرتره را زیاد کلیک کند ، این می تواند اثرات نامطلوبی ایجاد کند. ترفند این است که صدای دلخواه را پخش کنید و همزمان صدای دیگر را متوقف کنید. برای “متوقف کردن” یک قطعه از Audio، می توانیم آن را مکث کرده و تنظیم کنیم currentTime به 0:

PORTRAIT.addEventListener('pointerdown', () => {
  AUDIO.OUT.pause()
  AUDIO.IN.currentTime = AUDIO.OUT.currentTime = 0
  AUDIO.IN.play()
})
PORTRAIT.addEventListener('pointerup', () => {
  AUDIO.IN.pause()
  AUDIO.IN.currentTime = AUDIO.OUT.currentTime = 0
  AUDIO.OUT.play()
})

و این به ما “پرتره مبهم” می دهد!

قلم را ببینید
9. یک پرتره Squeaky!
توسط SitePoint (SitePoint)
بر CodePen.

خودشه!

اینگونه است که شما “Portraits Squeaky” را می سازید. اما نکته قابل اجرا در اینجا لذت داشتن در حین آزمایش چیزهای جدید است.

قلم را ببینید
Squeaky Portraits 😅 (کلیپ مسیر: مسیر ())
توسط SitePoint (SitePoint)
بر CodePen.

می توانستم چند شکل را شکل دهم و در آنجا بگذارم. اما چرا در اینجا متوقف شد؟ چرا ایده ای به ذهنتان نمی رسد و با آن کمی سرگرم نمی شوید؟ این یک روش عالی برای امتحان کردن چیزها و کشف تکنیک ها است.

به طور خلاصه ، ما:

  • کلیپ ها را ایجاد کرد
  • آنها را با انتقال تغییر شکل داد
  • تصاویر تعاملی ساخته شده است
  • صوتی اضافه شده است
  • اختلاف منظر را با یک ابزار نقشه برداری ایجاد کرد

با چه کاری می توانستید انجام دهید clip-path: path()؟ “Squeaky Portrait” شما چه شکلی است؟ این می تواند کاری کاملا متفاوت انجام دهد. خیلی دوست دارم ببینم شما چه می سازید!

مثل همیشه، با تشکر برای خواندن. می خواهم بیشتر ببینم؟ بیا منو پیدا کن توییتر یا بررسی کنید جریان مستقیم!

PS اگر می خواهید همه کد ها را بگیرید ، اینجا در این قسمت است مجموعه CodePen.