Designcember कैलकुलेटर

यह Window Controls Overlay API और Ambient Light Sensor API की मदद से, वेब पर सोलर कैलकुलेटर को फिर से बनाने की कोशिश है.

चुनौती

मैं 1980 के दशक का बच्चा हूं. जब मैं हाई स्कूल में था, तब सोलर कैलकुलेटर काफ़ी लोकप्रिय थे. स्कूल ने हम सभी को TI-30X SOLAR कैलकुलेटर दिया था. मुझे याद है कि हम सभी ने एक-दूसरे के कैलकुलेटर की तुलना करने के लिए, 69 का फ़ैक्टोरियल निकाला था. यह TI-30X कैलकुलेटर की सबसे बड़ी संख्या थी. (स्पीड में अंतर काफ़ी ज़्यादा था. मुझे अब भी नहीं पता कि ऐसा क्यों हुआ.)

अब, करीब 28 साल बाद, मैंने सोचा कि एचटीएमएल, सीएसएस, और JavaScript में कैलकुलेटर को फिर से बनाना, Designcember का एक मज़ेदार चैलेंज होगा. मैं एक डिज़ाइनर नहीं हूं, इसलिए मैंने शुरुआत से काम नहीं किया. मैंने Sassja Ceballos के CodePen का इस्तेमाल किया.

CodePen व्यू में, बाईं ओर एचटीएमएल, सीएसएस, और JS पैनल स्टैक किए गए हैं. साथ ही, दाईं ओर कैलकुलेटर की झलक दिखाई गई है.

इसे इंस्टॉल करने लायक बनाएं

यह शुरुआत अच्छी थी, लेकिन मैंने इसे पूरी तरह से स्केओमॉर्फ़िक बनाने का फ़ैसला किया. पहला चरण, इसे PWA बनाना था, ताकि इसे इंस्टॉल किया जा सके.

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" />

Pixel 6 Pro फ़ोन पर, Designcember Calculator को फ़ुलस्क्रीन मोड में दिखाया गया है.

डेस्कटॉप के साथ ब्लेंड करना

डेस्कटॉप पर, मेरे पास इस्तेमाल करने के लिए एक बेहतरीन सुविधा है: विंडो को ऊपर लाने की सुविधा. इसकी मदद से, मैं ऐप्लिकेशन विंडो के टाइटल बार में कॉन्टेंट डाल सकता हूं. पहला चरण, डिसप्ले मोड फ़ॉलबैक सीक्वेंस को बदलना है, ताकि उपलब्ध होने पर 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 के पुराने थीम में से एक थीम का इस्तेमाल किया गया है. अब मैं कैलकुलेटर को अपने डेस्कटॉप पर कहीं भी रख सकता/सकती हूं. साथ ही, सबसे ऊपर दाएं कोने में मौजूद शेवरॉन पर क्लिक करके, विंडो कंट्रोल करने की सुविधा चालू कर सकता/सकती हूं.

Designcember Calculator, स्टैंडअलोन मोड में चल रहा है. इसमें विंडो को ऊपर लाने की सुविधा चालू है. डिस्प्ले में, कैल्क्यूलेटर के वर्णमाला के हिसाब से &#39;Google&#39; लिखा होता है.

असल में काम करने वाला सोलर सेल

ज़ाहिर है, मुझे सोलर सेल को असल में काम करने लायक बनाना था. कैलकुलेटर सिर्फ़ तब काम करना चाहिए, जब रोशनी सही हो. मैंने इसे इस तरह से मॉडल किया है कि सीएसएस वैरिएबल --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 Calculator का डेमो ज़रूर आज़माएं. साथ ही, GitHub पर सोर्स कोड देखें. (ऐप्लिकेशन इंस्टॉल करने के लिए, आपको इसे अपनी विंडो में खोलना होगा. नीचे दिया गया एम्बेड किया गया वर्शन, मिनी इन्फ़ोबार को ट्रिगर नहीं करेगा.)

Happy Designcember!