progress-ring-componentの使い方

## はじめに
以前に作成したアニメーション付きWeb Component、[progress-ring-component](https://github.com/taisuke-j/progress-ring-component)の使い方についての説明です。

https://github.com/taisuke-j/progress-ring-component

## どんなコンポーネントなのか
**progress-ring-component**は[Stencil](https://stenciljs.com/)でビルドされたアニメーション付きのリング状の[Web Component](https://developer.mozilla.org/ja/docs/Web/API/Web_components)。指定されたパーセント値に達するまでスムーズに形状が変化します。また色や大きさ、太さなど自由にカスタマイズする事ができ、ダッシュボード等のUIに便利かと思います。内部で[easing-animation-frames](https://www.npmjs.com/package/easing-animation-frames)という軽量のアニメーションライブラリを使用していて、コンポーネント自体も軽量です。

CDNのjsファイルを`<head>`に読み込ませ、あとはhtmlファイル内で`<progress-ring-component>`タグを記述するだけOKです。React等のプロジェクト内でも使用可能です（後に説明）。

## 使用例 1

まずはシンプルな使用例です。

```html
<progress-ring percentage="30"></progress-ring>
<progress-ring percentage="60" round-linecap="true"></progress-ring>
<progress-ring percentage="90" disable-digits="true">
  <p class="completed-count">9/10<br />Complete</p>
</progress-ring>
```

![demo-1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674308/f22bc8c6-5d7d-7bcc-ef2f-45f65a5c4d83.gif)

[デモ1](https://unpkg.com/progress-ring-component@1.0.36/demo/demo-01.html)

## 使用例 2

次にクリックイベントを含んだ例です。

```html
<progress-ring percentage="10"></progress-ring>

<div class="buttons">
  <button id="buttonOne">30%</button>
  <button id="buttonTwo">60%</button>
  <button id="buttonThree">90%</button>
</div>

<script>
  const ring = document.querySelector("progress-ring");
  const buttonOne = document.querySelector("#buttonOne");
  const buttonTwo = document.querySelector("#buttonTwo");
  const buttonThree = document.querySelector("#buttonThree");

  buttonOne.addEventListener("click", () => {
    ring.setAttribute("percentage", 30);
  });
  buttonTwo.addEventListener("click", () => {
    ring.setAttribute("percentage", 60);
  });
  buttonThree.addEventListener("click", () => {
    ring.setAttribute("percentage", 90);
  });
</script>
```

![demo-2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674308/b12d150e-0df6-c963-ccdf-bf2ecc2b9e8e.gif)

[デモ2](https://unpkg.com/progress-ring-component@1.0.36/demo/demo-02.html)

## 使用例 3

アニメーション終了後にコールバック関数を呼び出すなども可能です（実装はデモのソースコードを見て頂ければと）。

![demo-3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674308/db4f208e-cfe4-174f-5a67-894974f19b4f.gif)

[デモ3](https://unpkg.com/progress-ring-component@1.0.36/demo/demo-03.html)

## プロパティの説明

必須のプロパティは`percentage`のみで、その他は値を指定しない場合はデフォルト値が使用されます。

| プロパティ名        | 説明                                         |
| ---------------- | ------------------------------------------- |
| percentage       | パーセント値（必須） |
| radius           | リングの半径（デフォルトは`80`）|
| stroke-width     | リングの太さ（デフォルトは`10`）|
| round-linecap    | ラインキャップ（線端）を丸くするか（デフォルトは`false`）|
| duration         | アニメーションのms時間（デフォルトは`4000`）|
| easing-type      | アニメーションのイージング（デフォルトは`quartInOut`）|
| int-size         | 整数値のフォントサイズ（デフォルトは`30`）|
| decimal-size     | 小数点以下のフォントサイズ（デフォルトは`intSize * 0.7`）|
| disable-digits   | パーセント値を非表示にする（デフォルトは`false`）|
| disable-decimals | 小数点以下を非表示にする（デフォルトは`false`）|
| colors           | パーセント値とリングの色（デフォルトは`'[[0,"#ff4f40"],[25, "#ffcd40"],[50, "#66a0ff"],[75, "#30bf7a"]]'`）|
| invert-colors    | 逆パターンの色を使用するか（デフォルトは`false`）|
| event-id         | コールバック関数で使用するイベントID（デフォルトは`undefined`）|

## セットアップ方法

htmlファイルの`<head>` タグ内に `<script type="module" src="https://unpkg.com/progress-ring-component/dist/progressring/progressring.esm.js"></script>`を指定。

```html
<!DOCTYPE html>
<html>
  <head>
    <script
      type="module"
      src="https://unpkg.com/progress-ring-component@1.0.36/dist/progressring/progressring.esm.js"
    ></script>
  </head>
  <body>
    <progress-ring percentage="50"></progress-ring>
  </body>
</html>
```

Typescriptを使用している場合は型定義の追加が必要な場合があります。以下、Reactコンポーネントの例です。
```tsx
// App.tsx

import { JSX as LocalJSX } from "progress-ring-component/loader";
import { HTMLAttributes } from "react";

type StencilToReact<T> = {
  [P in keyof T]?: T[P] &
    Omit<HTMLAttributes<Element>, "className"> & {
      class?: string;
    };
};

declare global {
  export namespace JSX {
    interface IntrinsicElements
      extends StencilToReact<LocalJSX.IntrinsicElements> {}
  }
}

function App() {
  return (
    <div>
      <progress-ring percentage={30}></progress-ring>
    </div>
  );
}

export default App;
```

## まとめ

シンプルで使いやすいコンポーネントだと思います。もし使用されることがあればフィードバックを頂けると幸いです。