كيف تنشئ ساعة ذات عقارب باستخدام تحريكات CSS و JavaScript
تُعدّ عملية إنشاء ساعة ذات عقارب حقيقية تعمل بالزمن الحقيقي من المشاريع البرمجية التعليمية الممتازة التي تجمع بين تنسيق الواجهة (Front-End) باستخدام HTML وCSS، وبرمجة الزمن والتحريكات باستخدام JavaScript. هذه الساعة تعتبر نموذجاً بسيطاً لكن فعالاً لإظهار مفاهيم مثل التفاعل مع الوقت الحقيقي، تحويل القيم الزمنية إلى درجات دوران، وكذلك استخدام الحركات CSS للتصميم الديناميكي الجذاب.
في هذا المقال، سيتم تفصيل الخطوات الدقيقة لإنشاء ساعة ذات عقارب (العقرب الصغير للساعة، المتوسط للدقائق، والطويل للثواني)، مع شرح وافر لكل عنصر برمجي، وتقديم الشيفرة البرمجية المخصصة لكل جزء، بالإضافة إلى تحليلات هندسية لحسابات الحركة وتوزيع العقارب، وأفضل الممارسات في كتابة الكود لتفادي المشكلات الشائعة.
الهيكل العام للساعة باستخدام HTML
الخطوة الأولى تبدأ بإنشاء الهيكل العام باستخدام HTML. هذا الهيكل سيتكون من عناصر تُستخدم لتمثيل القرص والعقارب.
html<div class="clock">
<div class="hand hour-hand">div>
<div class="hand minute-hand">div>
<div class="hand second-hand">div>
div>
عنصر
div مع الأصناف المناسبة للتحكم بها لاحقًا عبر CSS وJavaScript.تنسيق الساعة وتحريكات العقارب باستخدام CSS
تقوم CSS بدور محوري في تنسيق الساعة، من حيث الألوان، الأبعاد، تموضع المركز، وتحريكات العقارب حول مركز الساعة.
إعداد شكل الساعة
css.clock {
width: 300px;
height: 300px;
border: 10px solid #333;
border-radius: 50%;
position: relative;
padding: 2rem;
margin: 50px auto;
background: radial-gradient(circle, #fff 80%, #ccc);
box-shadow: 0 0 15px rgba(0,0,0,0.2);
}
تقوم هذه القواعد بإعداد ساعة دائرية، متوسطة الحجم، ذات حواف ناعمة، وتطبيق تدرج لوني لطيف في الخلفية مع ظل محيطي يعطي إحساساً ثلاثي الأبعاد.
تنسيق العقارب
css.hand {
width: 50%;
height: 6px;
background: #000;
position: absolute;
top: 50%;
left: 50%;
transform-origin: 100%;
transform: rotate(90deg);
transition: all 0.05s;
transition-timing-function: cubic-bezier(0.1, 2.7, 0.58, 1);
}
.hour-hand {
height: 8px;
background: #333;
width: 35%;
}
.minute-hand {
height: 6px;
background: #555;
width: 45%;
}
.second-hand {
height: 2px;
background: red;
width: 50%;
}
لكل عقرب لون مختلف وطول مختلف، مما يعزز من فهم المستخدم للتمييز بين العقارب الثلاثة. transform-origin يجعل نقطة الدوران تقع في نهاية العنصر، مما يسمح له بالدوران حول نقطة المركز.
ربط الساعة بالزمن الحقيقي باستخدام JavaScript
الآن ننتقل إلى قلب الساعة: جافا سكريبت. سيتم استخدام كائن Date لاستخلاص الوقت الفعلي، وتحويل القيم الزمنية إلى درجات دوران، ثم تطبيقها على العقارب.
javascriptconst hourHand = document.querySelector('.hour-hand');
const minuteHand = document.querySelector('.minute-hand');
const secondHand = document.querySelector('.second-hand');
function updateClock() {
const now = new Date();
const seconds = now.getSeconds();
const secondsDegrees = ((seconds / 60) * 360) + 90;
secondHand.style.transform = `rotate(${secondsDegrees}deg)`;
const minutes = now.getMinutes();
const minutesDegrees = ((minutes / 60) * 360) + ((seconds / 60) * 6) + 90;
minuteHand.style.transform = `rotate(${minutesDegrees}deg)`;
const hours = now.getHours();
const hoursDegrees = ((hours % 12) / 12 * 360) + ((minutes / 60) * 30) + 90;
hourHand.style.transform = `rotate(${hoursDegrees}deg)`;
}
setInterval(updateClock, 1000);
updateClock();
تحليل الكود
-
يتم إضافة 90 درجة لتعويض التدوير الابتدائي للعقارب (لأن العقرب موجه بالافتراض إلى اليمين).
-
كل ثانية تعني 6 درجات (360/60).
-
كل دقيقة تعني 6 درجات أيضًا، لكن نحسب تأثير الثواني عليها لزيادة الدقة.
-
كل ساعة تعني 30 درجة، ويُضاف إليها تأثير الدقائق للحصول على حركة سلسة لعقرب الساعات.
-
يتم تحديث العقارب كل ثانية باستخدام
setInterval.
معالجة مشاكل الدوران عند الدقيقة أو الساعة الكاملة
من التحديات التي تواجه المصممين في تحريكات CSS عند استخدام transition هو وجود قفزة غير طبيعية للعقرب عند وصوله إلى نهاية الدورة (من 360° إلى 0°).
الحل المقترح
إضافة شرط للتأكد من أن العقرب لن ينتقل بشكل خاطف عند الانتقال من زاوية 360 إلى 0. مثال على ذلك:
javascriptif (secondsDegrees === 90) {
secondHand.style.transition = 'none';
} else {
secondHand.style.transition = 'all 0.05s';
}
هذا الشرط يعطل التحريك عندما يكون العقرب في وضعية بداية الدورة، وبالتالي يمنع القفز الغريب عند اكتمال الدورة.
تحسين التصميم بإضافة علامات الساعات
لجعل الساعة أكثر واقعية، يمكن إضافة علامات الساعات الـ12:
html<div class="clock-face">
<div class="number number1">1div>
<div class="number number2">2div>
...
<div class="number number12">12div>
div>
ثم باستخدام CSS يتم ترتيب هذه العلامات حول دائرة الساعة بدقة، مثلاً:
css.number {
position: absolute;
font-size: 1.2rem;
font-weight: bold;
transform: translate(-50%, -50%);
}
.number1 { top: 15%; left: 75%; }
.number2 { top: 25%; left: 85%; }
/* يتم تكرار القواعد حتى number12 */
توزيع الأرقام يدوياً قد يكون دقيقًا ومرهقًا، ولكن يمكن تحسين ذلك رياضيًا باستخدام JavaScript لحساب مواضعها بالدوال المثلثية مثل Math.sin وMath.cos.
جدول توضيحي لزوايا العقارب
فيما يلي جدول يساعد على فهم آلية تحويل الزمن إلى زوايا دورانية:
| الوقت | زاوية العقرب الثواني | زاوية العقرب الدقائق | زاوية العقرب الساعات |
|---|---|---|---|
| 12:00:00 | 90° | 90° | 90° |
| 3:15:00 | 90° | 180° | 97.5° |
| 6:30:30 | 90° | 273° | 195° |
| 9:45:15 | 180° | 360° | 292.5° |
هذه الزوايا تعتمد على إضافة 90 درجة لتصحيح التحريك، كما تم ذكره سابقاً.
تحسينات إضافية على الساعة
1. إضافة مركز للعقارب
css.clock::after {
content: '';
width: 12px;
height: 12px;
background: black;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
z-index: 10;
}
2. إضافة صوت نبضي (اختياري)
باستخدام Web Audio API يمكن إضافة صوت “تك” عند كل ثانية، لإضفاء واقعية إضافية.
تنظيم الملفات والمجلدات
ينصح بإنشاء مشروع منظم على النحو التالي:
luaclock-project/
│
├── index.html
├── style.css
└── script.js
بهذه الطريقة يكون من السهل صيانة المشروع، وربطه مع محرر أكواد مثل VSCode أو استضافته على GitHub Pages.
أداء وتحسين تجربة المستخدم
لتحقيق أداء أفضل:
-
تجنب استخدام CSS Animations للعقارب، واستخدم JavaScript لأنه يمنحك تحكمًا مباشرًا.
-
احرص على استخدام
requestAnimationFrameفي المشاريع المعقدة بدلاً منsetIntervalلأنه يقدم أداءً أعلى في الحركات الرسومية. -
احرص على تقليل إعادة رسم العناصر على DOM لتقليل استهلاك الذاكرة.
الخلاصة التقنية
إن بناء ساعة بعقارب متحركة باستخدام HTML وCSS وJavaScript يُعد تجربة غنية في مفاهيم التحريك والتحكم بالوقت، ويمثل مشروعاً رائعاً للهواة والمطورين على حد سواء. هذه الساعة يمكن أن تتحول إلى عنصر أساسي في واجهات المستخدم للمواقع الزمنية أو تلك التي تتطلب عرض الوقت بشكل أنيق. كما يتيح المشروع فرصاً لتوسيع نطاق العمل بدمج مكتبات رسوميات أكثر تعقيداً مثل SVG أو Canvas، أو حتى إنشاء ساعة رقمية مكملة.

