ブラウザ上でUIを構築する際に、一般的に使われるのがDOMです。しかし、DOMは、要素の数が増えるとパフォーマンスが低下することがあります。また、各DOMノードのステートを管理するのは複雑で、ReactやVueなどのライブラリが利用されます。

今回紹介するKonva.jsは、DOMではなくCanvasを使ってUIを構築・表示します。大量のオブジェクトを表示した際のパフォーマンスの高さに加えて、ドラッグ&ドロップやアニメーションなどの機能も備えています。

Konva.jsとは

Konva.jsは、HTML5 Canvasを使って2Dグラフィックスを描画するためのJavaScriptライブラリです。特に、アニメーションやインタラクティブな要素を持つアプリケーションに適しています。Konva.jsは、DOM要素ではなくCanvasを使用するため、大量のオブジェクトを効率的に描画するのが得意です。

また、Konva.jsは、ReactやVueなどのフレームワークと組み合わせて使用することも可能です。これにより、既存のアプリケーションに簡単に統合できます。

インストール

Konva.jsはnpmからインストールできます。以下のコマンドを実行してください。

npm install konva

または、scriptタグで読み込みも可能です。

<script src="https://unpkg.com/konva@9/konva.min.js"></script>

基本的な使い方

まず、描画するためのコンテナをDOMで用意します。

<div id="container"></div>

そして、Konva.jsを初期化します。

const stage = new Konva.Stage({
  container: "container",
  width: window.innerWidth,
  height: window.innerHeight,
});

このステージに対して、レイヤーを追加します。

const layer = new Konva.Layer();
stage.add(layer);

レイヤーの上に、ボックスを描画します。

const box = new Konva.Rect({
  x: 50,
  y: 50,
  width: 100,
  height: 50,
  fill: "#00D2FF",
  stroke: "black",
  strokeWidth: 4,
  draggable: true,
});
layer.add(box);

さらに、ボックスに対してマウスイベントを追加します。

box.on("mouseover", function () {
  box.fill("#FF00D2");
});
box.on("mouseout", function () {
  box.fill("#00D2FF");
});
box.on("click", function () {
  alert("Box clicked!");
});

これで、Canvas上にボックスを表示して、マウスオーバーで色が変わり、クリックでアラートを出すと言った動作が実現できます。

詳しい使い方

ここからは、Konva.jsの詳細な使い方を紹介します。

描画できるオブジェクト

Konva.jsでは、以下のようなオブジェクトを描画できます。

  • 円弧
  • 矢印
  • カスタムシェイプ(多角形など)
  • 楕円
  • オブジェクトのグルーピング
  • 画像
  • テキスト
  • 四角形
  • パス
  • スプライト

テキストも直線に書くだけでなく、曲線に沿って描画するなど細かなカスタマイズが可能です。

描画

オブジェクトの中を塗りつぶすような描画にも幾つかのパターンが用意されています。

  • fill:オブジェクトの中を塗りつぶす
  • stroke:オブジェクトの外枠を描画する
  • opacity:透明度を指定する
  • shadow:影をつける
  • blend:ブレンドモードを指定する(背景色に合わせたテキストカラーなど)

アニメーション

Konva.jsでは、イージングや回転などさまざまなアニメーションが用意されています。アニメーションは Konva.Animation クラスを使用して実行します。

const circle = new Konva.Circle({
  x: 50,
  y: window.innerHeight / 2,
  radius: 30,
  fill: "red",
  stroke: "black",
  strokeWidth: 4,
});
layer.add(circle);

const amplitude = 100;
const period = 2000;

const anim = new Konva.Animation(function(frame) {
  circle.x(
    amplitude * Math.sin((frame.time * 2 * Math.PI) / period) +
    window.innerWidth / 2
  );
}, layer);

anim.start();

フィルター

