Create.jsでCanvas描画可能なライブラリをBitmapオブジェクトとして利用する

BitmapクラスはCanvasエレメントを参照できる

CreateJSの公式ドキュメントを参照すると、Bitmapクラスのコンストラクター引数は

Bitmap ( imageOrUri ) Defined in Bitmap:38

Parameters: imageOrUri CanvasImageSource | String | Object The source image to display. This can be a CanvasImageSource (image, video, canvas), an object with a getImage method that returns a CanvasImageSource, or a string URL to an image. If the latter, a new Image instance with the URL as its src will be used.

となっており、Canvasエレメント自体がコンストラクターに渡せることがわかります。

Canvasエレメントに描画した結果をCreate.jsで表示する

これを利用することで、Canvasに結果を描画するタイプのライブラリをCreate.jsの一部として取り込むことができます。

例として、Chart.jsの出力結果をCreate.jsのBitmapインスタンスとして使用してみます。

const chartCanvas = document.createElement("canvas");
chartCanvas.width = w;
chartCanvas.height = h;
const canvasContext = chartCanvas.getContext("2d");

const chartBitmap = new createjs.Bitmap(chartCanvas);

//ここでChart.js用のChart.ChartConfigurationオプションデータを生成する。

let chart = new Chart(canvasContext, options);

stage.add( chartBitmap );

というような感じで、オフスクリーンのcanvasエレメントを生成、コンテクストを取得、コンテクストとチャートオプションを渡してChartを初期化、という手順を踏むとCreate.jsのDisplayObjectとしてChart.jsの出力結果を利用できます。

Retinaディスプレイなど高DPI環境での問題

Chart.jsでは、Retinaディスプレイなど高DPI環境を判定してCanvasサイズを変更する処理を行っています。この処理が、Chart.jsをCreate.jsのBitmapインスタンスとして利用する際に問題となります。

Create.jsは動作環境での解像度を判定しません。そのためBitmapインスタンス化したChart.jsのチャートだけが倍のサイズになって表示されてしまいます。

Chart.jsではChart.helpers.retinaScaleという関数で高DPI環境の判定と処理を行っています。この関数を上書きしてしまうことでこの問題を解消できます。

var originalRetinaScale = Chart.helpers.retinaScale;

Chart.helpers.retinaScale = function(chart) {

    if( !chart.options.responsive && !chart.options.maintainAspectRatio )
    {
        return;
    }
    originalRetinaScale( chart );
};

上記の例ではresponsiveとmaintainAspectRatioの両方のオプションをfalseにした場合は、retinaScale関数の処理をスキップし、それ以外はオリジナルのretinaScale関数を実行するというものです。オプション指定のないチャートはスケーリング処理が行われるので、html側のチャートとCreate.js側のチャートが共存できます。