SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

フロントエンジニアのためのTauri 2.0ではじめるRustプログラミング

HTML5+CSS+JavaScriptでWebアプリのプロトタイプを完成させよう!

フロントエンジニアのための「Tauri 2.0」ではじめるRustプログラミング 第4回

  • X ポスト
  • このエントリーをはてなブックマークに追加

1個の矩形や1本のベジェ曲線を描く

 まずは単純に図形を描く実装だけしてみましょう。まだマウスでお絵描きするわけではありません。指定した座標に図形を描くだけです。この連載では、頂点と曲線を繋いで一筆書きするので、ここでは少しサイズのある頂点を矩形で描いてみて、次に曲線をベジェ曲線で描いてみます。

1個の矩形を描く

 輪郭線だけを描く場合は「stroke○○」というメソッドを使います。strokeというのは、絵画において「筆のタッチ」を意味する単語です。<canvas>タグは自由に絵を描画できる矩形領域で3Dも描けますが、今回は2Dを描きます。「context(コンテキスト)」は「文脈」や「状況」を表す単語で、ここでは描画領域の文脈を表すのでしょう。

1個の矩形を描く
1個の矩形を描く
サンプルコード「src」→「main.js」
// TAURI
const { invoke } = window.__TAURI__.core;
// 変数
let _canvas = document.querySelector('canvas');
let _context = _canvas.getContext('2d');
// 矩形の描画
_context.strokeStyle = 'rgb(0,0,0)';
_context.lineWidth = 10;
_context.strokeRect(200,150,100,100);

サンプルコードの解説

 「invoke」関数はTauriコマンド関数とデータをやり取りするもので、まだ使いません。

 <canvas>タグを「_canvas」変数に取得し、getContext('2d')で二次元の描画領域のコンテキストを取得して「_context」変数に代入します。

 コンテキストの「strokeStyle」プロパティで輪郭線を真っ黒にセットします。

 コンテキストの「lineWidth」プロパティで線の太さを10にセットします。

 コンテキストの「strokeRect」メソッドで(X,Y)=(200,150)から(幅,高さ)=(100,100)の正方形を描きます。

1本のベジェ曲線を描く

 ベジェ曲線のプログラミングを書く前に、ベジェ曲線とはどういうものなのか次の図を見てください。ベジェ曲線は2つの頂点Aと頂点Bを結んだ線分を、コントロールポイントの座標で磁石のように引っ張ったような曲線を描きます。ベジェ曲線も輪郭線である筆なのでstrokeを使います。

ベジェ曲線について
ベジェ曲線について
サンプルコード「src」→「main.js」
// TAURI
const { invoke } = window.__TAURI__.core;
// 変数
let _canvas = document.querySelector('canvas');
let _context = _canvas.getContext('2d');
// ベジェ曲線の描画
_context.strokeStyle = 'rgb(0,0,0)';
_context.lineWidth = 10;
_context.beginPath();
_context.moveTo(100,100);
_context.quadraticCurveTo(300,300,500,100);
_context.stroke();

サンプルコードの解説

 コンテキストの「beginPath」メソッドから線のパス(道筋)を描き始めます。

 コンテキストの「moveTo」メソッドで(X,Y)=(100,100)に頂点の始点の位置をセットします。

 コンテキストの「quadraticCurveTo」メソッドで曲線のコントロールポイント(300,300)と終点(500,100)をセットします。

 コンテキストの「stroke」メソッドで現在のパスの輪郭線を描画します。

お絵描きアプリの開発を始める

 マウスクリックを繰り返したら頂点だけ描画するアプリを作ります。まだ線は描画しません。まず、<canvas>タグにおけるマウスの正確な座標は考慮せずにクリック座標を取得してお絵描きします。後で正確なマウス座標を「getPos」関数で取得します。

マウスクリックで一筆書き

 次のサンプルコードのように追記してプロジェクトをデバッグビルドして実行したら、マウスをクリックしたときに、「_pos」配列にベジェ曲線の情報が入ります。その要素にはコントロールポイント(X1,Y1)、頂点(X1,Y1)、コントロールポイント(X2,Y2)、頂点(X2,Y2),・・・と繰り返されます。ただし、まだコントロールポイントのデータは使わず、頂点(X,Y)しか使いません。

