طراحی تایمر معکوس با HTML ،CSS و JavaScript – به زبان ساده


آیا تاکنون لازم شده است یک تایمر شمارش معکوس در یک پروژه قرار دهید؟ در چنین مواردی معمولاً به دنبال یک افزونه میگردیم، اما پیادهسازی چنین تایمری کاری سرراست محسوب میشود و صرفاً به آشنایی با HTML ،CSS و JavaScript نیاز دارد. در این مقاله با مراحل طراحی تایمر معکوس با HTML ،CSS و JavaScript آشنا خواهیم شد. در نهایت چیزی مانند زیر به دست میآوریم:
کارهایی که تایمر ما انجام میدهد و در این نوشته بررسی خواهیم کرد، به شرح زیر هستند:
- نمایش زمان باقیمانده اولیه
- تبدیل مقدار زمان به قالب MM:SS.
- محاسبه تفاضل بین زمان باقیمانده اولیه و مقدار زمان سپریشده.
- تغییر دادن رنگ در زمان نزدیک شدن زمان باقیمانده به صفر.
- نمایش پیشروی زمان باقیمانده به صورت یک حلقه انیمیت شده.
اینها مواردی هستند که باید پیادهسازی کنیم. در بخش بعدی کار را آغاز میکنیم.
گام 1: آغاز کار با markup ابتدایی و استایلها
کار خود را با ایجاد یک قالب مقدماتی برای تایمر خود آغاز میکنیم. ابتدا یک svg میسازیم و یک عنصر circle درون آن اضافه میکنیم تا یک حلقه تایمر رسم کنیم که زمان سپریشده را نشان میدهد و یک span برای نمایش مقدار زمان باقیمانده نمایش دهیم. توجه کنید که مشغول نوشتن HTML در جاوا اسکریپت هستیم که با هدفگیری عنصر app# درون DOM تزریق میشود.
البته میتوانیم مقدار زیادی از آن را به یک فایل HTML اضافه کنیم. این موضوع به ترجیح شخصی شما بستگی دارد.
اکنون که نوعی markup داریم تا با آن کار کنیم، اقدام به استایلبندی آن میکنیم تا نمای بصری خوبی برای آغاز کار داشته باشیم. به طور خاص قصد انجام کارهای زیر را داریم:
- تعیین اندازه تایمر.
- حذف fill و stroke از عنصر پوششی دایره برای به دست آوردن یک شکل که زمان سپریشده از خلال آن نمایش مییابد.
- تعیین عرض و رنگ حلقه.
با انجام کارهای فوق، قالب مقدماتی ما شکلی مانند زیر پیدا میکند:
گام 2: تعیین برچسب زمان
همچنان که احتمالاً متوجه شدهاید، قالب ما شامل یک <SPAN> خالی است که باید زمان باقیمانده را داخل آن نشان دهیم. این مکان را با یک مقدار مناسب پر میکنیم. پیشتر گفتیم که زمان در قالب MM:SS نمایش مییابد. به این منظور یک متد به نام formatTimeLeft ایجاد میکنیم:
سپس از متد خود در قالب استفاده میکنیم:
برای نمایش مقدار درون حلقه باید استایلهای خود را کمی بهروزرسانی کنیم:
اکنون آماده هستیم تا با مقدار timeLeft کار کنیم، اما هنوز آن را ایجاد نکردهایم. ابتدا آن را ایجاد میکنیم و مقدار ابتدایی را روی محدودیت زمانی خود تنظیم میکنیم.
اینک یک گام جلوتر هستیم:
اکنون تایمری داریم که در 20 ثانیه آغاز به کار میکند، اما هنوز عمل شمارش را انجام نمیدهد. در ادامه آن را کامل میکنیم تا ثانیه صفر را بشمارد.
گام 3: شمارش معکوس
اینک باید فکر کنیم برای شمارش معکوس زمان به چه چیز نیاز داریم. هم اینک یک مقدار timeLimit داریم که زمان ابتدایی ما را نشان میدهد و یک مقدار timePassed داریم که میزان زمان سپریشده از زمان آغاز شمارش معکوس را نشان میدهد. اینجا کاری که باید بکنیم این است که مقدار timePassed را یک واحد در هر ثانیه افزایش دهیم و مقدار timeLeft را بر اساس مقدار timePassed جدید محاسبه کند. این هدف با استفاده از setInterval قابل حصول است.
ابتدا متدی پیادهسازی میکنیم که startTimer را فراخوانی کند تا کارهای زیر را انجام دهد:
- تعیین بازه شمارنده.
- افزایش مقدار timePassed در هر ثانیه.
- محاسبه مجدد مقدار جدید timeLeft.
- بهروزرسانی مقدار برچسب در قالب.
همچنین باید ارجاعی به این شیء بازه نگهداری کنیم تا در زمان نیاز آن را پاک کنیم. به همین جهت است که متغیر timerInterval را ایجاد خواهیم کرد.
متدی داریم که با تایمر آغاز میشود، اما آن را هیچ کجا فراخوانی نمیکنیم. اینک تایمر را بیدرنگ پس از بارگذاری آغاز میکنیم.
اینک تایمر ما شروع به شمارش معکوس زمان میکنیم. با این که این وضعیت مناسبی است، اما در صورتی که میتوانستیم به حلقه پیرامون برچسب زمانی خود رنگ بدهیم و در مقادیر زمانی مختلف رنگ آن را عوض کنیم، بسیار زیباتر میشد.
گام 4: پوشاندن تایمر با حلقه دیگر
برای بصری سازی زمان سپریشده، باید یک لایه دوم به حلقه خود اضافه کنیم که انیمیشن را مدیریت کند. کاری که انجام میدهیم اساساً پشتهسازی یک حلقه سبز رنگ جدید روی حلقه خاکستری اصلی است به طوری که حلقه سبز انیمیت شود و بدین ترتیب حلقه خاکستری را با گذشت زمان آشکار سازد و مانند یک نوار پیشروی عمل کند.
ابتدا یک عنصر path به عنصر SVG خود اضافه میکنیم.
سپس یک رنگ اولیه برای مسیر زمانی باقیمانده تعیین میکنیم:
در نهایت چند استایل اضافه میکنیم تا مسیر مدور مانند حلقه خاکستری اصلی به نظر بیاید. نکته مهم این است که مطمئن شویم stroke-width به همان اندازه حلقه اصلی است و این که مدت زمان transition روی ثانیهای تعیین شده است که به طرز همواری انیمیت میشود و متناظر با زمان باقیمانده روی برچسب زمانی است.
بدین ترتیب یک استروک در خروجی ارائه میکنیم که حلقه تایمر را آن طور که باید، پوشش میدهد، اما هنوز انیمیت نمیشود تا حلقه تایمر را که گذشت زمان را نشان میدهد آشکار سازد.
برای انیمیت کردن خط طول زمان باقیمانده باید از مشخصه stroke-dasharray استفاده کنیم. روش کار در این آدرس (+) با تفصیل بیشتری توضیح داده است و مثالهایی از آن با استفاده از ترفندهای CSS توضیح داده شده است.
گام 5: انیمیت حلقه پیشروی
در این بخش به بررسی شیوه نمایش حلقه با مقادیر مختلف stroke-dasharray میپردازیم.
در تصویر فوق میبینیم که مقدار stroke-dasharray در عمل حلقه زمان باقیمانده را به بخشهای با طول برابر تقسیم میکند که طول آن برابر با مقدار زمان باقیمانده است. این اتفاق زمانی رخ میدهد که مقدار stroke-dasharray را روی یک عدد با رقم منفرد تنظیم میکنیم.
نام dasharray نشان میدهد که میتوانیم مقادیر چندگانه را به صورت یک آرایه تعیین کنیم. در ادامه به بررسی طرز رفتار آن در صورتی که دو عدد به جای یک عدد داشته باشیم میپردازیم. در این حالت آن مقادیر برابر با 10 و 30 هستند.
به این ترتیب طول بخش نخست (زمان باقیمانده) برابر با 10 و طول بخش دوم یعنی (زمان سپریشده) برابر با 30 تنظیم میشود. میتوانیم از آن در تایمر خود با کمی تغییر استفاده کنیم. چیزی که نیاز داریم ابتدا یک حلقه است که طول کامل دایره را بپوشاند، یعنی زمان باقیمانده برابر با طول حلقه ما باشد.
این طول چه قدر است؟ روش محاسبه این طول با استفاده از فرمول ریاضیاتی زیر است:
Length = 2πr = 2 * π * 45 = 282,6
این همان مقداری است که میخواهیم در زمان نمایش اولیه حلقه مورد استفاده قرار دهیم؛ طرز کار آن به صورت زیر است:
اینک مقدار اولیه در آرایه برابر با زمان باقیمانده ما است و مقدار دوم نیز میزان زمان سپریشده را نمایش میدهد. اینک باید مقدار نخست را دستکاری کنیم. در ادامه آنچه را که در زمان تغییر مقدار نخست میتوان انتظار داشت میبینیم:
دو متد ایجاد میکنیم که یکی مسئول محاسبه مقدار باقیمانده زمان و دیگری مسئول محاسبه مقدار stroke-dasharray و بهروزرسانی عنصر <path> است که زمان باقیمانده ما را نشان میدهد:
همچنین باید مسیر خود را در هر ثانیه که سپری میشود بهروزرسانی کنیم. این بدان معنی است که باید متد جدیداً ایجاد شده setCircleDasharray را درون timerInterval فراخوانی کنیم.
اکنون میبینیم که در حال حرکت است:
کد ما اکنون کار میکند، اما اگر به دقت به خصوص به آخر نگاه کنید به نظر میرسد که انیمیشن ما یک ثانیه تأخیر دارد. زمانی که به ثانیه 0 میرسد، بخش کوچکی از حلقه همچنان نمایان است.
دلیل این امر ناشی از این نکته است که مدت زمان انیمیت روی یک ثانیه تنظیم شده است. در وضعیتی که مقدار باقیمانده زمان روی صفر تنظیم شود، همچنان به یک ثانیه زمان نیاز دارد تا در عمل انیمیشن حلقه را به پایان ببرد. با کاهش طول حلقه به تدریج در طی شمارش معکوس میتوانیم این مشکل را نیز رفع کنیم. این کار را در متد calculateTimeFraction انجام میدهیم:
اینک نتیجه کار به صورت زیر است:
یک نکته دیگر نیز وجود دارد که باید مورد اشاره قرار دهیم. پیشتر گفتیم که خواستار تغییر رنگ نشانگر پیشروی در حالتی هستیم که زمان باقیمانده به نقطه مشخصی برسد. این نوع کارها موجب میشود که کاربر بداند که زمانش تقریباً رو به اتمام است.
گام 6: تغییر رنگ نوار پیشروی در زمان خاص
ابتدا باید دو آستانه اضافه کنیم که نشان میدهد رنگ در چه زمانی باید تغییر یابد و یکی نشانگر حالت هشدار و دیگری حالت اخطار است و برای هر دو حالت نیز رنگهایی تعیین میکنیم. کار خود را با رنگ سبز آغاز میکنیم و سپس رنگ را به نارنجی تغییر میدهیم تا نشانگر حالت هشدار باشد. در ادامه از رنگ قرمز برای نمایش حالت اخطار در حالتی که زمان تقریباً رو به اتمام است استفاده میکنیم.
اکنون متدی ایجاد میکنیم که مسئول بررسی این نکته است که آیا از آستانه مورد نظر عبور کردهایم یا نه و رنگ نوار پیشروی را در زمانی که این اتفاق بیفتد تغییر میدهد.
بنابراین ابتدا کلاس CSS را در زمانی که تایمر به نقطه خاصی برسد حذف میکنیم و کلاس دیگری به جای آن اضافه میکنیم. قصد داریم این کلاسها را تعریف کنیم.
اکنون چیزی را که میخواستیم به دست آوردیم. دموی نهایی این پروژه به صورت زیر است:
کدهای نهایی این پروژه را از این لینک (+) دانلود کنید. اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای طراحی سایت با HTML و CSS
- آموزش جاوا اسکریپت (JavaScript)
- مجموعه آموزشهای JavaScript (جاوا اسکریپت)
- جاوا اسکریپت چیست؟ — به زبان ساده
- ساخت تایمر شمارش معکوس با SwiftUI — از صفر تا صد
==
سلام
بسیار کاربردی و خوب .
ممنون از نوسنده و سایت خوب شما.
سلام وقتتون بخیر من هرچقدر سعی کردم فایل css و java script رو با html مخلوط کنم موفق نشدم میشه راهنماییم کنید؟
با سلام و احترام؛
صمیمانه از همراهی شما با مجله فرادرس و ارائه بازخورد سپاسگزاریم.
پیشنهاد میشود پیش از اجرای کدهای این مقاله، ابتدا مقاله زیر را مطالعه کنید تا با نحوه اجرا و پیادهسازی کدها و پروژههای جاوا اسکریپت بیشتر آشنا شوید:
همچنین میتوانید از دورههای آموزشی زیر برای یادگیری بیشتر استفاده کنید:
برای شما آرزوی سلامتی و موفقیت داریم.
با سلام!
من این کد روی در کروم اجرا کردم ولی درست اجرا نمیشه و فقط صفحه صفید میاد!
باسلام!
شما باید کد سی اس اس و جاوا اسکیریپ را با html مخلوط کنید.
سلام خسته نباشید استاد ,من میخواستم یک تایمر شمارش معکوس داخل اسلایدر یا حلقه داشته باشم اما کد جاوااسکریپتی که شما اموزش دادید یا از سایت های دیگه که برمیدارم و جایگزاری میکنم فقط در یکی از اسلایدرها یا حلقه ها می ایند میشه کدی بدید که در همه مطالب اسلایدرها یاهمون حلقه هابیایدمن خیلی به کمک شما احتیاج دارم لطفا کمکم کنید
سلام لطفا کد هایه کامل ثانیه شماررو هم برای دانلود داخل سایت قرار بدید
با سلام.
کدهای کامل پروژه به صورت یک فایل فشرده در لینک انتهای متن نیز ارائه شد.
با تشکر از توجه شما.
با سلام
کدهای این ا
سلام
با تشکر از آموزش خوبتون .
کد های نهایی رو هم میزارید؟