LoginSignup
0
0

最新のNoodlでCanvasを扱う

Posted at

Noodl2.3以降CanvasノードがなくなりNoodlでのCanvasの扱い方が変わっています。
そのためNoodl上でChart.jsを使おうにも、以前紹介したやり方はできなくなくなっています。
調べてみるとScriptノードでDOM要素を作成するというやり方が、
公式のドキュメントに紹介されていましたので、
最新のNoodで通用するCanvasの扱いについてまとめました。

最小限の手順

  • 外部ライブラリを読み込む(必要に応じて)
  • CanvasをScriptノードで追加する
  • Canvasのサイズを変える
  • Chart.jsを使つかう

1. 外部ライブラリを読み込む

以前はScriptノードとScriptDownloaderノードを使用していましたが、
現在はProjectSettings>CustomCode>HeadCode:Editを使います。

Headerにライブラリの読み込みを記述するので、どこかのページを開いた時には
ライブラリが読み込まれていることを前提に記述することができます。

header.png

必要に応じて外部ライブラリをNoodlに読み込みます。

Noodlのフォルダ内にライブラリを置く場合
<script src="./mermaid_10.4.0_mermaid.min.js"></script>
CDNを使う場合
<script src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs"></script>

headerEdit.png

2.ノードの配置

最低限必要なのはGroupノードとScriptノードです

  • Groupノードで描画したい部分を配置します
  • Scriptノードには描画するコード記述します
    nodeEditer.png

3.Scriptノードの記述

Scriptノード例
Script.Inputs = {
    group: 'reference',
}

Script.Signals = {
    didMount() {
        let canvas = document.createElement("canvas");
        const domElement = Script.Inputs.group.getDOMElement()
        const canvasElem = domElement.appendChild(canvas)
        let context = canvasElem.getContext('2d');
        //ここに描画に必要なコードを記述する

    },
    willUnmount() {
        //終了時の処理
    },
}

scriptEdit.png

解説

Scriptノード内ではCanvasエレメントの生成と、生成したエレメントをGroupに配置をしています

入力:Inputs

  • Groupノードの「This」出力を受けるため、Scriptノードの「group:'reference'」で定義します

初期化処理:Script.Signals.didMount()

  • Canvasエレメントを生成します
  • 入力されたgroupのエレメントを取得
  • groupエレメントに先ほど作成したCanvasエレメントを追加
  • Canvasエレメント描画用のContext関数を取得

4. ノードの接続

下記のようにつなぎます
Groupのサイズ変更に追従する場合はGroupからwidth,heightを取得します
Scriptノードの実行はGroupノードがマウントされた時としています

nodeEditer.png


Canvas描画の例1

Group:thie->Script:group
Group:width>Script:width
Group:height>Script:height

Script.Inputs = {
    group: 'reference',
    width: 'number',
    height: 'number'
}

Script.Signals = {
    didMount() {
        let canvas = document.createElement("canvas");
        const domElement = Script.Inputs.group.getDOMElement()

        canvas.width = Math.floor(Script.Inputs.width);
        canvas.height = Math.floor(Script.Inputs.height);
        const canvasElem = domElement.appendChild(canvas)
        let context = canvasElem.getContext('2d');

        // パスをリセット
        context.beginPath();
        //context.rect( 50, 50, 75, 50 );
        context.arc(100, 80, 50, 0 * Math.PI / 180, 360 * Math.PI / 180, false);
        context.fillStyle = "rgba(255,0,0,0.8)";

        context.fill();        // 塗りつぶしを実行
        context.strokeStyle = "purple";        // 線の色
        context.lineWidth = 8;        // 線の太さ
        context.stroke();        // 線を描画
    },
    willUnmount() {
    },
}

canvas.png

Canvas描画の例2

Group:thie->Script:group
Group:width>Script:width
Group:height>Script:height

Scriptノードでベジエ曲線を描く例
// ベジエ曲線の制御点の座標
const startX = 0;
const startY = 0;
const controlX1 = 100;
const controlY1 = 150;
const controlX2 = 200;
const controlY2 = 150;
const endX = 250;
const endY = 50;

let canvas
let ctx;

Script.Inputs = {
    group: 'reference',
    width: 'number',
    height: 'number'
}

Script.Signals = {
    didMount() {
        // キャンバス要素を取得        
        canvas = document.createElement("canvas");
        canvas.width = Math.floor(Script.Inputs.width);
        canvas.height = Math.floor(Script.Inputs.height);
        const canvasElem = Script.Inputs.group.getDOMElement().appendChild(canvas)
        ctx = canvasElem.getContext('2d');

        drawBezierCurve(ctx, startX, startY, controlX1, controlY1, controlX2, controlY2, endX, endY) 

    },
    willUnmount() {
    },
}

Node.OnInit = function () {
    document.body.addEventListener('mousemove', setPosition)
    document.body.addEventListener('mousedown', setPosition)
}

// ベジエ曲線を描く関数
function drawBezierCurve(context, startX, startY, controlX1, controlY1, controlX2, controlY2, endX, endY) {
    context.clearRect(0, 0, Script.Inputs.width, Script.Inputs.height);
    context.beginPath();
    context.moveTo(startX, startY);
    context.bezierCurveTo(controlX1, controlY1, controlX2, controlY2, endX, endY);
    context.stroke();
}

function setPosition(e) {
    Node.Outputs.PointerX = e.clientX
    Node.Outputs.PointerY = e.clientY
        canvas.width = Math.floor(Script.Inputs.width);
        canvas.height = Math.floor(Script.Inputs.height);
    //drawBezierCurve(ctx, startX, startY, controlX1, controlY1, controlX2, controlY2, endX, endY) 
    drawBezierCurve(ctx, startX, startY, controlX1, controlY1, controlX2, controlY2, e.clientX, e.clientY)

}

まとめ

Noodl:Canvasノードを使ってJavascriptライブラリをいろいろと実装する
として紹介していたのですが、Canvasノードがなくなったため、こちらの書き方も若干変わっています。
ライブラリを使用する例も引き続き解説していきます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0