_pos配列の中身

 [コントロールポイントX1,コントロールポイントY1,頂点X1,頂点Y1,コントロールポイントX2,コントロールポイントY2,頂点X2,頂点Y2,・・・]

 _pos配列の要素はコントロールポイント(X,Y)と頂点(X,Y)の4要素を繰り返します。

クリックした地点に矩形を描く
クリックした地点に矩形を描く
サンプルコード「src」→「main.js」
// TAURI
const { invoke } = window.__TAURI__.core;
// 変数
let _canvas = document.querySelector('canvas');
let _context = _canvas.getContext('2d');
let _pos = [];
let _current = 0;

// 全てのDOMが読み込み完了したら
window.addEventListener("DOMContentLoaded", () => {
  // マウスがクリックされたら頂点描画
  _canvas.addEventListener("mousedown", (e) => {
    let pos = getPos(e);
    _pos.push(pos[0],pos[1],pos[0],pos[1]);
	_current = _pos.length/4;
    line();
  });
});
// 図形の描画
function line() {
  _context.clearRect(0,0,_canvas.width,_canvas.height);
  _context.strokeStyle = 'rgb(0,0,0)';
  _context.lineWidth = 10;
  // 1クリックした頂点
  for ( let i = 0; i < _current; i++ ) _context.strokeRect(_pos[i*4+2],_pos[i*4+3],1,1);
}
// マウス座標の取得
function getPos(event) {
  return [event.pageX,event.pageY];
}

サンプルコードの解説

 htmlファイルのDOMが全て読み込み完了したら、マウスダウンをフックします。マウスダウンされたらマウス座標を取得し、_pos配列にコントロールポイントとマウス座標を追加(push)し、_pos配列をもとに複数描く頂点の数を_current変数に取得し、頂点を描きます。

 「line」関数で、<canvas>タグを真っ白にクリアし、頂点の矩形を_pos配列の要素の4分の1の数だけ繰り返して描画(strokeRectメソッド)します。

正確なクリック座標に

 次のサンプルコードのように追記してプロジェクトをデバッグビルドして実行したら、<canvas>タグにおける正確なクリック座標を取得できます。ウィンドウとウィンドウ内のクライアント領域と、<canvas>タグの配置位置を考慮してから、マウス座標との差から正確な座標が得られます。

サンプルコード「src」→「main.js」
(前略)
// マウス座標の取得
function getPos(event) {
  let clickX = event.pageX;
  let clickY = event.pageY;
  // 要素の位置を取得
  let clientRect = _canvas.getBoundingClientRect();
  let positionX = clientRect.left + window.pageXOffset;
  let positionY = clientRect.top + window.pageYOffset;
  // 要素内におけるクリック位置を計算
  let x = clickX - positionX;
  let y = clickY - positionY;

  return [x,y];
}

サンプルコードの解説

 単純にマウス座標(clickX,clickY)を取得します。

 <canvas>タグのクライアント領域をclientRect変数に取得します。

 ウィンドウの位置から考慮して<canvas>タグの左上の(positionX,positionY)を取得します。

 <canvas>タグにおけるマウス座標(x,y)を取得します。

 配列にした[x,y]をgetPos関数の戻り値として返します。

次のページ
線分を繋ぐ

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
フロントエンジニアのためのTauri 2.0ではじめるRustプログラミング連載記事一覧

もっと読む

この記事の著者

大西 武(オオニシ タケシ)

 1975年香川県生まれ。大阪大学経済学部経営学科中退。プログラミング入門書などを30冊以上商業出版する作家。ドコモでグランプリなどコンテストに20回以上入賞するアーティスト。オリジナルの間違い探し「3Dクイズ」がTVで約10回出題。プロフィールサイト:https://profile.vixar.jp

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

CodeZine編集部(コードジンヘンシュウブ)

CodeZineは、株式会社翔泳社が運営するソフトウェア開発者向けのWebメディアです。「デベロッパーの成長と課題解決に貢献するメディア」をコンセプトに、現場で役立つ最新情報を日々お届けします。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/20767 2025/02/12 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング