नए CSS sin() और cos() त्रिकोणमिति कार्यों के साथ एक घड़ी बनाना

नए CSS sin() और cos() त्रिकोणमिति कार्यों के साथ एक घड़ी बनाना

स्रोत नोड: 1999799

CSS त्रिकोणमिति कार्य यहाँ हैं! ठीक है, वे हैं यदि आप फ़ायरफ़ॉक्स और सफारी के नवीनतम संस्करणों का उपयोग कर रहे हैं, अर्थात। CSS में इस प्रकार की गणितीय शक्ति होने से संभावनाओं का एक पूरा समूह खुल जाता है। इस ट्यूटोरियल में, मैंने सोचा कि हम अपने पैर की उंगलियों को पानी में डुबाएंगे ताकि कुछ नए कार्यों को महसूस कर सकें: sin() और cos().

पाइपलाइन में अन्य त्रिकोणमिति कार्य हैं - सहित tan() - तो सिर्फ पर ध्यान क्यों दें sin() और cos()? वे उस विचार के लिए एकदम सही हैं जो मेरे मन में है, जो पाठ को एक वृत्त के किनारे पर रखना है। यह यहाँ CSS-Tricks पर कवर किया गया है जब क्रिस ने एक दृष्टिकोण साझा किया जो सैस मिक्सिन का उपयोग करता है. वह छह साल पहले की बात है, तो चलिए इसे ब्लीडिंग एज ट्रीटमेंट देते हैं।

यहाँ मेरे मन में क्या है। दोबारा, यह फिलहाल केवल फ़ायरफ़ॉक्स और सफारी में समर्थित है:

तो, यह बिल्कुल गोल आकार बनाने वाले शब्दों की तरह नहीं है, लेकिन हम क्लॉक फेस बनाने के लिए टेक्स्ट वर्णों को सर्कल के साथ रख रहे हैं। यहां कुछ मार्कअप दिए गए हैं जिनका उपयोग हम चीजों को शुरू करने के लिए कर सकते हैं:

<div class="clock"> <div class="clock-face"> <time datetime="12:00">12</time> <time datetime="1:00">1</time> <time datetime="2:00">2</time> <time datetime="3:00">3</time> <time datetime="4:00">4</time> <time datetime="5:00">5</time> <time datetime="6:00">6</time> <time datetime="7:00">7</time> <time datetime="8:00">8</time> <time datetime="9:00">9</time> <time datetime="10:00">10</time> <time datetime="11:00">11</time> </div>
</div>

इसके बाद, यहां कुछ सुपर बेसिक स्टाइल हैं .clock-face कंटेनर। मैंने उपयोग करने का निर्णय लिया <time> a के साथ टैग करें datetime विशेषता। 

.clock { --_ow: clamp(5rem, 60vw, 40rem); --_w: 88cqi; aspect-ratio: 1; background-color: tomato; border-radius: 50%; container-type: inline; display: grid; height: var(--_ow); place-content: center; position: relative; width var(--_ow);
}

मैंने वहां चीजों को थोड़ा सा सजाया, लेकिन केवल मूल आकार और पृष्ठभूमि का रंग पाने के लिए हमें यह देखने में मदद मिली कि हम क्या कर रहे हैं। ध्यान दें कि हम कैसे सहेजते हैं width एक में मान सीएसएस चर. हम उसे बाद में उपयोग करेंगे। अब तक देखने के लिए बहुत कुछ नहीं:

बाईं ओर संख्या 1-12 की लंबवत सूची के साथ टमाटर के रंग का बड़ा चक्र।

यह किसी प्रकार का आधुनिक कला प्रयोग जैसा लगता है, है ना? आइए एक नया चर पेश करते हैं, --_r, सर्कल को स्टोर करने के लिए त्रिज्या, जो वृत्त की चौड़ाई के आधे के बराबर है। इस प्रकार, यदि चौड़ाई (--_w) परिवर्तन, त्रिज्या मान (--_r) भी अपडेट होगा - एक और सीएसएस गणित समारोह के लिए धन्यवाद, calc():

.clock { --_w: 300px; --_r: calc(var(--_w) / 2); /* rest of styles */
}

अब थोड़ा गणित। एक वर्तुल 360 डिग्री का होता है। हमारी घड़ी पर 12 लेबल हैं, इसलिए हर 30 डिग्री पर नंबर लगाना चाहते हैं (360 / 12). गणित-भूमि में वृत्त 3 बजे शुरू होता है, अतः वास्तव में मध्याह्न है शून्य से 90 डिग्री उससे, जो 270 डिग्री है (360 - 90).

