Flash / silvervilleグラフィックエディターは、インターネット上では珍しくありません。 キャンバス上では、それらの数ははるかに少ないですが、非常に興味深いものもあります。 次に例を示します。 このシリーズの記事では、キャンバス上でグラフィカルエディターを作成するときに遭遇する可能性のあるさまざまなポイントについて説明する予定です。 些細な部分には触れず、最も興味深い部分だけを説明しようとします。 この記事では、スケッチ用のブラシを作成するための近似アルゴリズムについて説明します
それでは、どこから始めますか? 最初に、キャンバスを内部に持つ単純なファイルを作成します。 アルゴリズム自体が可能な限り透過的になるように、不要なフレームワークなどを使用せずに、できるだけコンパクトに記述しようとします。 スケッチ用のブラシを作成するクリーンなファイルを次に示します。
<! DOCTYPE html >
< html >
< head >
< title ></ title >
< meta http-equiv ="Content-Type" content ="text/html; charset=UTF-8" >
< style type ="text/css" >
body {
margin: 0;
}
#cnvs {
border: #000000 1px solid;
}
</ style >
</ head >
< body >
< canvas id ="cnvs" width ="800" height ="500" ></ canvas >
</ body >
</ html >
* This source code was highlighted with Source Code Highlighter .
キャンバスは、画面上のカーソルの座標がキャンバス上のピクセルの座標と一致するように、意図的に左上隅に配置されています(コードの純度のために境界線の1ピクセルの誤差は無視されますが、それについては知っており、覚えています)。
描画メカニズムを作成するには、標準のマウスイベント(onmousedown、onmouseup、onmousemove)のハンドラーがいくつか必要です。 それぞれの関数を作成します。
function mDown(e){
};
function mUp(e){
};
function mMove(e){
};
* This source code was highlighted with Source Code Highlighter .
また、いくつかの変数が必要です:アクションでは、マウスの左ボタンの現在の状態(押されたかどうか)を、ctx-キャンバスに描画するための2dコンテキスト、points-ポイントを格納する配列、pointer-この配列の要素の1つへのポインタに格納します。
それでは、アルゴリズムは何ですか? 友人がスケッチを描く方法を観察した後、私は将来のブラシのメカニズムをほぼ想像しました。 このようなブラシを作成するために考慮する必要がある主なポイント:スケッチはストロークで描かれ、ブラシは弱くなければなりません(友人は鉛筆を優しく押しますが、1箇所を数回塗りますので、線は前後にさまざまな尻尾で毛並みになります)、線は曲げで広くなります。
私のアルゴリズムのバージョンは次のとおりです。
- マウスの後に、鉛筆のように通常の線を引きます
- さらに、現在のポイントをいくつかの長く描かれたポイントに接続します(これにより、ベンドに厚さが与えられます)
- これはすべて、ランダム性の小さな要素(毛皮)である必要があります
- ブラシは部分的に透明になります(低強度)
わかりやすくするために、最初と2番目の段落を図に示します。

