Window Controls Overlay API と Ambient Light Sensor API を使用して、ウェブで太陽光発電電卓を再現するスキューモーフィックな試み。
課題
私は 1980 年代の子どもです。高校生のころ、太陽光発電の計算機が大流行でした。私たちは全員、学校から TI-30X SOLAR を渡されました。TI-30X が処理できる最大の数である 69 の階乗を計算することで、各計算機のベンチマークを互いに比較したときのことを思い出します。(速度のばらつきは非常に測定可能でしたが、原因はまだわかりません)。
約 28 年後の今、HTML、CSS、JavaScript で計算機を再現するのは、Designcember の楽しいチャレンジになるだろうと思いました。私はデザイナーではないので、ゼロから始めるのではなく、Sassja Ceballos の CodePen を使っていました。
インストール可能にする
なかなか良いスタートでしたが、スキューモーフィックな映像に仕上げることにしました。最初のステップは PWA 化で インストールできるようにしましたGlitch でベースライン PWA テンプレートを管理しており、簡単なデモが必要なときはいつでもリミックスしています。Service Worker がコーディング賞を受賞することはなく、明らかに本番環境に対応していませんが、アプリをインストールするには Chromium のミニ情報バーを表示するだけで十分です。
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" />
デスクトップとの組み合わせ
パソコンには、ウィンドウ コントロール オーバーレイという便利な機能があります。この機能を使うと、アプリ ウィンドウのタイトルバーにコンテンツを配置できます。まず、表示モードのフォールバック シーケンスをオーバーライドして、window-controls-overlay
が使用可能になったときに最初に使用を試みます。
{
"display_override": ["window-controls-overlay"]
}
これにより、タイトルバーが実質的に非表示になり、コンテンツがタイトルバー領域にあたかもその位置にないかのように上に移動します。私のアイデアは、スキューモーフィック型太陽電池をタイトルバーに移動し、それに応じて計算ツール UI の残りの部分を下に移動することです。titlebar-area-*
環境変数を使用する CSS でこれを行うこともできます。すべてのセレクタに 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: no-drag
を取得するボタンとは別に、(-webkit-)app-region: 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
クラスを一部の要素に適用するため、上記の CSS が有効になり、テーマの色も変更します。ウィンドウ コントロール オーバーレイが表示されているかどうかは、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 とほぼ同じです。デスクトップに電卓を自由に配置し、右上のシェブロンをクリックしてウィンドウ コントロール機能を有効にできます。
実際に動作している太陽電池
究極の技術を求めるには、もちろん太陽電池を実際に動作させる必要がありました。電卓は十分な明るさがある場合にのみ機能します。これをモデル化するには、JavaScript で制御する CSS 変数 --opacity
を使用して、表示する数字の CSS opacity
を設定します。
:root {
--opacity: 0.75;
}
#calc_expression,
#calc_result {
opacity: var(--opacity);
}
計算ツールが動作するのに十分な明るさがあるかどうかを検出するには、AmbientLightSensor
API を使用します。この API を使用できるようにするには、about:flags
で #enable-generic-sensor-extra-classes
フラグを設定し、'ambient-light-sensor'
権限をリクエストする必要がありました。以前と同様に、プログレッシブ エンハンスメントを使用して、API がサポートされている場合にのみ関連するコードを読み込みます。
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 デモを試し、Glitch のソースコードを確認してください。(アプリをインストールするには、アプリを別のウィンドウで開く必要があります。下記の埋め込みバージョンでは、ミニ情報バーは表示されません)。
Designcember をお楽しみください!