आइए एक और चर जोड़ें, --_d, जिसका उपयोग हम सेट करने के लिए कर सकते हैं हद घड़ी के चेहरे पर प्रत्येक संख्या के लिए मूल्य। हम अपना चक्र पूरा करने के लिए मानों को 30 डिग्री तक बढ़ाने जा रहे हैं:

.clock time:nth-child(1) { --_d: 270deg; }
.clock time:nth-child(2) { --_d: 300deg; }
.clock time:nth-child(3) { --_d: 330deg; }
.clock time:nth-child(4) { --_d: 0deg; }
.clock time:nth-child(5) { --_d: 30deg; }
.clock time:nth-child(6) { --_d: 60deg; }
.clock time:nth-child(7) { --_d: 90deg; }
.clock time:nth-child(8) { --_d: 120deg; }
.clock time:nth-child(9) { --_d: 150deg; }
.clock time:nth-child(10) { --_d: 180deg; }
.clock time:nth-child(11) { --_d: 210deg; }
.clock time:nth-child(12) { --_d: 240deg; }

ठीक है, अब हमारे हाथ गंदे करने का समय है sin() और cos() कार्य करता है! हम जो करना चाहते हैं, वह प्रत्येक संख्या के लिए X और Y निर्देशांक प्राप्त करने के लिए उनका उपयोग करना है ताकि हम उन्हें घड़ी के चारों ओर ठीक से रख सकें।

X निर्देशांक का सूत्र है radius + (radius * cos(degree)). आइए इसे अपने नए में प्लग करें --_x चर:

--_x: calc(var(--_r) + (var(--_r) * cos(var(--_d))));

Y निर्देशांक का सूत्र है radius + (radius * sin(degree)). इसकी गणना करने के लिए हमारे पास वह है जो हमें चाहिए:

--_y: calc(var(--_r) + (var(--_r) * sin(var(--_d))));

संख्याओं को सेट करने के लिए हमें कुछ हाउसकीपिंग चीज़ें करने की आवश्यकता होती है, तो चलिए यह सुनिश्चित करने के लिए उन पर कुछ बुनियादी स्टाइल डालते हैं कि वे हमारे निर्देशांकों के साथ पूरी तरह से स्थित हैं और रखे गए हैं:

.clock-face time { --_x: calc(var(--_r) + (var(--_r) * cos(var(--_d)))); --_y: calc(var(--_r) + (var(--_r) * sin(var(--_d)))); --_sz: 12cqi; display: grid; height: var(--_sz); left: var(--_x); place-content: center; position: absolute; top: var(--_y); width: var(--_sz);
}

नोटिस --_sz, जिसका हम उपयोग करेंगे width और height एक क्षण में संख्याओं का। आइए देखें कि हमारे पास अब तक क्या है।

बड़े टमाटर के रंग का चक्र जिसके किनारों पर ऑफ-सेंटर घंटे संख्या लेबल हैं।

यह निश्चित रूप से घड़ी की तरह अधिक दिखता है! देखें कि प्रत्येक संख्या का शीर्ष-बायां कोना वृत्त के चारों ओर सही स्थान पर कैसे स्थित है? प्रत्येक संख्या के लिए पदों की गणना करते समय हमें त्रिज्या को "सिकुड़ने" की आवश्यकता होती है। हम कर सकते हैं घटा एक संख्या का आकार (--_sz) वृत्त के आकार से (--_w), त्रिज्या की गणना करने से पहले:

--_r: calc((var(--_w) - var(--_sz)) / 2);
बड़े टमाटर के रंग का चक्र जिसके गोल किनारे पर घंटे संख्या के लेबल हैं।

ज्यादा बेहतर! चलो रंग बदलते हैं, ताकि यह और अधिक सुरुचिपूर्ण दिखे:

एक गहरे भूरे रंग की पृष्ठभूमि के खिलाफ संख्या के साथ एक सफेद घड़ी का चेहरा। घड़ी की कोई भुजा नहीं है।

हम यहीं रुक सकते थे! हमने पाठ को एक वृत्त के चारों ओर रखने का लक्ष्य पूरा कर लिया है, है ना? लेकिन घंटे, मिनट और सेकंड दिखाने के लिए हथियारों के बिना घड़ी क्या है?

उसके लिए एक CSS एनीमेशन का उपयोग करते हैं। पहले, अपने मार्कअप में तीन और तत्व जोड़ते हैं,

<div class="clock"> <!-- after <time>-tags --> <span class="arm seconds"></span> <span class="arm minutes"></span> <span class="arm hours"></span> <span class="arm center"></span>
</div>

