وضعیت هک CSS انیمیشن و زمان پخش هوش داده PlatoBlockchain. جستجوی عمودی Ai.

وضعیت انیمیشن CSS و زمان پخش هک

Wolfenstein فقط CSS پروژه کوچکی است که چند هفته پیش ساختم. این یک آزمایش با تبدیل‌ها و انیمیشن‌های سه بعدی CSS بود.

با الهام از دمو FPS و دیگری قلم کد Wolfenstein، تصمیم گرفتم نسخه خودم را بسازم. این بازی بر اساس اپیزود 1 – طبقه 9 از بازی اصلی Wolfenstein 3D ساخته شده است.

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

در اینجا یک ویدیوی پخش است:

[محتوای جاسازی شده]

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

:checked ~ div { animation-name: spin; }

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

با این حال، حل دو مشکل به ویژه دشوار بود:

  • هر زمان که بازیکن بر روی دشمن کلیک کرد، انیمیشن "شلیک سلاح" را پخش کنید.
  • وقتی رئیس تندرو آخرین ضربه را خورد، یک حرکت آهسته دراماتیک وارد کنید.

در سطح فنی، این به این معنی بود:

  • با علامت زدن کادر بعدی یک انیمیشن را دوباره پخش کنید.
  • وقتی یک چک باکس علامت زده می شود، انیمیشن را کم کنید.

در واقع هیچ کدام به درستی در پروژه من حل نشد! من یا در نهایت از راه‌حل‌ها استفاده کردم یا فقط منصرف شدم.

از سوی دیگر، پس از مدتی حفاری، در نهایت کلید هر دو مشکل را پیدا کردم: تغییر ویژگی‌های اجرای انیمیشن‌های CSS. در این مقاله به بررسی بیشتر این موضوع خواهیم پرداخت:

  • نمونه های تعاملی زیاد
  • تشریح ها: هر نمونه چگونه کار می کند (یا کار نمی کند)؟
  • پشت صحنه: مرورگرها چگونه حالت های انیمیشن را مدیریت می کنند؟

اجازه دهید من "آجرهای من را پرتاب کن".

مشکل 1: پخش مجدد انیمیشن

مثال اول: "فقط یک چک باکس دیگر"

اولین شهود من "فقط یک چک باکس دیگر اضافه کنید" بود که کار نمی کند:

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

در اینجا نحوه کار (یا "کار نمی کند"):

  1. La animation-name of <div> is none به صورت پیش فرض.
  2. کاربر روی یک چک باکس کلیک می کند، animation-name شود spin، و انیمیشن از ابتدا شروع می شود.
  3. پس از مدتی کاربر روی چک باکس دیگر کلیک می کند. یک قانون جدید CSS اعمال می شود، اما animation-name is هنوز spin، یعنی هیچ انیمیشنی اضافه یا حذف نمی شود. انیمیشن به سادگی به پخش خود ادامه می دهد انگار هیچ اتفاقی نیفتاده است.

مثال دوم: شبیه سازی انیمیشن

یک روش کاری شبیه سازی انیمیشن است:

#spin1:checked ~ div { animation-name: spin1; }
#spin2:checked ~ div { animation-name: spin2; }

در اینجا چگونه کار می کند:

  1. animation-name is none در ابتدا
  2. کاربر روی "Spin!" کلیک می کند. animation-name شود spin1. انیمیشن spin1 از ابتدا شروع شده است زیرا به تازگی اضافه شده است.
  3. کاربر روی "دوباره چرخش!" کلیک می کند. animation-name شود spin2. انیمیشن spin2 از ابتدا شروع شده است زیرا به تازگی اضافه شده است.

توجه داشته باشید که در مرحله 3، spin1 به دلیل نظم قوانین CSS حذف شده است. اگر "دوباره بچرخ!" ابتدا بررسی می شود.

مثال سوم: "ضمیمه کردن همان انیمیشن"

یکی دیگر از رویکردهای کاری، "ضمیمه کردن همان انیمیشن" است:

#spin1:checked ~ div { animation-name: spin; }
#spin2:checked ~ div { animation-name: spin, spin; }

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

#spin1:checked ~ div { animation-name: spin1; }
#spin2:checked ~ div { animation-name: spin2, spin1; }

