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.

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

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.

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!