फिर तीनों भुजाओं के लिए कुछ सामान्य मार्कअप। दोबारा, इसमें से अधिकतर यह सुनिश्चित कर लें कि हथियार पूरी तरह से स्थित हैं और तदनुसार रखा गया है:

.arm { background-color: var(--_abg); border-radius: calc(var(--_aw) * 2); display: block; height: var(--_ah); left: calc((var(--_w) - var(--_aw)) / 2); position: absolute; top: calc((var(--_w) / 2) - var(--_ah)); transform: rotate(0deg); transform-origin: bottom; width: var(--_aw);
}

हम उपयोग करेंगे वही एनीमेशन तीनों भुजाओं के लिए:

@keyframes turn { to { transform: rotate(1turn); }
}

फर्क सिर्फ इतना है कि अलग-अलग भुजाओं को पूर्ण मोड़ लेने में कितना समय लगता है। के लिए घंटे हाथ, यह 12 घंटे एक पूर्ण मोड़ बनाने के लिए। animation-duration गुण केवल मिलीसेकंड और सेकंड में मान स्वीकार करता है। आइए सेकंड के साथ बने रहें, जो कि 43,200 सेकंड है (60 seconds * 60 minutes * 12 hours).

animation: turn 43200s infinite;

यह 1 घंटे के लिए मिनट हाथ एक पूर्ण मोड़ बनाने के लिए। लेकिन हम चाहते हैं कि यह एक हो बहु-चरण एनीमेशन इसलिए बाजुओं के बीच की गति रेखीय के बजाय कंपित होती है। हमें 60 चरणों की आवश्यकता होगी, प्रत्येक मिनट के लिए एक:

animation: turn 3600s steps(60, end) infinite;

RSI सेकंड हाथ is लगभग एक जैसा मिनट आर्म के रूप में, लेकिन अवधि 60 मिनट के बजाय 60 सेकंड है:

animation: turn 60s steps(60, end) infinite;

आइए उन गुणों को अपडेट करें जिन्हें हमने सामान्य शैलियों में बनाया था:

.seconds { --_abg: hsl(0, 5%, 40%); --_ah: 145px; --_aw: 2px; animation: turn 60s steps(60, end) infinite;
}
.minutes { --_abg: #333; --_ah: 145px; --_aw: 6px; animation: turn 3600s steps(60, end) infinite;
}
.hours { --_abg: #333; --_ah: 110px; --_aw: 6px; animation: turn 43200s linear infinite;
}

क्या होगा अगर हम मौजूदा समय में शुरू करना चाहते हैं? हमें थोड़ी सी जावास्क्रिप्ट चाहिए:

const time = new Date();
const hour = -3600 * (time.getHours() % 12);
const mins = -60 * time.getMinutes();
app.style.setProperty('--_dm', `${mins}s`);
app.style.setProperty('--_dh', `${(hour+mins)}s`);

मैंने जोड़ लिया है id="app" क्लॉकफेस पर और उस पर दो नए कस्टम गुण सेट करें जो एक नकारात्मक सेट करते हैं animation-delay, जैसा कि मेट मार्सचल्को ने किया था जब उसने केवल CSS वाली घड़ी साझा की।  getHours() JavaScipt की विधि Date ऑब्जेक्ट 24-घंटे के प्रारूप का उपयोग कर रहा है, इसलिए हम इसका उपयोग करते हैं remainder ऑपरेटर इसे 12-घंटे के प्रारूप में बदलने के लिए।

CSS में, हमें जोड़ने की आवश्यकता है animation-delay भी:

.minutes { animation-delay: var(--_dm, 0s); /* other styles */
} .hours { animation-delay: var(--_dh, 0s); /* other styles */
}

बस एक और बात। सीएसएस का उपयोग करना @supports और जिन गुणों को हमने पहले ही बना लिया है, हम उन ब्राउज़रों को फ़ॉलबैक प्रदान कर सकते हैं जो समर्थन नहीं करते हैं sin() और cos(). (धन्यवाद, तेमानी अफिफ!):

@supports not (left: calc(1px * cos(45deg))) {
  time {
    left: 50% !important;
    top: 50% !important;
    transform: translate(-50%,-50%) rotate(var(--_d)) translate(var(--_r)) rotate(calc(-1*var(--_d)))
  }
}

और, देखा! हमारी घड़ी हो गई! यहाँ अंतिम डेमो एक बार और है। फिर से, फिलहाल यह केवल Firefox और Safari में समर्थित है।

इसके अलावा हम क्या कर सकते हैं?

