Designcember Hesap Makinesi

Window Controls Overlay API ve Ambiyans Işığı Sensör API'si kullanarak web'de güneş enerjisi hesaplayıcıyı yeniden oluşturmaya yönelik şüpheli bir deneme.

Yarışma

1980'lerde yaşayan bir çocuğum. Lisedeyken en popüler olan şeylerden biri güneş hesaplayıcılarıydı. Okul bize TI-30X SOLAR vermişti ve TI-30X'in başa çıkabileceği en yüksek sayı olan 69'u hesaplayarak hesap makinelerimizi birbirimizle karşılaştırırken güzel hatıralarım var. (Hız farkı çok ölçülebilirdi, ama nedeniyle ilgili hâlâ bir fikrim yoktu.)

Yaklaşık 28 yıl sonra, hesap makinesini HTML, CSS ve JavaScript'te yeniden oluşturmanın eğlenceli bir Designcember yarışması olacağını düşündüm. Çok fazla tasarımcı olmadığım için sıfırdan başlamadım ancak Sassja Ceballos'un CodePen'i ile başladım.

Sol tarafta yığın HTML, CSS ve JS panelleri, sağ tarafta ise hesap makinesi önizlemesi bulunan CodePen görünümü.

Yüklenebilir hale getirin

Kötü bir başlangıç olmamakla birlikte, şüphesiz mükemmellik için cesaretlendirmeye karar verdim. İlk adım, yüklenebilmesi için uygulamayı PWA yapmaktı. Glitch'te temel PWA şablonu tutuyorum. Hızlı bir demoya ihtiyaç duyduğumda bunları remiks olarak remiks olarak derliyorum. Hizmet çalışanı size kodlama ödülü vermez ve kesinlikle üretime hazır değildir ancak uygulamanın yüklenebilmesi için Chromium'un mini bilgi çubuğunun tetiklenmesi yeterlidir.

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

Mobille uyumlu hale getirme

Uygulama artık yüklenebilir olduğuna göre, bir sonraki adım uygulamanın işletim sistemi uygulamalarıyla mümkün olduğunca uyumlu hale gelmesini sağlamaktır. Mobilde bunu yapmak için Web Uygulaması Manifest'indeki görüntüleme modunu fullscreen olarak ayarlıyorum.

{
  "display": "fullscreen"
}

Kamera deliği olan veya çentikli cihazlarda, içeriğin ekranın tamamını kaplayacak şekilde görüntü alanında ince ayarlamalar yapmak uygulamanın mükemmel görünmesini sağlar.

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

Pixel 6 Pro telefonda tam ekran çalışan Designcember Hesap Makinesi.

Masaüstüyle uyumlu hale getirme

Masaüstünde kullanabileceğim güzel bir özellik var: Pencere Denetimleri Yer Paylaşımı. Bu özellik, içeriği uygulama penceresinin başlık çubuğuna yerleştirmeme olanak tanır. İlk adım, görüntü modu yedek sırasını geçersiz kılmaktır. Böylece, kullanılabilir olduğunda ilk olarak window-controls-overlay kullanmaya çalışır.

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

Böylece başlık çubuğu etkin bir şekilde kaybolur ve içerik, başlık çubuğu yokmuş gibi başlık çubuğu alanına taşınır. Benim fikrim, iskeletli güneş hücresini başlık çubuğuna yukarı, hesap makinesi arayüzünün geri kalanını da uygun şekilde aşağıya taşımak. Bunu titlebar-area-* ortam değişkenlerini kullanan bazı CSS ile yapabilirim. Tüm seçicilerin bir wco sınıfı içerdiğini fark edeceksiniz. Bu sınıf, birkaç paragraf aşağıda belirtilmiştir.

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

