Window Controls Overlay API और Ambient Light Sensor API की मदद से, वेब पर सोलर कैलकुलेटर को फिर से बनाने की कोशिश.
चुनौती
मैं 1980 के दशक का बच्चा हूं. जब मैं हाई स्कूल में था, तब सोलर कैलकुलेटर काफ़ी लोकप्रिय थे. स्कूल ने हम सभी को एक TI-30X SOLAR दिया था. मुझे याद है कि हम एक-दूसरे के कैलकुलेटर की तुलना करते थे. इसके लिए, हम 69 की फ़ैक्टरियल का हिसाब लगाते थे. यह TI-30X कैलकुलेटर के लिए सबसे बड़ी संख्या थी. (स्पीड में अंतर का पता लगाना बहुत आसान था, लेकिन मुझे अब भी नहीं पता कि ऐसा क्यों हुआ.)
अब, करीब 28 साल बाद, मुझे लगा कि एचटीएमएल, सीएसएस, और JavaScript में कैलकुलेटर को फिर से बनाना, Designcember का एक मज़ेदार चैलेंज होगा. मैं ज़्यादा डिज़ाइनर नहीं हूं, इसलिए मैंने शुरू से नहीं बल्कि Sassja Ceballos के CodePen से शुरुआत की.
इसे इंस्टॉल किया जा सके
शुरुआत अच्छी थी, लेकिन मैंने इसे शानदार स्क्यूमॉर्फ़िक डिज़ाइन देने के लिए बेहतर बनाने का फ़ैसला किया. पहला चरण, इसे PWA बनाना था, ताकि इसे इंस्टॉल किया जा सके. मेरे पास Glitch पर एक बेसलाइन PWA टेंप्लेट है. जब भी मुझे तुरंत डेमो की ज़रूरत होती है, तो मैं उसे रीमिक्स कर लेती हूं. इसकी सेवा वर्कर आपको कोडिंग का कोई अवॉर्ड नहीं दिलाएगी और यह बिल्कुल प्रोडक्शन के लिए तैयार नहीं है. हालांकि, यह Chromium के मिनी जानकारी बार को ट्रिगर करने के लिए काफ़ी है, ताकि ऐप्लिकेशन इंस्टॉल किया जा सके.
self.addEventListener('install', (event) => {
self.skipWaiting();
});
self.addEventListener('activate', (event) => {
self.clients.claim();
event.waitUntil(
(async () => {
if ('navigationPreload' in self.registration) {
await self.registration.navigationPreload.enable();
}
})(),
);
});
self.addEventListener('fetch', (event) => {
event.respondWith(
(async () => {
try {
const response = await event.preloadResponse;
if (response) {
return response;
}
return fetch(event.request);
} catch {
return new Response('Offline');
}
})(),
);
});
मोबाइल के साथ ब्लेंड करना
अब ऐप्लिकेशन इंस्टॉल किया जा सकता है. अगला चरण, इसे ऑपरेटिंग सिस्टम के ऐप्लिकेशन के साथ ज़्यादा से ज़्यादा ब्लेंड करना है. मोबाइल पर, वेब ऐप्लिकेशन मेनिफ़ेस्ट में डिसप्ले मोड को fullscreen
पर सेट करके ऐसा किया जा सकता है.
{
"display": "fullscreen"
}
जिन डिवाइसों में कैमरा होल या नॉच है उन पर, व्यूपोर्ट में बदलाव करके, कॉन्टेंट को पूरी स्क्रीन पर दिखाया जा सकता है. इससे ऐप्लिकेशन शानदार दिखता है.
<meta name="viewport" content="initial-scale=1, viewport-fit=cover" />
डेस्कटॉप के साथ ब्लेंड करना
डेस्कटॉप पर, एक शानदार सुविधा का इस्तेमाल किया जा सकता है:
विंडो कंट्रोल ओवरले. इसकी मदद से, ऐप्लिकेशन विंडो के टाइटल बार में कॉन्टेंट डाला जा सकता है. सबसे पहले, डिसप्ले मोड के फ़ॉलबैक क्रम को बदलें, ताकि उपलब्ध होने पर window-controls-overlay
का इस्तेमाल किया जा सके.
{
"display_override": ["window-controls-overlay"]
}
इससे टाइटल बार हट जाता है और कॉन्टेंट, टाइटल बार के एरिया में ऊपर की ओर चला जाता है. ऐसा लगता है कि टाइटल बार वहां मौजूद ही नहीं है. मेरा सुझाव है कि स्क्यूमॉर्फ़िक सोलर सेल को टाइटल बार में ऊपर और कैलकुलेटर के बाकी यूज़र इंटरफ़ेस (यूआई) को नीचे ले जाया जाए. ऐसा करने के लिए, titlebar-area-*
एनवायरमेंट वैरिएबल का इस्तेमाल करने वाली कुछ सीएसएस का इस्तेमाल किया जा सकता है. आपको पता चलेगा कि सभी सिलेक्टर में wco
क्लास है, जो कुछ पैराग्राफ़ नीचे काम आएगा.
#calc_solar_cell.wco {
position: fixed;
left: calc(0.25rem + env(titlebar-area-x, 0));
top: calc(0.75rem + env(titlebar-area-y, 0));
width: calc(env(titlebar-area-width, 100%) - 0.5rem);
height: calc(env(titlebar-area-height, 33px) - 0.5rem);
}
#calc_display_surface.wco {
margin-top: calc(env(titlebar-area-height, 33px) - 0.5rem);
}
इसके बाद, मुझे यह तय करना होगा कि किन एलिमेंट को खींचकर छोड़ा जा सकता है, क्योंकि टाइटल बार, जिसका इस्तेमाल आम तौर पर खींचकर छोड़ने के लिए किया जाता है वह उपलब्ध नहीं है. क्लासिक विजेट के स्टाइल में, (-webkit-)app-region: drag
लागू करके पूरे कैलकुलेटर को खींचा और छोड़ा जा सकता है. हालांकि, बटन पर (-webkit-)app-region: no-drag
लागू होता है, ताकि उन्हें खींचा और छोड़ा न जा सके.
#calc_inside.wco,
#calc_solar_cell.wco {
-webkit-app-region: drag;
app-region: drag;
}
button {
-webkit-app-region: no-drag;
app-region: no-drag;
}
आखिरी चरण में, ऐप्लिकेशन को विंडो कंट्रोल ओवरले में होने वाले बदलावों के हिसाब से रीऐक्ट करने लायक बनाना होता है. प्रगतिशील बेहतर बनाने के सही तरीके में, मैं इस सुविधा का कोड सिर्फ़ तब लोड करता हूं, जब ब्राउज़र उस पर काम करता हो.
if ('windowControlsOverlay' in navigator) {
import('/wco.js');
}
जब भी विंडो कंट्रोल ओवरले की ज्यामिति में बदलाव होता है, तो मैं ऐप्लिकेशन में बदलाव करता/करती हूं, ताकि वह ज़्यादा से ज़्यादा स्वाभाविक दिखे. इस इवेंट को डीबाउंस करना एक अच्छा विचार है, क्योंकि जब उपयोगकर्ता विंडो का साइज़ बदलता है, तो यह बार-बार ट्रिगर हो सकता है. उदाहरण के लिए, मैंने कुछ एलिमेंट पर wco
क्लास लागू की है, ताकि ऊपर दी गई मेरी सीएसएस काम कर सके. साथ ही, मैंने थीम का रंग भी बदला है. navigator.windowControlsOverlay.visible
प्रॉपर्टी की जांच करके, यह पता लगाया जा सकता है कि विंडो कंट्रोल ओवरले दिख रहा है या नहीं.
const meta = document.querySelector('meta[name="theme-color"]');
const nodes = document.querySelectorAll(
'#calc_display_surface, #calc_solar_cell, #calc_outside, #calc_inside',
);
const toggleWCO = () => {
if (!navigator.windowControlsOverlay.visible) {
meta.content = '';
} else {
meta.content = '#385975';
}
nodes.forEach((node) => {
node.classList.toggle('wco', navigator.windowControlsOverlay.visible);
});
};
const debounce = (func, wait) => {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
};
navigator.windowControlsOverlay.ongeometrychange = debounce((e) => {
toggleWCO();
}, 250);
toggleWCO();
अब मुझे कैलकुलेटर विजेट मिलता है, जो Winamp की क्लासिक थीम के साथ, Winamp की पुरानी थीम जैसा ही लगता है. अब मैं अपने डेस्कटॉप पर कैलकुलेटर को अपनी पसंद के मुताबिक कहीं भी रख सकता हूं. साथ ही, सबसे ऊपर दाएं कोने में मौजूद शेवरॉन पर क्लिक करके, विंडो कंट्रोल की सुविधा चालू कर सकता हूं.
असल में काम करने वाला सोलर सेल
असल में सोलर सेल को काम करने के लिए, मुझे ज़रूर से ज़्यादा से ज़्यादा जानकारी चाहिए थी. कैलकुलेटर सिर्फ़ तब काम करना चाहिए, जब रोशनी काफ़ी हो. मैंने इसे इस तरह से मॉडल किया है: मैंने डिसप्ले पर अंकों की सीएसएस opacity
को, सीएसएस वैरिएबल --opacity
के ज़रिए सेट किया है. इसे JavaScript के ज़रिए कंट्रोल किया जाता है.
:root {
--opacity: 0.75;
}
#calc_expression,
#calc_result {
opacity: var(--opacity);
}
कैलकुलेटर के काम करने के लिए, रोशनी काफ़ी है या नहीं, यह पता लगाने के लिए, हम AmbientLightSensor
एपीआई का इस्तेमाल करते हैं. इस एपीआई को उपलब्ध कराने के लिए, मुझे about:flags
में #enable-generic-sensor-extra-classes
फ़्लैग सेट करना पड़ा और 'ambient-light-sensor'
की अनुमति का अनुरोध करना पड़ा. पहले की तरह, एपीआई के काम करने पर ही काम का कोड लोड करने के लिए, मैं प्रोग्रेसिव बेहतर बनाने की सुविधा का इस्तेमाल करता/करती हूं.
if ('AmbientLightSensor' in window) {
import('/als.js');
}
जब भी कोई नई रीडिंग उपलब्ध होती है, तो सेंसर आस-पास की रोशनी की जानकारी लक्स यूनिट में दिखाता है. आम तौर पर, लाइट की स्थितियों के हिसाब से वैल्यू की टेबल के आधार पर, मैंने एक बहुत ही आसान फ़ॉर्मूला बनाया है. इसकी मदद से, लक्स वैल्यू को 0 से 1 के बीच की वैल्यू में बदला जा सकता है. मैंने इस वैल्यू को प्रोग्राम के हिसाब से --opacity
वैरिएबल को असाइन किया है.
const luxToOpacity = (lux) => {
if (lux > 250) {
return 1;
}
return lux / 250;
};
const sensor = new window.AmbientLightSensor();
sensor.onreading = () => {
console.log('Current light level:', sensor.illuminance);
document.documentElement.style.setProperty(
'--opacity',
luxToOpacity(sensor.illuminance),
);
};
sensor.onerror = (event) => {
console.log(event.error.name, event.error.message);
};
(async () => {
const {state} = await navigator.permissions.query({
name: 'ambient-light-sensor',
});
if (state === 'granted') {
sensor.start();
}
})();
नीचे दिए गए वीडियो में देखा जा सकता है कि कमरे की रोशनी को ज़रूरत के मुताबिक बढ़ाने पर, कैलकुलेटर कैसे काम करना शुरू करता है. और यहाँ आपके पास है: एक स्क्यूमॉर्फ़िक सोलर कैलकुलेटर, जो असल में काम करता है. मेरी पुरानी और भरोसेमंद TI-30X SOLAR कैलकुलेटर ने काफ़ी तरक्की की है.
डेमो
Designcember कैलकुलेटर के डेमो को आज़माना न भूलें और Glitch पर सोर्स कोड देखें. (ऐप्लिकेशन को इंस्टॉल करने के लिए, आपको उसे अपनी विंडो में खोलना होगा. नीचे दिए गए एम्बेड किए गए वर्शन से, छोटा जानकारी बार ट्रिगर नहीं होगा.)
Designcember की शुभकामनाएं!