बस इधर-उधर गड़बड़ कर रहे हैं, लेकिन हम अपनी घड़ी को जल्दी से एक गोलाकार इमेज गैलरी में बदल सकते हैं <time> के साथ टैग <img> फिर चौड़ाई अद्यतन करना (--_w) और त्रिज्या (--_r) मान:

आइए एक और प्रयास करें। मैंने पहले उल्लेख किया था कि कैसे घड़ी एक आधुनिक कला प्रयोग की तरह दिखती थी। हम उसमें झुक सकते हैं और दूसरे दिन एक आर्ट गैलरी में एक पोस्टर पर देखे गए पैटर्न को फिर से बना सकते हैं (जो मैंने दुर्भाग्य से नहीं खरीदा)। जैसा कि मुझे याद है, इसे "चंद्रमा" कहा जाता था और इसमें एक वृत्त बनाने वाले बिंदुओं का एक गुच्छा होता था।

विभिन्न अर्थटोन रंगों के छोटे भरे हुए हलकों के एक समूह से बना एक बड़ा वृत्त।

हम इस बार एक अक्रमित सूची का उपयोग करेंगे क्योंकि मंडलियां किसी विशेष आदेश का पालन नहीं करती हैं। हम सभी सूची आइटमों को मार्कअप में भी नहीं डालने जा रहे हैं। इसके बजाय, आइए उन्हें जावास्क्रिप्ट से इंजेक्ट करें और कुछ नियंत्रण जोड़ें जिनका उपयोग हम अंतिम परिणाम में हेरफेर करने के लिए कर सकते हैं।

नियंत्रण रेंज इनपुट हैं (<input type="range">) जिसे हम एक में लपेटेंगे <form> और के लिए सुनो input घटना।

<form id="controls"> <fieldset> <label>Number of rings <input type="range" min="2" max="12" value="10" id="rings" /> </label> <label>Dots per ring <input type="range" min="5" max="12" value="7" id="dots" /> </label> <label>Spread <input type="range" min="10" max="40" value="40" id="spread" /> </label> </fieldset>
</form>

हम इस विधि को "इनपुट" पर चलाएंगे, जो एक गुच्छा बनाएगा <li> डिग्री के साथ तत्व (--_d) वेरिएबल जिनका हमने पहले प्रयोग किया था, प्रत्येक पर लागू होते हैं। हम अपने त्रिज्या चर का पुनरुत्पादन भी कर सकते हैं (--_r)।

मैं यह भी चाहता हूं कि डॉट्स अलग-अलग रंग के हों। तो, चलो यादृच्छिक करें (ठीक है, नहीं पूरी तरह से यादृच्छिक) प्रत्येक सूची आइटम के लिए एचएसएल रंग मान और इसे एक नए सीएसएस चर के रूप में संग्रहीत करें, --_bgc:

const update = () => { let s = ""; for (let i = 1; i <= rings.valueAsNumber; i++) { const r = spread.valueAsNumber * i; const theta = coords(dots.valueAsNumber * i); for (let j = 0; j < theta.length; j++) { s += `<li style="--_d:${theta[j]};--_r:${r}px;--_bgc:hsl(${random( 50, 25 )},${random(90, 50)}%,${random(90, 60)}%)"></li>`; } } app.innerHTML = s;
}

RSI random() विधि संख्याओं की परिभाषित सीमा के भीतर एक मान चुनती है:

const random = (max, min = 0, f = true) => f ? Math.floor(Math.random() * (max - min) + min) : Math.random() * max;

और बस। हम मार्कअप को रेंडर करने के लिए जावास्क्रिप्ट का उपयोग करते हैं, लेकिन जैसे ही यह रेंडर हो जाता है, हमें वास्तव में इसकी आवश्यकता नहीं होती है। sin() और cos() फ़ंक्शन हमें सभी बिंदुओं को सही स्थानों पर रखने में मदद करते हैं।

अंतिम विचार

त्रिकोणमिति कार्यों की शक्तियों को प्रदर्शित करने के लिए एक वृत्त के चारों ओर चीजों को रखना एक बहुत ही बुनियादी उदाहरण है sin() और cos()। पर ये वास्तव में अच्छा है कि हमें आधुनिक सीएसएस सुविधाएँ मिल रही हैं जो पुराने समाधान के लिए नए समाधान प्रदान करती हैं मुझे यकीन है कि हम अधिक दिलचस्प, जटिल और रचनात्मक उपयोग के मामले देखेंगे, विशेष रूप से क्रोम और एज के लिए ब्राउज़र समर्थन के रूप में।

समय टिकट:

से अधिक सीएसएस ट्रिक्स