توجه داشته باشید که وقتی "دوباره بچرخ!" علامت زده می شود، انیمیشن در حال اجرا قدیمی تبدیل به دومین انیمیشن در لیست جدید می شود که می تواند غیر قابل درک باشد. یک پیامد مستقیم این است: ترفند کار نخواهد کرد اگر animation-fill-mode is forwards. در اینجا یک نسخه نمایشی است:

اگر تعجب می کنید که چرا این مورد است، در اینجا چند سرنخ وجود دارد:

  • animation-fill-mode is none به طور پیش فرض، به این معنی است که "انیمیشن در صورت پخش نشدن هیچ تاثیری ندارد".
  • animation-fill-mode: forwards; به این معنی است که «پس از اتمام پخش انیمیشن، باید برای همیشه در آخرین فریم کلیدی باقی بماند».
  • spin1تصمیم همیشه نادیده گرفته می شود spin2به خاطر spin1 بعداً در لیست ظاهر می شود.
  • فرض کنید کاربر روی «Spin!» کلیک می‌کند، منتظر چرخش کامل است، سپس روی «دوباره چرخش» کلیک می‌کند. در این لحظه. spin1 قبلاً تمام شده است و spin2 تازه شروع می شود

بحث

قانون سرانگشتی: شما نمی توانید یک انیمیشن CSS موجود را "ریستارت" کنید. در عوض، می‌خواهید یک انیمیشن جدید اضافه و پخش کنید. این ممکن است توسط مشخصات W3C:

هنگامی که یک انیمیشن شروع شد، ادامه می یابد تا زمانی که به پایان برسد یا نام انیمیشن حذف شود.

اکنون با مقایسه دو مثال آخر، فکر می‌کنم در عمل، «انیمشن‌های شبیه‌سازی» اغلب بهتر عمل می‌کنند، به خصوص زمانی که پیش‌پردازنده CSS در دسترس باشد.

مشکل 2: حرکت آهسته

ممکن است کسی فکر کند که کند کردن یک انیمیشن فقط یک موضوع طولانی تر است animation-duration:

div { animation-duration: 0.5s; }
#slowmo:checked ~ div { animation-duration: 1.5s; }

در واقع، این کار می کند:

... یا این کار را می کند؟

با چند ترفند، بهتر است مشکل را ببینید.

بله، انیمیشن کند شده است. و نه، ظاهر خوبی ندارد. سگ (تقریباً) همیشه وقتی چک باکس را تغییر می‌دهید «پرش» می‌کند. علاوه بر این، به نظر می رسد که سگ به جای موقعیت اولیه، به یک موقعیت تصادفی می پرد. چطور؟

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

هر دو عنصر سایه انیمیشن های مشابهی را اجرا می کنند animation-duration. و تحت تأثیر چک باکس قرار نمی گیرند.

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

نقل قول مشخصات W3C:

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

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

تلاشی دیگر

یک ایده این است که انیمیشن فعلی را مکث کنید، سپس یک انیمیشن کندتر اضافه کنید که از آنجا شروع به کار کند:

div {
  animation-name: spin1;
  animation-duration: 2s;
}

#slowmo:checked ~ div {
  animation-name: spin1, spin2;
  animation-duration: 2s, 5s;
  animation-play-state: paused, running;
}

بنابراین کار می کند:

... یا این کار را می کند؟

با کلیک بر روی "Slowmo!" سرعت آن کاهش می یابد. اما اگر منتظر یک دایره کامل باشید، یک "پرش" خواهید دید. در واقع، زمانی که "Slowmo!" روی آن کلیک می شود.

دلیلش هم اینه که ما نداریم from فریم کلیدی تعریف شده - و ما نباید. هنگامی که کاربر روی "Slowmo!" کلیک می کند، spin1 در برخی موقعیت ها مکث می شود و spin2 دقیقا از همان موقعیت شروع می شود. ما به سادگی نمی توانیم آن موقعیت را از قبل پیش بینی کنیم... یا می توانیم؟

یک راه حل کاری

ما میتوانیم! با استفاده از یک ویژگی سفارشی، می‌توانیم زاویه را در انیمیشن اول ثبت کنیم، سپس آن را به انیمیشن دوم منتقل کنیم:

div {
  transform: rotate(var(--angle1));
  animation-name: spin1;
  animation-duration: 2s;
}

#slowmo:checked ~ div {
  transform: rotate(var(--angle2));
  animation-name: spin1, spin2;
  animation-duration: 2s, 5s;
  animation-play-state: paused, running;
}

