اگر کوچکترین علاقه ای به بازی های ویدیویی دارید ، بدون شک از Cyberpunk 2077 آگاه هستید. این یکی از مورد انتظارترین بازی های سال 2020 است. دنیایی که می کشد سبک خاصی دارد. وب سایت بازی در به تصویر کشیدن زیبایی شناسی کار درخشان انجام می دهد. طراحی آن در برقراری ارتباط ظاهری و احساسی بسیار عالی عمل می کند. همانطور که می توانید تصور کنید ، این بدان معنی است که دارای برخی از اجزای UI نسبتاً ظریف است.

ابتدا شخصی با من تماس گرفت و از من پرسید چگونه می توانم جلوه تصویری مورد استفاده در سایت را ایجاد کنم. اگر تصاویر را در گالری های تصویر قرار دهید ، این جلوه “نویز” منظمی دارد.

یک جلوه ناقص و سر و صدا هنگام قرار گرفتن در بالای صحنه

من این چالش را پذیرفتم. من حفاری کردم تا نگاهی به منبع سایت بیندازم. پس از کمی حفاری ، متوجه شدم که این برنامه با سایه بان و WebGL در حال اجرا است. من کاملاً در نوشتن سایه بان و WebGL تازه کار هستم. این باعث شد من امتحان کنم. اما ، در حال حاضر ، من یادگیری WebGL و کد سایه بان را در مورد ردیف های بعدی قرار داده ام.

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

یک دکمه روشن و روشن موجود

و در اینجا نحوه انجام این کار وجود دارد!

دکمه جلوه

بیایید با برخی از نشانه گذاری شروع کنیم:

<button class="cybr-btn">
  Beginning_
</button>

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

بیایید یک قانون سفارشی @ font-face ایجاد کنیم:

@font-face {
  font-family: Cyber;
  src: url("https://assets.codepen.io/605876/Blender-Pro-Bold.otf");
  font-display: swap;
}

هنگامی که این مورد را بدست آوردیم ، می توانیم سبک اصلی را در جای خود قرار دهیم. استفاده از متغیرهای CSS برای مواردی مانند رنگ و اندازه قلم بعداً به ما فرصت می دهد. دلیل استفاده از فضای رنگی HSL نیز به همین دلیل است. بعداً دلیل آن را نشان خواهیم داد.

--primary: hsl(var(--primary-hue), 85%, calc(var(--primary-lightness, 50) * 1%));
--shadow-primary: hsl(var(--shadow-primary-hue), 90%, 50%);
--primary-hue: 0;
--primary-lightness: 50;
--color: hsl(0, 0%, 100%);
--font-size: 26px;
--shadow-primary-hue: 180;

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

قلم را ببینید
دکمه CSS Cyberpunk 2077: آغاز
توسط SitePoint (SitePoint)
بر CodePen.

گوشه قطع شده

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

ما می توانیم گوشه را با استفاده از clip-path ویژگی:

clip-path: polygon(-10% -10%, 110% -10%, 110% 110%, 10% 110%, -10% 40%);

توجه داشته باشید که چگونه لبه های دکمه را نمی گیریم. ما به دکمه 10 درصد فضای تنفس می دهیم. این به این دلیل است که ما باید برچسب “R25” و این واقعیت را که اثر ناخوشایند خارج از دکمه جریان دارد ، حساب کنیم. این یک ترفند شسته و رفته است clip-path. ما می توانیم از آن به عنوان کنترل شده استفاده کنیم overflow: hidden. ما می گوییم ، “بله ، شما می توانید کمی سرریز کنید. اما فقط همین مقدار “.

افزودن آن به دکمه ما جلوه بریده شده مورد نظر ما را می دهد.

قلم را ببینید
دکمه CSS Cyberpunk 2077: برش
توسط SitePoint (SitePoint)
بر CodePen.

ایجاد برچسب R25

