|
@@ -53,16 +53,18 @@ export class StaveNote extends StemmableNote {
|
|
|
|
|
|
// Static rendering method that can be called from
|
|
|
// other classes (e.g. VibratoBracket)
|
|
|
- static renderVibrato(ctx, x, y, opts, y2) {
|
|
|
- const {vibrato_width, wave_width, wave_girth, wave_height } = opts;
|
|
|
- const num_waves = vibrato_width / wave_width;
|
|
|
- const step = Math.abs(y2 - y) / num_waves + 2
|
|
|
+ static renderVibrato(ctx, x, y, opts) {
|
|
|
+ let {width, height, wave_width, wave_girth, wave_height, stem_direction } = opts;
|
|
|
+ const num_waves = Math.floor(width / wave_width);
|
|
|
+ let step = height / (num_waves / 2) * stem_direction
|
|
|
+ if (step == 0){
|
|
|
+ stem_direction = 1
|
|
|
+ step = 0.3
|
|
|
+ }
|
|
|
|
|
|
ctx.beginPath();
|
|
|
-
|
|
|
- let i;
|
|
|
ctx.moveTo(x, y + wave_girth);
|
|
|
- for (i = 0; i < num_waves / 2; ++i) {
|
|
|
+ for (let i = 0; i < num_waves / 2; ++i) {
|
|
|
ctx.quadraticCurveTo(x + (wave_width / 2), y - (wave_height / 2), x + wave_width, y);
|
|
|
x += wave_width;
|
|
|
y += step;
|
|
@@ -70,22 +72,28 @@ export class StaveNote extends StemmableNote {
|
|
|
x += wave_width;
|
|
|
}
|
|
|
|
|
|
- for (i = 0; i < num_waves / 2; ++i) {
|
|
|
- ctx.quadraticCurveTo(
|
|
|
- x - (wave_width / 2),
|
|
|
- (y + (wave_height / 2)) + wave_girth,
|
|
|
- x - wave_width, y + wave_girth);
|
|
|
+ for (let i = 0; i < num_waves / 2; ++i) {
|
|
|
+ ctx.quadraticCurveTo( x - (wave_width / 2), (y + (wave_height / 2)) + wave_girth, x - wave_width, y + wave_girth);
|
|
|
x -= wave_width;
|
|
|
y -= step;
|
|
|
- ctx.quadraticCurveTo(
|
|
|
- x - (wave_width / 2),
|
|
|
- (y - (wave_height / 2)) + wave_girth,
|
|
|
- x - wave_width, y + wave_girth);
|
|
|
+ ctx.quadraticCurveTo( x - (wave_width / 2), (y - (wave_height / 2)) + wave_girth, x - wave_width, y + wave_girth);
|
|
|
x -= wave_width;
|
|
|
}
|
|
|
+ if(stem_direction < 0){
|
|
|
+ ctx.stroke()
|
|
|
+ }
|
|
|
ctx.fill();
|
|
|
}
|
|
|
|
|
|
+ /** 绘制滑音 */
|
|
|
+ static renderSlideNote(ctx, x, y, x1, y1){
|
|
|
+ ctx.beginPath();
|
|
|
+ ctx.moveTo(x, y);
|
|
|
+ ctx.lineTo(x1,y1);
|
|
|
+ ctx.lineWidth = 2
|
|
|
+ ctx.stroke();
|
|
|
+ }
|
|
|
+
|
|
|
// ## Static Methods
|
|
|
//
|
|
|
// Format notes inside a ModifierContext.
|
|
@@ -414,6 +422,8 @@ export class StaveNote extends StemmableNote {
|
|
|
this.octave_shift = noteStruct.octave_shift;
|
|
|
this.beam = null;
|
|
|
this.vibrato = null;
|
|
|
+ this.slideNote = null;
|
|
|
+
|
|
|
|
|
|
// Pull note rendering properties
|
|
|
this.glyph = Flow.getGlyphProps(this.duration, this.noteType);
|
|
@@ -483,6 +493,11 @@ export class StaveNote extends StemmableNote {
|
|
|
this.vibrato = vibrato
|
|
|
}
|
|
|
|
|
|
+ /** 增加滑音 */
|
|
|
+ setSlideNote(slideNote){
|
|
|
+ this.slideNote = slideNote
|
|
|
+ }
|
|
|
+
|
|
|
getCategory() { return StaveNote.CATEGORY; }
|
|
|
|
|
|
// Builds a `Stem` for the note
|
|
@@ -878,9 +893,6 @@ export class StaveNote extends StemmableNote {
|
|
|
}
|
|
|
|
|
|
setKeyLine(index, line) {
|
|
|
- if (this.glyph.code_head == "va5" || this.glyph.code_head == "v3c") {
|
|
|
- line = 3
|
|
|
- }
|
|
|
this.keyProps[index].line = line;
|
|
|
this.reset();
|
|
|
return this;
|
|
@@ -1154,22 +1166,47 @@ export class StaveNote extends StemmableNote {
|
|
|
drawVibrato() {
|
|
|
if (this.vibrato) {
|
|
|
const ctx = this.context;
|
|
|
- ctx.openGroup('vibrato');
|
|
|
const x = this.vibrato.getNoteHeadEndX() + 2
|
|
|
- const { y_top: y } = this.vibrato.getNoteHeadBounds();
|
|
|
- let { y_bottom: y2 } = this.getNoteHeadBounds();
|
|
|
- let width = Math.abs(this.getNoteHeadBeginX() - x) - 10
|
|
|
+ let { y_bottom: y } = this.vibrato.getNoteHeadBounds();
|
|
|
+ let { y_top: y2 } = this.getNoteHeadBounds();
|
|
|
+ const stem_direction = y < y2 ? 1 : -1;
|
|
|
+ let width = Math.abs(this.getNoteHeadBeginX() - 5 - x)
|
|
|
+ let height = Math.abs(y2 - y);
|
|
|
+ if (this.duration === 'w' || this.vibrato.stave.y !== this.stave.y) {
|
|
|
+ width = this.vibrato.stave.getNoteEndX() - 5 - x
|
|
|
+ }
|
|
|
if (this.vibrato.stave.y !== this.stave.y) {
|
|
|
- width = 30
|
|
|
- y2 = y + 10
|
|
|
+ // 不在统一行
|
|
|
+ height = 0
|
|
|
}
|
|
|
+ ctx.openGroup('vibrato');
|
|
|
StaveNote.renderVibrato(this.context, x, y, {
|
|
|
harsh: true,
|
|
|
- vibrato_width: width,
|
|
|
+ width,
|
|
|
+ height,
|
|
|
wave_height: 6,
|
|
|
wave_width: 4,
|
|
|
- wave_girth: 2,
|
|
|
- }, y2)
|
|
|
+ wave_girth: 4,
|
|
|
+ stem_direction
|
|
|
+ })
|
|
|
+ ctx.closeGroup();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 绘制滑音 */
|
|
|
+ drawSlide() {
|
|
|
+ if (this.slideNote) {
|
|
|
+ const ctx = this.context;
|
|
|
+ const x = this.slideNote.getNoteHeadEndX() + 2
|
|
|
+ let {y_bottom: y } = this.slideNote.getNoteHeadBounds();
|
|
|
+ let x1 = this.getNoteHeadBeginX() - 4
|
|
|
+ let { y_top: y1 } = this.getNoteHeadBounds();
|
|
|
+ if (this.duration === 'w' || this.slideNote.stave.y !== this.stave.y) {
|
|
|
+ x1 = this.slideNote.stave.getNoteEndX() - 2
|
|
|
+ }
|
|
|
+ ctx.openGroup('slide');
|
|
|
+ StaveNote.renderSlideNote(ctx, x, y, x1, y1)
|
|
|
ctx.closeGroup();
|
|
|
}
|
|
|
|
|
@@ -1210,6 +1247,7 @@ export class StaveNote extends StemmableNote {
|
|
|
}
|
|
|
ctx.closeGroup();
|
|
|
this.drawVibrato();
|
|
|
+ this.drawSlide();
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1318,7 +1356,15 @@ export class StaveNote extends StemmableNote {
|
|
|
this.note_heads[i].setLine(line + _top)
|
|
|
} else {
|
|
|
if (lines === 2){
|
|
|
- this.note_heads[i].setLine(3)
|
|
|
+ if (this.duration === 'q') {
|
|
|
+ this.note_heads[i].setLine(2)
|
|
|
+ } else if(this.duration === 'w') {
|
|
|
+ this.note_heads[i].setLine(4)
|
|
|
+ } else if (this.duration === 'h') {
|
|
|
+ this.note_heads[i].setLine(2.5)
|
|
|
+ } else {
|
|
|
+ this.note_heads[i].setLine(2)
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|