Kalkulator Designcember

Upaya skeuomorfik untuk membuat ulang kalkulator tenaga surya di web dengan Window Controls Overlay API dan Ambient Light Sensor API.

Tantangan

Saya anak tahun 1980-an. Satu hal yang sangat populer saat saya masih di sekolah menengah adalah kalkulator tenaga surya. Kami semua diberi TI-30X SOLAR oleh sekolah, dan saya memiliki kenangan indah saat kami membandingkan kalkulator kami satu sama lain dengan menghitung faktorial 69, angka tertinggi yang dapat ditangani TI-30X. (Variasi kecepatannya sangat terukur, saya masih tidak tahu mengapa.)

Sekarang, hampir 28 tahun kemudian, saya pikir akan menjadi tantangan Designcember yang menyenangkan untuk membuat ulang kalkulator dalam HTML, CSS, dan JavaScript. Karena bukan seorang desainer, saya tidak memulai dari awal, tetapi dengan CodePen oleh Sassja Ceballos.

Tampilan CodePen dengan panel HTML, CSS, dan JS bertumpuk di sebelah kiri dan pratinjau kalkulator di sebelah kanan.

Membuatnya dapat diinstal

Meskipun ini bukan awal yang buruk, saya memutuskan untuk meningkatkannya agar menjadi skeuomorfik yang luar biasa. Langkah pertama adalah menjadikannya PWA agar dapat diinstal.

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');
      }
    })(),
  );
});

Memadukan dengan perangkat seluler

Setelah aplikasi dapat diinstal, langkah berikutnya adalah membuatnya menyatu dengan aplikasi sistem operasi sebanyak mungkin. Di perangkat seluler, saya dapat melakukannya dengan menyetel mode tampilan ke fullscreen di Manifes Aplikasi Web.

{
  "display": "fullscreen"
}

Pada perangkat dengan lubang atau notch kamera, menyesuaikan area pandang sehingga konten menutupi seluruh layar akan membuat aplikasi terlihat menarik.

<meta name="viewport" content="initial-scale=1, viewport-fit=cover" />

Kalkulator Designcember berjalan dalam layar penuh di ponsel Pixel 6 Pro.

Menyatu dengan desktop

Di desktop, ada fitur keren yang dapat saya gunakan: Window Controls Overlay, yang memungkinkan saya menempatkan konten di panel judul jendela aplikasi. Langkah pertama adalah mengganti urutan penggantian mode tampilan sehingga mode tersebut mencoba menggunakan window-controls-overlay terlebih dahulu saat tersedia.

{
  "display_override": ["window-controls-overlay"]
}

Tindakan ini akan membuat kolom judul menghilang secara efektif dan konten akan berpindah ke area kolom judul seolah-olah kolom judul tidak ada. Ide saya adalah memindahkan sel surya skeumorfik ke atas ke dalam kolom judul dan sisa UI kalkulator ke bawah, yang dapat saya lakukan dengan beberapa CSS yang menggunakan variabel lingkungan titlebar-area-*. Anda akan melihat bahwa semua pemilih memiliki class wco, yang akan relevan beberapa paragraf di bawah.

#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);
}

Selanjutnya, saya perlu memutuskan elemen mana yang akan dibuat dapat ditarik, karena panel judul yang biasanya saya gunakan untuk menarik tidak tersedia. Dengan gaya widget klasik, saya bahkan dapat membuat seluruh kalkulator dapat ditarik dengan menerapkan (-webkit-)app-region: drag, selain tombol, yang mendapatkan (-webkit-)app-region: no-drag sehingga tidak dapat digunakan untuk menarik.

#calc_inside.wco,
#calc_solar_cell.wco {
  -webkit-app-region: drag;
  app-region: drag;
}

button {
  -webkit-app-region: no-drag;
  app-region: no-drag;
}

Langkah terakhir adalah membuat aplikasi reaktif terhadap perubahan overlay kontrol jendela. Dalam pendekatan progressive enhancement yang sebenarnya, saya hanya memuat kode untuk fitur ini jika browser mendukungnya.

if ('windowControlsOverlay' in navigator) {
  import('/wco.js');
}

Setiap kali geometri overlay kontrol jendela berubah, saya akan mengubah aplikasi agar terlihat sealami mungkin. Sebaiknya debounce peristiwa ini, karena dapat sering dipicu saat pengguna mengubah ukuran jendela. Yaitu, saya menerapkan class wco ke beberapa elemen, sehingga CSS saya dari atas akan diterapkan, dan saya juga mengubah warna tema. Saya dapat mendeteksi apakah overlay kontrol jendela terlihat dengan memeriksa properti 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();

Sekarang, dengan semua ini, saya mendapatkan widget kalkulator yang terasa hampir seperti Winamp klasik dengan salah satu tema Winamp lama. Sekarang saya dapat dengan bebas menempatkan kalkulator di desktop dan mengaktifkan fitur kontrol jendela dengan mengklik chevron di sudut kanan atas.

Kalkulator Designcember berjalan dalam mode mandiri dengan fitur Overlay Kontrol Jendela aktif. Layar menampilkan kata 'Google' dalam alfabet kalkulator.

Sel surya yang benar-benar berfungsi

Untuk membuat proyek ini benar-benar keren, saya tentu saja perlu membuat sel surya ini benar-benar berfungsi. Kalkulator hanya akan berfungsi jika ada cukup cahaya. Cara saya membuat model ini adalah dengan menetapkan opacity CSS dari digit pada layar melalui variabel CSS --opacity yang saya kontrol melalui JavaScript.

:root {
  --opacity: 0.75;
}

#calc_expression,
#calc_result {
  opacity: var(--opacity);
}

Untuk mendeteksi apakah ada cukup cahaya agar kalkulator berfungsi, saya menggunakan AmbientLightSensor API. Agar API ini tersedia, saya perlu menetapkan flag #enable-generic-sensor-extra-classes di about:flags dan meminta izin 'ambient-light-sensor'. Seperti sebelumnya, saya menggunakan progressive enhancement untuk hanya memuat kode yang relevan saat API didukung.

if ('AmbientLightSensor' in window) {
  import('/als.js');
}

Sensor menampilkan cahaya sekitar dalam unit lux setiap kali pembacaan baru tersedia. Berdasarkan tabel nilai situasi cahaya umum, saya membuat formula yang sangat sederhana untuk mengonversi nilai lux menjadi nilai antara 0 dan 1 yang saya tetapkan secara terprogram ke variabel --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();
  }
})();

Dalam video di bawah, Anda dapat melihat cara kalkulator mulai berfungsi setelah saya menyalakan lampu ruangan dengan cukup terang. Dan itulah: kalkulator surya skeumorfik yang benar-benar berfungsi. TI-30X SOLAR lama saya yang telah teruji waktu memang telah berkembang pesat.

Demo

Pastikan untuk mencoba demo Kalkulator Designcember dan lihat kode sumber di GitHub. (Untuk menginstal aplikasi, Anda harus membukanya di jendelanya sendiri. Versi sematan di bawah tidak akan memicu infobar mini.)

Selamat merayakan Designcember!