بعد ، بیایید آن برچسب “R25” را ایجاد کنیم. ما می توانیم به یک عنصر شبه در اینجا دسترسی پیدا کنیم و از آن استفاده کنیم content ویژگی. در حقیقت ، این روش در سایت انجام می شود. اما با این روش باید به آن توجه داشت – این واقعیت که خواننده صفحه ممکن است آن را بخواند. متن واقعی دکمه نیز صدق می کند. هر دکمه در سایت دارای یک متن با موفقیت است. آیا ما می خواهیم که توسط خواننده صفحه خوانده شود؟ اگر بله ، پس می توانیم آن را همانطور که هست بگذاریم. بیایید فرض کنیم که آنها برای اهداف تزئینی هستند. ما می توانیم نشانه گذاری و استفاده خود را به روز کنیم aria-hidden به طوری که یک صفحه خوان فقط متن دکمه را می خواند:

<button class="cybr-btn">
  Clipped<span aria-hidden>_</span>
  <span aria-hidden class="cybr-btn__tag">R25</span>
</button>

برای سبک کردن برچسب ، می توانیم آن را ارائه دهیم absolute تثبیت موقعیت. این نیاز به تنظیم ما دارد relative قرارگیری بر روی دکمه. مانند خود دکمه ، برچسب از an استفاده می کند inset box-shadow:

.cybr-btn {
  --label-size: 9px;
  --shadow-secondary-hue: 60;
  --shadow-secondary: hsl(var(--shadow-secondary-hue), 90%, 60%);
  position: relative;
}
.cybr-btn__tag {
  position: absolute;
  padding: 1px 4px;
  letter-spacing: 1px;
  line-height: 1;
  bottom: -5%;
  right: 5%;
  background: var(--shadow-secondary);
  color: hsl(0, 0%, 0%);
  font-size: var(--label-size);
  box-shadow: 2px 0 inset var(--shadow-primary);
}

ما برخی دیگر از متغیرهای CSS را در اینجا معرفی کرده ایم. اگرچه آنها توسط برچسب استفاده می شوند ، ما آنها را زیر انتخاب دکمه قرار داده ایم. این یک دلیل دارد. بعداً ممکن است تصمیم بگیریم از قدرت متغیرهای حوزه استفاده کنیم. در صورت انجام این کار ، فقط باید متغیرها را روی انتخابگر دکمه تنظیم کنیم. اگر متغیرها را تحت قانون برچسب بگذاریم ، متغیرهایی که روی دکمه تنظیم شده اند قدرت دامنه کمتری ندارند. ما تنظیم کردیم background-color برای برچسب. اما خیلی زود مشخص می شود که این کار در سایت انجام نمی شود.

با درج برچسب ما ، اکنون دکمه در حال شکل گرفتن است.

قلم را ببینید
دکمه های CSS Cyberpunk 2077: برچسب گذاری
توسط SitePoint (SitePoint)
بر CodePen.

افزودن جلوه glitch

زمان اثر قطعی است. از نظر تجربه ، فرض من در اینجا این بود که دکمه در حال کپی شدن است. دکمه کپی دارای نوعی انیمیشن برش خورده است. اولین کار ما در اینجا ایجاد بدنه glitch است. یادتان هست که ما قبلاً استفاده از تصویر پس زمینه را کشف کردیم؟ به زودی مشخص شد که چرا از آن استفاده می شود: تهیه برش برای برچسب. این یعنی background-color پشت دکمه برای برچسب یکسان است. گوشه برش خورده نیز با تصویر ایجاد می شود.

زمینه قرمز

توجه کنید که چگونه مرز آبی گوشه را دنبال می کند و دور “R25” را می چرخاند؟ با استفاده از یک مسیر کلیپ ، آن گوشه را برش داده و “R25” را به طور کلی مشخص نمی کند. پیاده سازی سایت از a drop-shadow.

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

به عنوان مثال ، اگر بخواهیم رنگ دکمه را تغییر دهیم چه می کنیم؟ آیا ما باید تصاویر زیادی برای هر نوع رنگ دکمه ایجاد کنیم؟ اگر نسبت ابعاد دکمه را تغییر دهیم چه می شود؟ تصویر دیگر مناسب نخواهد بود.

انیمیشن glitchy سریع است. آنقدر سریع است که بعید به نظر می رسد گوشه بریده شده قابل توجه باشد. این داد و ستد برای مجموعه ای از سبک های انعطاف پذیر و قابل استفاده مجدد ارزشش را دارد.

بیایید با آن راه حل ادامه دهیم. ما می توانیم یک عنصر جدید برای اشکال اضافه کنیم. این به همان متن دکمه ما نیاز دارد و همچنین باید از صفحه خوان با آن مخفی شود aria-hidden:

