Kalkulator Designcember

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

Tantangan

Saya anak tahun 1980-an. Hal yang sangat populer saat saya masih di sekolah menengah adalah kalkulator solar. Kami semua diberi TI-30X SOLAR oleh sekolah, dan saya memiliki kenangan indah saat kami melakukan benchmark kalkulator satu sama lain dengan menghitung faktorial 69, angka tertinggi yang dapat ditangani TI-30X. (Variasi kecepatan sangat terukur, saya masih belum tahu alasannya.)

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

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

Buat aplikasi dapat diinstal

Meskipun bukan awal yang buruk, saya memutuskan untuk meningkatkannya agar menjadi skeumorfisme yang luar biasa. Langkah pertama adalah membuatnya menjadi PWA agar dapat diinstal. Saya mengelola template PWA dasar di Glitch yang saya remix setiap kali memerlukan demo cepat. Service worker-nya tidak akan memenangkan penghargaan coding apa pun dan pastinya tidak siap produksi, tetapi cukup untuk memicu infobar mini Chromium sehingga aplikasi 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');
      }
    })(),
  );
});

Menggabungkan 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 menetapkan mode tampilan ke fullscreen di Manifes Aplikasi Web.

{
  "display": "fullscreen"
}

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

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

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

Menggabungkan dengan desktop

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

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

Hal ini membuat panel judul hilang secara efektif dan konten akan naik ke area panel judul seolah-olah panel judul tidak ada. Ide saya adalah memindahkan sel surya skeuomporfik ke atas ke panel judul dan UI kalkulator lainnya 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. Dalam 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 bereaksi terhadap perubahan overlay kontrol jendela. Dalam pendekatan peningkatan progresif yang sebenarnya, saya hanya memuat kode untuk fitur ini saat browser mendukungnya.

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

Setiap kali jendela mengontrol perubahan geometri overlay, saya akan mengubah aplikasi agar terlihat senatural mungkin. Sebaiknya lakukan debouncing pada peristiwa ini, karena peristiwa ini dapat sering dipicu saat pengguna mengubah ukuran jendela. Yaitu, saya menerapkan class wco ke beberapa elemen, sehingga CSS dari atas akan aktif, 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 hampir seperti Winamp klasik dengan salah satu tema Winamp lama. Sekarang saya dapat menempatkan kalkulator di desktop dengan bebas dan mengaktifkan fitur kontrol jendela dengan mengklik chevron di sudut kanan atas.

Designcember Calculator berjalan dalam mode mandiri dengan fitur Window Controls Overlay aktif. Layar mengeja &#39;Google&#39; dalam alfabet kalkulator.

Sel surya yang benar-benar berfungsi

Untuk menjadi geek sejati, tentu saja saya harus membuat sel surya benar-benar berfungsi. Kalkulator hanya boleh berfungsi jika ada cukup cahaya. Cara saya membuat model ini adalah dengan menetapkan opacity CSS angka 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 tanda #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 satuan lux setiap kali pembacaan baru tersedia. Berdasarkan tabel nilai situasi cahaya standar, saya menemukan 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 secukupnya. Dan begitulah: kalkulator surya skeuomorfik yang benar-benar berfungsi. TI-30X SOLAR lama saya yang telah teruji waktu telah berkembang pesat.

Demo

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

Selamat Designcember!