Genellikle sürükleme için kullandığım başlık çubuğu mevcut olmadığından, sonraki adımda hangi öğelerin sürüklenebilir olacağına karar vermem gerekiyor. Klasik widget tarzında, (-webkit-)app-region: drag öğesini uygulayarak hesap makinesinin tamamını sürüklenebilir duruma getirebilirim. Düğmeler hariç olmak üzere, (-webkit-)app-region: no-drag tuşu, sürüklemek için kullanılamaz.

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

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

Son adım, uygulamanın, pencere denetimleri yer paylaşımı değişikliklerine duyarlı olmasını sağlamaktır. Gerçek bir progresif geliştirme yaklaşımında, bu özelliğin kodunu sadece tarayıcı desteklediğinde yüklüyorum.

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

Pencere kontrollerinde yer paylaşımlı geometri değişiklikleri olduğunda, uygulamayı mümkün olduğunca doğal görünecek şekilde değiştiriyorum. Kullanıcı pencereyi yeniden boyutlandırdığında etkinlik sık sık tetiklenebileceğinden bu etkinliğin geri döndürülmesi iyi bir fikirdir. Örneğin, wco sınıfını bazı öğelere uyguluyorum. Böylece, yukarıdaki CSS'm devreye giriyor ve tema rengini de değiştiriyorum. navigator.windowControlsOverlay.visible özelliğini kontrol ederek pencere kontrolü yer paylaşımının görünür olup olmadığını belirleyebilirim.

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();

Şimdi tüm bunlar yerine getirildikten sonra, eski tarz Winamp temalarından birine sahip, neredeyse klasik Winamp'e benzeyen bir hesap makinesi widget'ı edindim. Artık hesap makinesini masaüstüme rahatça yerleştirebilirim ve sağ üst köşedeki v ayracı tıklayarak pencere kontrolleri özelliğini etkinleştirebilirim.

Designcember Hesap Makinesi, Pencere Denetimleri Yer Paylaşımı özelliği etkinken bağımsız modda çalışır. Ekranda, hesap makinesi alfabesinde &quot;Google&quot; yazıyor.

Gerçekte çalışan bir güneş hücresi

En büyük gariplikler için tabii ki güneş hücresinin gerçekten çalışmasını sağlamam gerekiyordu. Hesap makinesi yalnızca yeterli ışık olduğunda çalışır. Bunu, JavaScript aracılığıyla kontrol ettiğim bir CSS değişkeni --opacity aracılığıyla ekrandaki rakamların CSS opacity'sini ayarlamak gibi bir model oluşturdum.

:root {
  --opacity: 0.75;
}

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

Hesap makinesinin çalışmasına yetecek kadar ışığı olup olmadığını belirlemek için AmbientLightSensor API'yi kullanıyorum. Bu API'nin kullanılabilmesi için about:flags ürününde #enable-generic-sensor-extra-classes işaretini ayarlamam ve 'ambient-light-sensor' iznini istemem gerekiyordu. Daha önce olduğu gibi, ilgili kodu yalnızca API desteklendiğinde yüklemek için progresif geliştirme kullanıyorum.

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

Yeni bir ölçüm olduğunda sensör, ortam ışığını lux biriminde döndürür. Tipik ışık durumlarının bir değerler tablosuna dayanarak, lüks değerini programla --opacity değişkenine atadığım 0 ile 1 arasında bir değere dönüştürmek için çok basit bir formül buldum.

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

Aşağıdaki videoda, odanın ışığı yeterince iyileştiğinde hesap makinesinin nasıl çalışmaya başladığını görebilirsiniz. İşte oldu: Gerçekten çalışan bir güneş hesap makinesi. Benim eskiden test edilmiş TI-30X SOLAR gerçekten çok yol katetti.

Demografi

Tasarım Cember Hesap Makinesi demosunu oynamayı ve Glitch'teki kaynak koduna göz atmayı unutmayın. (Uygulamayı yüklemek için kendi penceresinde açmanız gerekir. Aşağıdaki yerleşik sürüm mini bilgi çubuğunu tetiklemez.)

Designcember'da mutlu yıllar!