トラがエシレバターになるWebComponents

![026_mini.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124296/ba54a025-ad2f-1be7-b860-8e7e49e4bc87.gif)

# WebComponentsとは

Web Developer Roadmap でも今年からリスト入りした
コンポーネントを作るための **ブラウザ標準の技術** の総称。

HTML, JS, CSSが一体となった非常に再利用性の高いコンポーネントを作ることができます。

![https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_124296_6e550479-02b5-6cc0-8af0-2aa269233033.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124296/dccac21c-e8ab-6718-3732-2812c14941a7.png)

# オリジナルのHTMLタグを作れるだけじゃない

トラがエシレバターになるコンポーネントは、
いつもみんなが使っている `<img>` タグに `is="my-img"` を指定しただけです。

![スクリーンショット 2020-01-23 21.54.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124296/fb6d5170-1e70-87ba-be86-b25d8726b44a.png)

これがWebComponentsのすごいところで、ただオリジナルのHTMLタグを作るだけじゃなく
**ネイティブの機能を活かして** 独自に拡張（e.g. クリックすると回転してエシレバター）することができます。

````js
customElements.define('my-img', MyImg, { extends: 'img' });
````

実装時に重要なのはこの一行だけで、
継承したいネイティブのタグ `{ extends: 'img' }` を指定して
`customElements.define` にぶちこむだけです。

また、 `is属性` を設定しなければ通常の `<img>` タグを利用することができます。

# ソースコード

````js:my-img.js
import butter from '../assets/butter.png';

/**
 * <img>タグの拡張 - HTMLImageElementを継承
 */
class MyImg extends HTMLImageElement {
  constructor() {
    super();
    this.times = 0;
    this.type = '';
    this.innerHTML = `
      <style>
        :host { display: block; cursor: pointer; }
        .rotate1 { animation: rotate 0.75s linear infinite; }
        .rotate2 { animation-duration: 0.5s; }
        .rotate3 { animation-duration: 0.25s; }
        .rotate4 { animation-duration: 0.125s; }
        .rotate5 { animation-name: none; }
        @keyframes rotate {
          0% { transform: rotate(0deg) translate(-50px) rotate(0deg); }
          100% { transform: rotate(-360deg) translate(-50px)  rotate(360deg); }
        }
      </style>
    `;
    this.addEventListener('click', this.rotate);
  }

  rotate() {
    this.times++;
    this.classList.add(`rotate${this.times}`);

    // バターになる
    if (this.times === 5) {
      this.src = butter;
    }
  }
}

customElements.define('my-img', MyImg, { extends: 'img' });

````

````html:index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <title>WebComponents Sample</title>
  </head>
  <body>
    <h1>トラがエシレバターになるWebComponents</h1>

    <div style="text-align: center; margin: 50px auto;">
      <img src="./assets/tiger.png" alt="トラ" is="my-img" width="240" />
    </div>

    <script src="./my-img.js"></script>
  </body>
</html>
````

トラがエシレバターになるPR:
https://github.com/cc822jp/saturday-hackathon/pull/1/files

# その他こだわった点

普通に回転させるとバター感が薄れてしまうため
半円周上に動くように調整しました。

![demo2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124296/064e9c4d-c6cf-efe6-9983-2ec41e7fa38d.gif)

# 実際の案件に耐えうるのか？

MS Edgeのブラウザエンジンがchromiumに置き換わることで、
全てのメジャーブラウザでpolyfill無しで利用することができます。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">An effort 9 years in the making, but we’ve finally made it.<br><br>WebComponents are supported natively in every major browser <a href="https://t.co/6yPoTXno27">pic.twitter.com/6yPoTXno27</a></p>&mdash; Polymer Project (@polymer) <a href="https://twitter.com/polymer/status/1217578939456970754?ref_src=twsrc%5Etfw">January 15, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

※Googleが推進するPolymer Projectでも歓喜してました
※polyfillを使うことで旧バージョンのEdgeでも利用することはできます。

# まとめ

動画でも解説しているので良ければ見てみてくださいm(__)m

https://youtu.be/RkBrmHKIgik