@keyframes spin1 {
  to {
    --angle1: 360deg;
  }
}

@keyframes spin2 {
  from {
    --angle2: var(--angle1);
  }
  to {
    --angle2: calc(var(--angle1) + 360deg);
  }
}

توجه داشته باشید: @property در این مثال استفاده شده است که توسط همه مرورگرها پشتیبانی نمی شود.

راه حل "کامل".

یک هشدار به راه حل قبلی وجود دارد: "خروج از slowmo" به خوبی کار نمی کند.

در اینجا راه حل بهتری وجود دارد:

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

این راه حل مانند "تغییر" "دنده" عمل می کند:

  • چرخ دنده ها: دو تا هستند <div>س یکی پدر و مادر دیگری است. هر دو دارای spin انیمیشن اما با متفاوت animation-duration. حالت نهایی عنصر انباشته شدن هر دو انیمیشن است.
  • جابجایی: در ابتدا فقط یکی <div> انیمیشن خود را در حال اجرا دارد. دیگری مکث می کند. هنگامی که چک باکس تغییر می کند، هر دو انیمیشن حالت خود را عوض می کنند.

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

یک راه حل عملی (با JS)

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

یک توضیح سریع:

  • یک ویژگی سفارشی برای ردیابی پیشرفت انیمیشن استفاده می شود.
  • زمانی که چک باکس را تغییر دهید، انیمیشن «بازراه‌اندازی» می‌شود.
  • کد JS درست را محاسبه می کند animation-delay برای اطمینان از انتقال یکپارچه من توصیه می کنم این مقاله اگر با مقادیر منفی آشنا نیستید animation-delay.

شما می توانید این راه حل را به عنوان ترکیبی از "راه اندازی مجدد انیمیشن" و رویکرد "تغییر دنده" مشاهده کنید.

در اینجا مهم است که پیشرفت انیمیشن را به درستی پیگیری کنید. در صورتی که راه حل ها امکان پذیر است @property در دسترس نیست. به عنوان مثال، این نسخه استفاده می کند z-index برای پیگیری پیشرفت:

نکته جانبی: در ابتدا سعی کردم یک نسخه فقط CSS ایجاد کنم اما موفق نشدم. در حالی که 100٪ مطمئن نیستم، فکر می کنم به این دلیل است animation-delay is متحرک نیست.

در اینجا نسخه ای با حداقل جاوا اسکریپت وجود دارد. فقط "ورود آهسته" کار می کند.

لطفاً اگر موفق به ایجاد یک نسخه فقط CSS کار می‌شوید، به من اطلاع دهید!

Slow-mo Any Animation (با JS)

در نهایت، من می خواهم راه حلی را به اشتراک بگذارم که برای (تقریبا) هر انیمیشنی، حتی با چندین انیمیشن پیچیده کار می کند. @keyframes:

اساسا، شما باید یک ردیاب پیشرفت انیمیشن اضافه کنید، سپس با دقت محاسبه کنید animation-delay برای انیمیشن جدید با این حال، گاهی اوقات بدست آوردن مقادیر صحیح ممکن است مشکل باشد (اما ممکن است).

مثلا:

  • animation-timing-function نیست linear.
  • animation-direction نیست normal.
  • مقادیر متعدد در animation-name مختلف با animation-duration'شن animation-delay's

این روش نیز شرح داده شده است اینجا کلیک نمایید برای Web Animations API.

تشکر و قدردانی

من این مسیر را پس از مواجهه با پروژه های فقط CSS شروع کردم. برخی بودند آثار هنری ظریف، و برخی بودند ابزارهای پیچیده. موارد مورد علاقه من آنهایی هستند که شامل اشیاء سه بعدی هستند، به عنوان مثال، این توپ پرتاب و این مکعب بسته بندی.

در ابتدا نمی دانستم اینها چگونه ساخته می شوند. بعدها خواندم و چیزهای زیادی از آن یاد گرفتم این آموزش زیبا توسط آنا تودور.

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

نتیجه

در این مقاله رفتار انیمیشن های CSS را در زمانی که یک animate-* دارایی تغییر یافته است به خصوص ما راه حل هایی را برای "بازپخش یک انیمیشن" و "انیمیشن آهسته" کار کردیم.

امیدوارم این مقاله برای شما جالب باشد. لطفا بگو به چه می اندیشی!

تمبر زمان:

بیشتر از ترفندهای CSS