したがって、ポイント配列には、最後の10ポイントの座標を格納します(10番を選択しました。これを試すことができます)。 透明度を使用して強度を下げます(0.1に設定します-これは、ブラシが90%透明になることを意味します)。 変数を宣言してキャンバスにアクセスするためのコードは次のとおりです。
var action = "up" ;
var ctx,points,pointer;
function initcnvs(){
ctx = document .getElementById( 'cnvs' ).getContext( '2d' );
ctx.globalAlpha = 0.1;
points = new Array(10);
};
* This source code was highlighted with Source Code Highlighter .
ボディのオンロードでinitcnvs()関数を呼び出します。 関連イベントの他の機能:
< body onload ="initcnvs()" onmousedown ="mDown(event)" onmousemove ="mMove(event)" onmouseup ="mUp(event)" >
* This source code was highlighted with Source Code Highlighter .
最後に、アルゴリズム自体。 ボタンをクリックすると、アクションがdownに変更され、配列の最初のポイントがスローされ、ポインターが設定されます。
function mDown(e){
action = "down" ;
points[0] = [e.pageX, e.pageY];
pointer = 0;
};
* This source code was highlighted with Source Code Highlighter .
ボタンを離すと、配列がクリアされ、アクションがupに変更されます。
function mUp(e){
points = new Array(10);
action = "up" ;
};
* This source code was highlighted with Source Code Highlighter .
最後に、移動するとき(マウスが固定されている場合のみ)、配列内に新しいポイントを定義します(最後まで到達したら、最初から開始します)。 次に、前のポイントを新しいカーソル座標に接続する通常のセグメントを描画し、配列が既にいっぱいになっている場合、現在のカーソル位置を配列の最も古いポイントに接続し、ランダムハウスに5ピクセルのエラーを追加します。 最後に、新しい座標を配列に保存します。
function mMove(e){
if (action == "down" ) {
var nextpoint = pointer + 1;
if (nextpoint > 9) nextpoint = 0;
ctx.beginPath();
ctx.moveTo(points[pointer][0],points[pointer][1]);
ctx.lineTo(e.pageX, e.pageY);
if (points[nextpoint]) {
ctx.moveTo(points[nextpoint][0] + Math.round(Math.random()*10-5),points[nextpoint][1] + Math.round(Math.random()*10-5));
ctx.lineTo(e.pageX, e.pageY);
}
ctx.stroke();
pointer = nextpoint;
points[pointer] = [e.pageX, e.pageY];
}
};
* This source code was highlighted with Source Code Highlighter .
このブラシの動きは次のとおりです。

パラメータ、ランダム性、強度を試して、結果を見ることができます。 これは全体の例のソースコードで、非常にコンパクトに作成されています。
<! DOCTYPE html >
< html >
< head >
< title ></ title >
< meta http-equiv ="Content-Type" content ="text/html; charset=UTF-8" >
< style type ="text/css" >
body {
margin: 0;
}
#cnvs {
border: #000000 1px solid;
}
</ style >
< script type ="text/javascript" >
var action = "up" ;
var ctx,points,pointer;
function initcnvs(){
ctx = document .getElementById( 'cnvs' ).getContext( '2d' );
ctx.globalAlpha = 0.1;
points = new Array(10);
};
function mDown(e){
action = "down" ;
points[0] = [e.pageX, e.pageY];
pointer = 0;
};
function mUp(e){
points = new Array(10);
action = "up" ;
};
function mMove(e){
if (action == "down" ) {
var nextpoint = pointer + 1;
if (nextpoint > 9) nextpoint = 0;
ctx.beginPath();
ctx.moveTo(points[pointer][0],points[pointer][1]);
ctx.lineTo(e.pageX, e.pageY);
if (points[nextpoint]) {
ctx.moveTo(points[nextpoint][0] + Math.round(Math.random()*10-5),points[nextpoint][1] + Math.round(Math.random()*10-5));
ctx.lineTo(e.pageX, e.pageY);
}
ctx.stroke();
pointer = nextpoint;
points[pointer] = [e.pageX, e.pageY];
}
};
</ script >
</ head >
< body onload ="initcnvs()" onmousedown ="mDown(event)" onmousemove ="mMove(event)" onmouseup ="mUp(event)" >
< canvas id ="cnvs" width ="800" height ="500" ></ canvas >
</ body >
</ html >
* This source code was highlighted with Source Code Highlighter .
以上で、この記事がお役に立てば幸いです。 将来的には、スマートハッチング、キャンバスの「キャンセル」ボタン、ぼやけたブラシを使ったトリックなどについて話す予定です。 また、トピックに関する何かに興味がある場合は、コメントを書いてください。これについても説明します。 テキストの誤り-プライベートで、事前に感謝します。
PSこのブラシの私のクレイジーなスキル:
