BlurHash SW

BlurHash SW

npm filesize license standard-readme compliant

The BlurHash API provided by ServiceWorker.

https://github.com/3846masa/blurhash-sw

Table of Contents

Install

Add the following code to your ServiceWorker script.

// sw.js
importScripts('https://unpkg.com/blurhash-sw@1.0.15/dist/index.js');

blurhashSW({
  routeUrl: '/.blurhash/:blurhash',
  width: 32,
  height: 32,
});
<script>
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/sw.js');
  }
</script>

Usage

See also demo page.

The easiest way

Set the BlurHash URL as background-image.

You should encode the BlurHash hash contained in the URL.

<img
  src="https://source.unsplash.com/alY6_OpdwRQ/793x529"
  alt="Shibuya 109"
  width="793"
  height="529"
  style="
    background-size: 100% 100%;
    background-image: url(/.blurhash/LGBEE%2CIr.At8t8IU-%3DR%2BR6R4OrIo);
  "
  loading="lazy"
/>
Shibuya 109

With fade-in transition

Wrap the img element in the div element.

The BlurHash URL should be assigned as background-image of the div element.

<div
  style="
    width: fit-content;
    background-size: 100% 100%;
    background-image: url(/.blurhash/LKF%23tH-psS%2C%3F3%3FoJWVNbIVs.%24*n%24);
  "
>
  <img
    src="https://source.unsplash.com/7H77FWkK_x4/472x512"
    alt="Tokyo tower"
    width="472"
    height="512"
    style="
      opacity: 0;
      transition: ease-out 0.3s opacity;
    "
    onload="this.style.opacity=1"
    loading="lazy"
  />
</div>
Tokyo tower

Using data-blurhash attribute

The BlurHash URL is not available until the ServiceWorker is ready.

Therefore, when visiting the site for the first time, background-image cannot be loaded.

As a workaround, generate background-image based on data-blurhash when the ServiceWorker is ready.

navigator.serviceWorker
  .register('/sw.js')
  .then(() => navigator.serviceWorker.ready)
  .then(() => {
    const $elemList = document.querySelectorAll('[data-blurhash]');
    for (const $elem of $elemList) {
      const blurhash = $elem.dataset.blurhash;
      $elem.style.backgroundSize = `100% 100%`;
      $elem.style.backgroundImage = `url(/.blurhash/${encodeURIComponent(blurhash)})`;
    }
  });
<img
  src="https://source.unsplash.com/HkGaG67usNE/597x398"
  alt="Kinkaku-ji"
  width="597"
  height="398"
  loading="lazy"
  data-blurhash="L%C%zEXANengKnkCj]n$NMjXsoW?"
/>
Kinkaku-ji
<div
  style="
    width: fit-content;
  "
  data-blurhash="LmF~daR+NGWA_4RjRjWBkCadV@W;"
>
  <img
    src="https://source.unsplash.com/wPMvPMD9KBI/262x394"
    alt="Himeji castle"
    width="262"
    height="394"
    style="
      opacity: 0;
      transition: ease-out 0.3s opacity;
    "
    onload="this.style.opacity=1"
    loading="lazy"
  />
</div>
Himeji castle

Contributing

PRs accepted.

License

MIT (c) 3846masa