「VexFlow 描画エリアと5線譜と小節」の版間の差分
(→小節) |
|||
(同じ利用者による、間の14版が非表示) | |||
44行目: | 44行目: | ||
<table style="border: 0; border-collapse: collapse;"> | |||
<tr border="0" style="color: white; background-color:#666666; font-weight: bolder;"> | |||
<td width="300px">動作</td> | |||
<td width="200px">Keyword</td> | |||
<td width="100px">指定値の例</td> | |||
</tr> | |||
<tr> | |||
<td>置き換えするタグのID名</td> | |||
<td>elementId</td> | |||
<td>'VexFlow'</td> | |||
</tr> | |||
</table> | |||
上記の elementId: の後ろの '' シングルクォーテーションで囲われた文字列が置き換え対象のタグID名です。同じIDを持つタグが複数あるとおかしくなるので唯一である必要があります。使われなさそうなID名になるような癖をつけておいた方がよいでしょう。例えば、例では VexFlow ですが、yonet202301_Output00 とかドメイン名+年月+'Output'+通し番号とかね。 | 上記の elementId: の後ろの ' ' シングルクォーテーションで囲われた文字列が置き換え対象のタグID名です。同じIDを持つタグが複数あるとおかしくなるので唯一である必要があります。使われなさそうなID名になるような癖をつけておいた方がよいでしょう。例えば、例では VexFlow ですが、yonet202301_Output00 とかドメイン名+年月+'Output'+通し番号とかね。 | ||
<table style="border: 0; border-collapse: collapse;"> | |||
<tr border="0" style="color: white; background-color:#666666; font-weight: bolder;"> | |||
<td width="300px">動作</td> | |||
<td width="200px">Keyword</td> | |||
<td width="100px">指定値の例</td> | |||
</tr> | |||
<tr> | |||
<td>描画エリア横幅</td> | |||
<td>width</td> | |||
<td>1900</td> | |||
</tr> | |||
<tr style="background-color: #bbbbbb;"> | |||
<td>描画エリア高さ幅</td> | |||
<td>height</td> | |||
<td>195</td> | |||
</tr> | |||
</table> | |||
65行目: | 91行目: | ||
のように宣言します。 | のように宣言します。 | ||
ここまでの説明をまとめたプログラムコードは以下のようになります。まだ何も起こらないコードです。 | |||
<syntaxhighlight lang="javascript"> | |||
<script src="https://cdn.jsdelivr.net/npm/vexflow@4.1.0/build/cjs/vexflow.js"></script>//※1pageで一度だけ記述する行 | |||
<div id="VexFlow"></div> | |||
<script> | |||
(function(){ | |||
const { | |||
Factory, | |||
} = Vex.Flow; | |||
const f = new Factory({ renderer: { elementId: 'VexFlow', width: 1900, height: 195 } }); | |||
})(); | |||
</script> | |||
</syntaxhighlight> | |||
何もおこらないので、上記のコードは実行しないで下さい。時間の無駄です。 | |||
== '''五線譜''' == | |||
上記で土台は出来上がっていることになりますので、少しコードを追加すると五線譜が描けます。 | |||
<div id="yonet202301_Output01"></div> | |||
<yjavascript></script> | |||
<script> | |||
(function(){ | |||
const { | |||
Factory, | |||
Stave, | |||
} = Vex.Flow; | |||
const f = new Factory({ renderer: { elementId: 'yonet202301_Output01', width: 1000, height: 195 } }); | |||
const ctx = f.getContext(); | |||
const stave1 = new Stave(10, 50, 400).setContext(ctx).draw(); | |||
})(); | |||
</yjavascript> | |||
<syntaxhighlight lang="javascript" line start="1"> | |||
<div id="yonet202301_Output01"></div> | |||
<script> | |||
(function(){ | |||
const { | |||
Factory, | |||
Stave, | |||
} = Vex.Flow; | |||
const f = new Factory({ renderer: { elementId: 'yonet202301_Output01', width: 1000, height: 195 } }); | |||
const ctx = f.getContext(); | |||
const stave1 = new Stave(10, 50, 400).setContext(ctx).draw(); | |||
})(); | |||
</script> | |||
</syntaxhighlight> | |||
Stave オブジェクトを利用しますので、4行目の宣言のところに Stave を追加しました。そして、10,11行目を追加しています。最初に作ったFactoryのオブジェクトの格納変数 f のメンバ関数 f.getContext() で描画デバイスコンテキストを取得できます。このコンテキストは先に準備した描画エリアと、これから準備する描画パーツを結び付ける役割を持つ、筆のようなものです。筆を通じて描画の信号が伝わるイメージです。ctx は、デバイスコンテキスト変数と呼んだりすることになります。 | |||
ctxを引数にとるメンバ関数を利用しつつ、Stave オブジェクトを生成しています。その生成時の引数が(10, 50, 400)という謎な数値です。引数の意味ですが、 | |||
*第一引数:横方向の余白px値 10px | |||
*第二引数:縦方向の余白px値 50px | |||
*第三引数:5線譜の横幅px値 400px | |||
という意味です。オブジェクトに同一のオブジェクトが返却される関数になっているので、続けて、ドットを使ってメンバ関数を指定できます。但し順番には意味があります。手前から順番に設定する必要がある場合があります。その意味で .setContext(ctx).draw() という関数が指定されています。前もって作った ctx のデバイスコンテキスト変数を引数にとって描画処理を指示したことになります。 | |||
== '''小節''' == | |||
小節は5線譜を2回描くだけです。 | |||
<div id="yonet202301_Output02"></div> | |||
<yjavascript></script> | |||
<script> | |||
(function(){ | |||
const { | |||
Factory, | |||
Stave, | |||
} = Vex.Flow; | |||
const f = new Factory({ renderer: { elementId: 'yonet202301_Output02', width: 1000, height: 195 } }); | |||
const ctx = f.getContext(); | |||
const stave1 = new Stave(10, 50, 400).setContext(ctx).draw(); | |||
const stave2 = new Stave(410, 50, 400).setContext(ctx).draw(); | |||
})(); | |||
</yjavascript> | |||
<syntaxhighlight lang="javascript" line start="1"> | |||
<div id="yonet202301_Output02"></div> | |||
<script> | |||
(function(){ | |||
const { | |||
Factory, | |||
Stave, | |||
} = Vex.Flow; | |||
const f = new Factory({ renderer: { elementId: 'yonet202301_Output02', width: 1000, height: 195 } }); | |||
const ctx = f.getContext(); | |||
const stave1 = new Stave(10, 50, 400).setContext(ctx).draw(); | |||
const stave2 = new Stave(410, 50, 400).setContext(ctx).draw(); | |||
})(); | |||
</script> | |||
</syntaxhighlight> | |||
12行目を追加しただけです。座標値をちょっと変えてやるだけです。単純に5線譜を二つ並べてるだけです。このページの記事は以上になります。つづけて、もう少し踏み込んだ記事を書く予定です。 | |||
[[VexFlow 使い方]]に戻る。 | [[VexFlow 使い方]]に戻る。 |
2023年2月3日 (金) 00:20時点における最新版
VexFlow 使い方に戻る。
概要
タイトルを5線譜にしようかと思ったのだけれど、その根本にある描画エリアを説明しなければならないのだけど、描画エリアだけを説明するのも内容が少なすぎる。そして、5線譜を繋ぐだけの小節についても説明した方が手っ取り早いと思ったのです。なので「部屋とYシャツと私」みたいなタイトルにしました。その前にコードの書き方を説明しておきます。
コードの書き方
WebSiteに複数の楽譜を掲載することもあると思いますが、VexFlowはコードの中にHTMLタグの任意で指定したIDが付与されているタグに対して、楽譜へ置き換えるように動作します。
つまり、id="VefFlow"を標的とすると置き換えられるのは、
<div id="VexFlow"></div>
のようなHTMLです。これで置き換えられる部分がわかったと思います。次はコード側の標的の設定の仕方を紹介しなければなりませんが、また少しあとで、紹介します。
複数の楽譜を描画する場合は、上記のような異なるIDを持つタグを作成します。コード側では、複数の楽譜で似たような変数を使いますが、重複していたら相互に影響しあってしまいます。そこで、楽譜ごとに関数にすることで変数を隠蔽することができます。ひとつのWebPageでJavaScriptの変数が影響し合うことはないです。そこで便利なのが、以下のような即時実行関数です。
(function(){
//ここにコード
})();
ここにコードと書いてある部分に一つの楽譜についてのコードを記述します。JavaScriptがわかっていないと、こういったアイデアが生まれにくいので、VexFlowを操るのは大変だと思います。自分も初心者程度の知識しかありませんので、少なくとも自分と同じくらいまで学習された方がよろしいでしょう。
この先の説明では即時実行関数の中に記述するということを説明することは、ほとんど無いと思います。以後お見知りおきを。
HTMLタグの置き換えと描画エリア
先に説明したようなHTMLのタグを置き換える指定と、描画エリアの指定は以下のように行います。
const f = new Factory({ renderer: { elementId: 'VexFlow', width: 1900, height: 195 } });
動作 | Keyword | 指定値の例 |
置き換えするタグのID名 | elementId | 'VexFlow' |
上記の elementId: の後ろの ' ' シングルクォーテーションで囲われた文字列が置き換え対象のタグID名です。同じIDを持つタグが複数あるとおかしくなるので唯一である必要があります。使われなさそうなID名になるような癖をつけておいた方がよいでしょう。例えば、例では VexFlow ですが、yonet202301_Output00 とかドメイン名+年月+'Output'+通し番号とかね。
動作 | Keyword | 指定値の例 |
描画エリア横幅 | width | 1900 |
描画エリア高さ幅 | height | 195 |
この命令のように new を使ってオブジェクトを生成する手法を使う場合、VexFlow独自のオブジェクト名である場合は、個別にオブジェクトを使うことを宣言する必要があります。Factoryの場合は
const {
Factory,
} = Vex.Flow;
のように宣言します。
ここまでの説明をまとめたプログラムコードは以下のようになります。まだ何も起こらないコードです。
<script src="https://cdn.jsdelivr.net/npm/vexflow@4.1.0/build/cjs/vexflow.js"></script>//※1pageで一度だけ記述する行
<div id="VexFlow"></div>
<script>
(function(){
const {
Factory,
} = Vex.Flow;
const f = new Factory({ renderer: { elementId: 'VexFlow', width: 1900, height: 195 } });
})();
</script>
何もおこらないので、上記のコードは実行しないで下さい。時間の無駄です。
五線譜
上記で土台は出来上がっていることになりますので、少しコードを追加すると五線譜が描けます。
<div id="yonet202301_Output01"></div>
<script>
(function(){
const {
Factory,
Stave,
} = Vex.Flow;
const f = new Factory({ renderer: { elementId: 'yonet202301_Output01', width: 1000, height: 195 } });
const ctx = f.getContext();
const stave1 = new Stave(10, 50, 400).setContext(ctx).draw();
})();
</script>
Stave オブジェクトを利用しますので、4行目の宣言のところに Stave を追加しました。そして、10,11行目を追加しています。最初に作ったFactoryのオブジェクトの格納変数 f のメンバ関数 f.getContext() で描画デバイスコンテキストを取得できます。このコンテキストは先に準備した描画エリアと、これから準備する描画パーツを結び付ける役割を持つ、筆のようなものです。筆を通じて描画の信号が伝わるイメージです。ctx は、デバイスコンテキスト変数と呼んだりすることになります。
ctxを引数にとるメンバ関数を利用しつつ、Stave オブジェクトを生成しています。その生成時の引数が(10, 50, 400)という謎な数値です。引数の意味ですが、
- 第一引数:横方向の余白px値 10px
- 第二引数:縦方向の余白px値 50px
- 第三引数:5線譜の横幅px値 400px
という意味です。オブジェクトに同一のオブジェクトが返却される関数になっているので、続けて、ドットを使ってメンバ関数を指定できます。但し順番には意味があります。手前から順番に設定する必要がある場合があります。その意味で .setContext(ctx).draw() という関数が指定されています。前もって作った ctx のデバイスコンテキスト変数を引数にとって描画処理を指示したことになります。
小節
小節は5線譜を2回描くだけです。
<div id="yonet202301_Output02"></div>
<script>
(function(){
const {
Factory,
Stave,
} = Vex.Flow;
const f = new Factory({ renderer: { elementId: 'yonet202301_Output02', width: 1000, height: 195 } });
const ctx = f.getContext();
const stave1 = new Stave(10, 50, 400).setContext(ctx).draw();
const stave2 = new Stave(410, 50, 400).setContext(ctx).draw();
})();
</script>
12行目を追加しただけです。座標値をちょっと変えてやるだけです。単純に5線譜を二つ並べてるだけです。このページの記事は以上になります。つづけて、もう少し踏み込んだ記事を書く予定です。
VexFlow 使い方に戻る。