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