<button class="cybr-btn">
  Glitch<span aria-hidden>_</span>
  <span aria-hidden class="cybr-btn__glitch">Glitch_</span>
  <span aria-hidden class="cybr-btn__tag">R25</span>
</button>

ما باید متن را در اینجا کپی کنیم ، و گزینه هایی داریم. این سایت از یک عنصر شبه برای تکثیر متن استفاده می کند. اما اگر این کار را انجام دهیم ، این به معنای متحرک سازی همزمان دو عنصر برای اثر است. با انتقال متن به عنصر glitch ، فقط باید یک عنصر را متحرک کنیم:

.cybr-btn__glitch {
  position: absolute;
  height: 100%;
  width: 100%;
  top: 0;
  left: 0;
  box-shadow: 0 0 0 4px var(--shadow-primary);
  text-shadow: 2px 2px var(--shadow-primary), -2px -2px var(--shadow-secondary);
}

استفاده از برخی سبک ها مانند text-shadow و یک box-shadow ما را به اینجا برسان

قلم را ببینید
دکمه های CSS Cyberpunk 2077: Glitch Body
توسط SitePoint (SitePoint)
بر CodePen.

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

.cybr-btn {
  --clip: polygon(0 0, 100% 0, 100% 100%, 8% 100%, 0 70%);
}
.cybr-btn:before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: var(--primary);
  clip-path: var(--clip);
  z-index: -1;
}

ما می توانیم حذف کنیم clip-path از دکمه آن کلیپ را در متغیری قرار دهید که بتوانیم از آن استفاده مجدد کنیم. ما باید اقدام کنیم z-index: -1 به عناصر شبه به طوری که متن هنوز نشان می دهد:

.cybr-btn {
  --border: 4px;
}

.cybr-btn__glitch {
  position: absolute;
  top: calc(var(--border) * -1);
  left: calc(var(--border) * -1);
  right: calc(var(--border) * -1);
  bottom: calc(var(--border) * -1);
  background: var(--shadow-primary);
  text-shadow: 2px 2px var(--shadow-primary), -2px -2px var(--shadow-secondary);
  clip-path: var(--clip);
}

.cybr-btn__glitch:before {
  content: '';
  position: absolute;
  top: calc(var(--border) * 1);
  right: calc(var(--border) * 1);
  bottom: calc(var(--border) * 1);
  left: calc(var(--border) * 1);
  clip-path: var(--clip);
  background: var(--primary);
  z-index: -1;
}

سپس می توانیم از کلیپس برای عنصر شبه عنصر glitch استفاده مجدد کنیم. ترفند درست سازی عنصر glitch این است که آن را کاملاً به گونه ای قرار دهید که انگار مرز است. سپس عنصر شبه را در بالای آن قرار دهید. استفاده از همان گیره برای هر دو عنصر ، مرز آبی شسته و رفته ای را که پس از گوشه قرار دارد ، به ما می دهد.

قلم را ببینید
دکمه های CSS Cyberpunk 2077: قطعی مجدد
توسط SitePoint (SitePoint)
بر CodePen.

چقدر خوب است؟ ما حتی می توانیم مسیر کلیپ را تنظیم کنیم تا این برش در حدود “R25” بدست آید. تنظیم clip-path و سبک های برچسب را مانند این حذف کنید:

.cybr-btn {
  --clip: polygon(0 0, 100% 0, 100% 100%, 95% 100%, 95% 90%, 85% 90%, 85% 100%, 8% 100%, 0 70%);
}

.cybr-btn__tag {
  position: absolute;
  padding: 1px 4px;
  letter-spacing: 1px;
  line-height: 1;
  bottom: -5%;
  right: 5%;
  color: hsl(0, 0%, 0%);
  font-size: var(--label-size);
}

قلم را ببینید
دکمه های CSS Cyberpunk 2077: برچسب را بردارید
توسط SitePoint (SitePoint)
بر CodePen.

و این جایی است که ما فرصت داریم کار جالب دیگری انجام دهیم. وقتی دکمه را بررسی کردم و تصویر پس زمینه را کشف کردم ، آن را پایین کشیدم. و آنچه که من یافتم این است که مرز با قرار دادن دو تصویر و ترجمه تصویر پایین امکان پذیر است. اکنون که ما استفاده می کنیم clip-path، ما نیز می توانیم همین کار را انجام دهیم.

دو تصویر انباشته

اگر ما از :before عنصر شبه برای رنگ آبی دکمه ما و :after برای رنگ قرمز ، سپس ترجمه کنید :before عنصر شبه با اندازه مرز ، این مرز را به ما می دهد. بدون اعمال a ، مرز را به ما می دهد border:

.cybr-btn:after,
.cybr-btn:before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  clip-path: var(--clip);
  z-index: -1;
}

.cybr-btn:before {
  background: var(--shadow-primary);
  transform: translate(var(--border), 0);
}

.cybr-btn:after {
  background: var(--primary);
}

اکنون سایه مربوط به برچسب و دکمه را داریم. و برچسب از رنگ زمینه در پشت آن استفاده خواهد کرد. سعی کنید تغییر دهید background-color برای body و خواهید دید!

قلم را ببینید
دکمه های CSS Cyberpunk 2077: حاشیه انباشته
توسط SitePoint (SitePoint)
بر CodePen.

متحرک سازی دکمه

تقریباً آنجا! قطع کن. ما اشکال داریم ما همه چیزهایی را که نیاز داریم ، داریم. تنها چیزی که باقی مانده متحرک سازی دکمه روشن است :hover.

چگونه آن اثر قطعی اتفاق می افتد؟ ترفند این است که فقط عنصر قطعی را نشان دهید :hover و بصورت پیش فرض یک انیمیشن روی آن اعمال شده است. فرض من در اینجا استفاده از بود transform و clip-path در مجموعه ای از فریم های کلیدی. و من حق داشتم! از کجا فهمیدم؟ من دکمه را بازرسی کردم و از “حالت فورس” Chrome برای تنظیم دکمه روی استفاده کردم :hover حالت.

مجبور کردن دولت در بازرس

سپس ، سبک ها را بررسی کنید و انیمیشن را پیدا کنید. روی نام پرونده کلیک کنید و این کار شما را به منبع می رساند.

کد منبع انیمیشن

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