フィルターは画像をぼかしたり、コントラストを変化させたりと、さまざまな効果を与えることができます。Konva.jsでは、以下のフィルターが用意されています。

  • ぼかし
  • 輝度
  • コントラスト
  • エンボス
  • グレースケール
  • ノイズ
  • セピア
  • その他

以下は、ぼかしの例です。

const imageObj = new Image();
// 画像を読み込んだ際のイベント
imageObj.onload = () => {
  // Konva.js向けの画像オブジェクトの作成
  const image = new Konva.Image({
    x: 50,
    y: 50,
    image: imageObj,
    draggable: true,
  });
  // レイヤーに画像を追加
  layer.add(image);

  // 画像にフィルター設定を追加
  image.cache();
  image.filters([Konva.Filters.Blur]);
  image.blurRadius(10);

  // スライダーの作成
  const slider = document.createElement("input");
  slider.type = "range";
  slider.min = "0";
  slider.max = "40";
  slider.value = image.blurRadius(); // 初期値
  slider.style.position = "absolute";
  slider.style.top = "20px";
  slider.style.left = "20px";

  // スライダーのイベントリスナー
  slider.addEventListener("input", (e) => {
    const value = parseInt(e.target.value);
    image.blurRadius(value); // ぼかしに適用
  });

  document.body.appendChild(slider);
};
// 画像のURLを指定して読み込む
imageObj.src = "https://konvajs.org/assets/lion.png";
imageObj.crossOrigin = "anonymous";

デモ

以下は、Konva.jsを使ったデモです。公式サイトでぜひ触ってみてください。

画像エディタ

指定した画像を表示し、そこにオブジェクトやテキストを追加できます。編集が完了したら画像としてダウンロードできます。

Canvas Designer Editor for JavaScript | Konva - JavaScript Canvas 2d Library

コンテクストメニュー

オブジェクトを右クリックした際に、コンテクストメニューを表示するデモです。

How to show a context menu for HTML5 canvas shape? | Konva - JavaScript Canvas 2d Library

動物を当てはめるゲーム

浮かんでいる動物のイラストを、指定された枠にドラッグ&ドロップして当てはめるゲームです。ボット判定などでも同様の仕組みが使われているのを見ることがあります。

Animals on the Beach Game | Konva - JavaScript Canvas 2d Library

100匹のウサギが跳びはねるアニメーション

Konva.jsでは、大量のオブジェクト表示も問題ありません。ここでは、100匹のウサギが跳びはねるアニメーションを実装しています。

Jumping Bunnies Performance Stress Test | Konva - JavaScript Canvas 2d Library

他にも多数のデモが用意されていますので、ぜひ触ってみてください。

他の技術との違い

Canvasを使って表示を行うライブラリは幾つかありますが、Konva.jsは画像やシェイプの表示とアニメーションに特化しているのが特徴です。代表的なライブラリとしては以下のようなものがあります。

PixiJSは、Canvasにも対応していますが、本来はWebGL向けのようです。ゲームやアニメーション作成に強い印象があります。Fabric.jsは、SVGにも対応している点が特徴です。Paper.jsは、ベクターグラフィックスに特化しており、ダイナミックなグラフやデータのビジュアライズが得意です。そして、Two.jsは2Dアニメーションに特化しており、イベントハンドリングは弱い印象です。

Konva.jsは、これらのライブラリと比べて、シンプルなAPIでありながら、アニメーションやインタラクティブな要素を簡単に実装できる点が魅力です。また、ReactやVueなどのフレームワークとの統合も容易で、既存のアプリケーションに組み込みやすいのも利点です。

まとめ

今回はKonva.jsを使って、Canvas上にオブジェクトを描画する方法を紹介しました。Konva.jsは、アニメーションやインタラクティブな要素を簡単に実装できるライブラリであり、大量のオブジェクト表示にも強いです。アプリのUI表示として、検討してみると新しい発見があるかもしれません。

Konva - JavaScript Canvas 2d Library