@keyframes glitch-anim-1 {
    0% {
        opacity: 1;
        -webkit-transform: translateZ(0);
        transform: translateZ(0);
        -webkit-clip-path: polygon(0 2%,100% 2%,100% 5%,0 5%);
        clip-path: polygon(0 2%,100% 2%,100% 5%,0 5%)
    }

    2% {
        -webkit-clip-path: polygon(0 78%,100% 78%,100% 100%,0 100%);
        clip-path: polygon(0 78%,100% 78%,100% 100%,0 100%);
        -webkit-transform: translate(-5px);
        transform: translate(-5px)
    }

    6% {
        -webkit-clip-path: polygon(0 78%,100% 78%,100% 100%,0 100%);
        clip-path: polygon(0 78%,100% 78%,100% 100%,0 100%);
        -webkit-transform: translate(5px);
        transform: translate(5px)
    }

    8% {
        -webkit-clip-path: polygon(0 78%,100% 78%,100% 100%,0 100%);
        clip-path: polygon(0 78%,100% 78%,100% 100%,0 100%);
        -webkit-transform: translate(-5px);
        transform: translate(-5px)
    }

    9% {
        -webkit-clip-path: polygon(0 78%,100% 78%,100% 100%,0 100%);
        clip-path: polygon(0 78%,100% 78%,100% 100%,0 100%);
        -webkit-transform: translate(0);
        transform: translate(0)
    }

    10% {
        -webkit-clip-path: polygon(0 54%,100% 54%,100% 44%,0 44%);
        clip-path: polygon(0 54%,100% 54%,100% 44%,0 44%);
        -webkit-transform: translate3d(5px,0,0);
        transform: translate3d(5px,0,0)
    }

    13% {
        -webkit-clip-path: polygon(0 54%,100% 54%,100% 44%,0 44%);
        clip-path: polygon(0 54%,100% 54%,100% 44%,0 44%);
        -webkit-transform: translateZ(0);
        transform: translateZ(0)
    }

    13.1% {
        -webkit-clip-path: polygon(0 0,0 0,0 0,0 0);
        clip-path: polygon(0 0,0 0,0 0,0 0);
        -webkit-transform: translate3d(5px,0,0);
        transform: translate3d(5px,0,0)
    }

    15% {
        -webkit-clip-path: polygon(0 60%,100% 60%,100% 40%,0 40%);
        clip-path: polygon(0 60%,100% 60%,100% 40%,0 40%);
        -webkit-transform: translate3d(5px,0,0);
        transform: translate3d(5px,0,0)
    }

    20% {
        -webkit-clip-path: polygon(0 60%,100% 60%,100% 40%,0 40%);
        clip-path: polygon(0 60%,100% 60%,100% 40%,0 40%);
        -webkit-transform: translate3d(-5px,0,0);
        transform: translate3d(-5px,0,0)
    }

    20.1% {
        -webkit-clip-path: polygon(0 0,0 0,0 0,0 0);
        clip-path: polygon(0 0,0 0,0 0,0 0);
        -webkit-transform: translate3d(5px,0,0);
        transform: translate3d(5px,0,0)
    }

    25% {
        -webkit-clip-path: polygon(0 85%,100% 85%,100% 40%,0 40%);
        clip-path: polygon(0 85%,100% 85%,100% 40%,0 40%);
        -webkit-transform: translate3d(5px,0,0);
        transform: translate3d(5px,0,0)
    }

    30% {
        -webkit-clip-path: polygon(0 85%,100% 85%,100% 40%,0 40%);
        clip-path: polygon(0 85%,100% 85%,100% 40%,0 40%);
        -webkit-transform: translate3d(-5px,0,0);
        transform: translate3d(-5px,0,0)
    }

    30.1% {
        -webkit-clip-path: polygon(0 0,0 0,0 0,0 0);
        clip-path: polygon(0 0,0 0,0 0,0 0)
    }

    35% {
        -webkit-clip-path: polygon(0 63%,100% 63%,100% 80%,0 80%);
        clip-path: polygon(0 63%,100% 63%,100% 80%,0 80%);
        -webkit-transform: translate(-5px);
        transform: translate(-5px)
    }

    40% {
        -webkit-clip-path: polygon(0 63%,100% 63%,100% 80%,0 80%);
        clip-path: polygon(0 63%,100% 63%,100% 80%,0 80%);
        -webkit-transform: translate(5px);
        transform: translate(5px)
    }

    45% {
        -webkit-clip-path: polygon(0 63%,100% 63%,100% 80%,0 80%);
        clip-path: polygon(0 63%,100% 63%,100% 80%,0 80%);
        -webkit-transform: translate(-5px);
        transform: translate(-5px)
    }

    50% {
        -webkit-clip-path: polygon(0 63%,100% 63%,100% 80%,0 80%);
        clip-path: polygon(0 63%,100% 63%,100% 80%,0 80%);
        -webkit-transform: translate(0);
        transform: translate(0)
    }

    55% {
        -webkit-clip-path: polygon(0 10%,100% 10%,100% 0,0 0);
        clip-path: polygon(0 10%,100% 10%,100% 0,0 0);
        -webkit-transform: translate3d(5px,0,0);
        transform: translate3d(5px,0,0)
    }

    60% {
        -webkit-clip-path: polygon(0 10%,100% 10%,100% 0,0 0);
        clip-path: polygon(0 10%,100% 10%,100% 0,0 0);
        -webkit-transform: translateZ(0);
        transform: translateZ(0);
        opacity: 1
    }

    60.1% {
        -webkit-clip-path: polygon(0 0,0 0,0 0,0 0);
        clip-path: polygon(0 0,0 0,0 0,0 0);
        opacity: 1
    }

    to {
        -webkit-clip-path: polygon(0 0,0 0,0 0,0 0);
        clip-path: polygon(0 0,0 0,0 0,0 0);
        opacity: 1
    }
}

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

.cybr-btn {
  --shimmy-distance: 5;
  --clip-one: polygon(0 2%, 100% 2%, 100% 95%, 95% 95%, 95% 90%, 85% 90%, 85% 95%, 8% 95%, 0 70%);
  --clip-two: polygon(0 78%, 100% 78%, 100% 100%, 95% 100%, 95% 90%, 85% 90%, 85% 100%, 8% 100%, 0 78%);
  --clip-three: polygon(0 44%, 100% 44%, 100% 54%, 95% 54%, 95% 54%, 85% 54%, 85% 54%, 8% 54%, 0 54%);
  --clip-four: polygon(0 0, 100% 0, 100% 0, 95% 0, 95% 0, 85% 0, 85% 0, 8% 0, 0 0);
  --clip-five: polygon(0 0, 100% 0, 100% 0, 95% 0, 95% 0, 85% 0, 85% 0, 8% 0, 0 0);
  --clip-six: polygon(0 40%, 100% 40%, 100% 85%, 95% 85%, 95% 85%, 85% 85%, 85% 85%, 8% 85%, 0 70%);
  --clip-seven: polygon(0 63%, 100% 63%, 100% 80%, 95% 80%, 95% 80%, 85% 80%, 85% 80%, 8% 80%, 0 70%);
}

@keyframes glitch {
  0% {
    clip-path: var(--clip-one);
  }
  2%, 8% {
    clip-path: var(--clip-two);
    transform: translate(calc(var(--shimmy-distance) * -1%), 0);
  }
  6% {
    clip-path: var(--clip-two);
    transform: translate(calc(var(--shimmy-distance) * 1%), 0);
  }
  9% {
    clip-path: var(--clip-two);
    transform: translate(0, 0);
  }
  10% {
    clip-path: var(--clip-three);
    transform: translate(calc(var(--shimmy-distance) * 1%), 0);
  }
  13% {
    clip-path: var(--clip-three);
    transform: translate(0, 0);
  }
  14%, 21% {
    clip-path: var(--clip-four);
    transform: translate(calc(var(--shimmy-distance) * 1%), 0);
  }
  25% {
    clip-path: var(--clip-five);
    transform: translate(calc(var(--shimmy-distance) * 1%), 0);
  }
  30% {
    clip-path: var(--clip-five);
    transform: translate(calc(var(--shimmy-distance) * -1%), 0);
  }
  35%, 45% {
    clip-path: var(--clip-six);
    transform: translate(calc(var(--shimmy-distance) * -1%));
  }
  40% {
    clip-path: var(--clip-six);
    transform: translate(calc(var(--shimmy-distance) * 1%));
  }
  50% {
    clip-path: var(--clip-six);
    transform: translate(0, 0);
  }
  55% {
    clip-path: var(--clip-seven);
    transform: translate(calc(var(--shimmy-distance) * 1%), 0);
  }
  60% {
    clip-path: var(--clip-seven);
    transform: translate(0, 0);
  }
  31%, 61%, 100% {
    clip-path: var(--clip-four);
  }
}

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

در اینجا یک نسخه آزمایشی کند شده برای نشان دادن نحوه کار انیمیشن ارائه شده است:

قلم را ببینید
دکمه های CSS Cyberpunk 2077: انیمیشن کم سرعت
توسط SitePoint (SitePoint)
بر CodePen.

و همچنین یک نسخه ی نمایشی تهیه کرده ام که وضعیت های مختلف کلیپ را نشان می دهد:

قلم را ببینید
دکمه های CSS Cyberpunk 2077: حالات برش دهنده
توسط SitePoint (SitePoint)
بر CodePen.

این امر باعث می شود که ما بتوانیم حالت های مختلف انیمیشن را حفظ و تغییر دهیم.

اتصال با شناور

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

.cybr-btn__glitch {
  display: none;
}
.cybr-btn:hover .cybr-btn__glitch {
  display: block;
}

و این نتیجه ای است که به دنبال آن بودیم:

قلم را ببینید
دکمه CSS Cyberpunk 2077: اولین پاس
توسط SitePoint (SitePoint)
بر CodePen.

بسته شدن

و اینگونه شما می توانید دکمه های Cyberpunk 2077 را فقط با CSS از نو بسازید!

به یاد دارید که چگونه از متغیرها برای رنگ ها استفاده کردیم؟ این یک دلیل داشت. با ترکیب HSL با متغیرها ، ما نه تنها می توانیم به راحتی انواع رنگ را اضافه کنیم ، بلکه می توانیم یک نوع را نیز اضافه کنیم :active تغییر رنگ نیز.

در اینجا نسخه آزمایشی نهایی است.

قلم را ببینید
دکمه های Pure CSS Cyberpunk 2077 😎
توسط SitePoint (SitePoint)
بر CodePen.

مثل همیشه ، هر گونه سوال یا پیشنهادی ، دریغ نکنید من را در توییتر پینگ کنید – @ jh3yy.