Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fonts: DEMOS #1216

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions demos/fonts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Fonts

## all.html

The full `vexflow.js` includes the following music engraving fonts: Bravura, Petaluma, Gonville, and Custom. In this case, `Vex.Flow.setMusicFont('Bravura', ...);` is a synchronous function that changes the current font stack.

## core.html

These files depends on `vexflow-core.js` and the individual font JS files:

```
vexflow-font-bravura.js
vexflow-font-gonville.js
vexflow-font-petaluma.js
vexflow-font-custom.js
```

`core.html` uses the await keyword to call an async function that returns once the requested font is successfully loaded:

```
await Vex.Flow.setMusicFont('Petaluma');`
```

## core-with-promise.html

The async `Vex.Flow.setMusicFont(...)` returns a Promise. This demo shows how to use a `.then(onFulfilledCallback)` to request a font stack, and initialize VexFlow once the fonts are ready.
76 changes: 76 additions & 0 deletions demos/fonts/all.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<!DOCTYPE html>
<html>
<body>
<div id="outputBravura"></div>
<div id="outputGonville"></div>
<div id="outputPetaluma"></div>
<!-- The standard vexflow build includes three music fonts. -->
<script src="../../build/vexflow.js"></script>
<script type="module">
console.log('VexFlow BUILD ' + Vex.Flow.BUILD);

////////////////////////////////////////////////////////////////////////
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a huge fan of this big comment line :-)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. Will remove. Sometimes I put in these "horizontal separators" to help guide the code reader between large code blocks, but here I have extra braces { } anyways, so they're probably not needed.


{
Vex.Flow.setMusicFont('Bravura');
const factory = new Vex.Flow.Factory({
renderer: { elementId: 'outputBravura', width: 500, height: 130 },
});
const score = factory.EasyScore();
factory
.System()
.addStave({
voices: [
score.voice(score.notes('C#5/q, B4, A4, G#4', { stem: 'up' })),
score.voice(score.notes('C#4/h, C#4', { stem: 'down' })),
],
})
.addClef('treble')
.addTimeSignature('4/4');
factory.draw();
}

////////////////////////////////////////////////////////////////////////

{
Vex.Flow.setMusicFont('Gonville');
const factory = new Vex.Flow.Factory({
renderer: { elementId: 'outputGonville', width: 500, height: 130 },
});
const score = factory.EasyScore();
factory
.System()
.addStave({
voices: [
score.voice(score.notes('C#5/q, B4, A4, G#4', { stem: 'up' })),
score.voice(score.notes('C#4/h, C#4', { stem: 'down' })),
],
})
.addClef('treble')
.addTimeSignature('4/4');
factory.draw();
}

////////////////////////////////////////////////////////////////////////

{
Vex.Flow.setMusicFont('Petaluma');
const factory = new Vex.Flow.Factory({
renderer: { elementId: 'outputPetaluma', width: 500, height: 130 },
});
const score = factory.EasyScore();
factory
.System()
.addStave({
voices: [
score.voice(score.notes('C#5/q, B4, A4, G#4', { stem: 'up' })),
score.voice(score.notes('C#4/h, C#4', { stem: 'down' })),
],
})
.addClef('treble')
.addTimeSignature('4/4');
factory.draw();
}
</script>
</body>
</html>
38 changes: 38 additions & 0 deletions demos/fonts/core-with-promise.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<!--
Instead of async/await, you can use Promise style chains.
For example: Vex.Flow.setMusicFont(...).then(onFulfilledCallback)
-->
<html>
<body>
<div id="output"></div>
<!-- The vexflow core build includes no music fonts. -->
<script src="../../build/vexflow-core.js"></script>
<script>
// Vex.Flow.setMusicFont(...fontNames) is an async function that triggers
// the loading of the fonts (stored in vexflow-font-xxxx.js).
// It returns a Promise that resolves to the loaded music font(s).
Vex.Flow.setMusicFont('Petaluma', 'Bravura', 'Gonville', 'Custom').then(onFontsLoaded);

function onFontsLoaded(musicFonts) {
console.log('Successfully loaded this music font stack:');
const [bravura, gonville, petaluma, custom] = musicFonts;
console.log(bravura, gonville, petaluma, custom);

const factory = new Vex.Flow.Factory({ renderer: { elementId: 'output', width: 500, height: 200 } });
const score = factory.EasyScore();
const system = factory.System();
system
.addStave({
voices: [
score.voice(score.notes('C#5/q, B4, A4, G#4', { stem: 'up' })),
score.voice(score.notes('C#4/h, C#4', { stem: 'down' })),
],
})
.addClef('treble')
.addTimeSignature('4/4');
factory.draw();
}
</script>
</body>
</html>
65 changes: 65 additions & 0 deletions demos/fonts/core.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<!DOCTYPE html>
<html>
<!--
Use async/await to load fonts dynamically.
For example: await Vex.Flow.setMusicFont('Bravura')
Open the developer console to verify that only vexflow-core.js is loaded when this page is first shown.
-->
<head>
<meta charset="UTF-8" />
<style>
html {
font: 16px 'Helvetica Neue', Arial, sans-serif;
}
body {
margin: 20px;
}
</style>
</head>
<body>
<p>Choose one of the fonts below:</p>
<div>
<a href="#" onclick="chooseFont('Bravura')">Bravura</a> &nbsp;
<a href="#" onclick="chooseFont('Gonville')">Gonville</a> &nbsp;
<a href="#" onclick="chooseFont('Petaluma')">Petaluma</a> &nbsp;
</div>
<div id="output"></div>
<!-- The vexflow core build includes no music fonts. -->
<script src="../../build/vexflow-core.js"></script>
<script type="module">
async function chooseFont(fontName) {
const container = document.getElementById('output');
while (container.firstChild) {
container.removeChild(container.firstChild);
}

// Vex.Flow.setMusicFont(fontName) is an async function that triggers
// the loading of the font stored in vexflow-font-${fontName}.js.
// Choose between:
// await Vex.Flow.setMusicFont('Bravura')
// await Vex.Flow.setMusicFont('Gonville')
// await Vex.Flow.setMusicFont('Petaluma')
await Vex.Flow.setMusicFont(fontName);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For vexflow-core.js, Flow.setMusicFont(fontName) is async. So you'll have to use await to make sure the font is loaded before proceeding to render the score.


renderScore();
}

function renderScore() {
const factory = new Vex.Flow.Factory({ renderer: { elementId: 'output', width: 500, height: 200 } });
const score = factory.EasyScore();
const system = factory.System();
system
.addStave({
voices: [
score.voice(score.notes('C#5/q, B4, A4, G#4', { stem: 'up' })),
score.voice(score.notes('C#4/h, C#4', { stem: 'down' })),
],
})
.addClef('treble')
.addTimeSignature('4/4');
factory.draw();
}
window.chooseFont = chooseFont;
</script>
</body>
</html>
26 changes: 26 additions & 0 deletions demos/fonts/with-bravura.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!DOCTYPE html>
<!--
vexflow-core-with-bravura.js bundles the Bravura music font.
There is no need to call Vex.Flow.setMusicFont(...).
-->
<html>
<body>
<div id="output"></div>
<script src="../../build/vexflow-core-with-bravura.js"></script>
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are new! Simon of OSMD requested support for smaller builds without undesired fonts.

vexflow-core.js bundles zero fonts. Load fonts at runtime by calling Flow.setMusicFont(...fontNames).

vexflow-core-with-bravura.js bundles only the Bravura font by default. Other fonts can be dynamically loaded with a call to Flow.setMusicFont(...fontNames).

<script type="module">
const factory = new Vex.Flow.Factory({ renderer: { elementId: 'output', width: 500, height: 200 } });
const score = factory.EasyScore();
const system = factory.System();
system
.addStave({
voices: [
score.voice(score.notes('C#5/q, B4, A4, G#4', { stem: 'up' })),
score.voice(score.notes('C#4/h, C#4', { stem: 'down' })),
],
})
.addClef('treble')
.addTimeSignature('4/4');
factory.draw();
</script>
</body>
</html>
26 changes: 26 additions & 0 deletions demos/fonts/with-gonville.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!DOCTYPE html>
<!--
vexflow-core-with-gonville.js bundles the Gonville music font.
There is no need to call Vex.Flow.setMusicFont(...).
-->
<html>
<body>
<div id="output"></div>
<script src="../../build/vexflow-core-with-gonville.js"></script>
<script type="module">
const factory = new Vex.Flow.Factory({ renderer: { elementId: 'output', width: 500, height: 200 } });
const score = factory.EasyScore();
const system = factory.System();
system
.addStave({
voices: [
score.voice(score.notes('C#5/q, B4, A4, G#4', { stem: 'up' })),
score.voice(score.notes('C#4/h, C#4', { stem: 'down' })),
],
})
.addClef('treble')
.addTimeSignature('4/4');
factory.draw();
</script>
</body>
</html>
26 changes: 26 additions & 0 deletions demos/fonts/with-petaluma.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!DOCTYPE html>
<!--
vexflow-core-with-petaluma.js bundles the Petaluma music font.
There is no need to call Vex.Flow.setMusicFont(...).
-->
<html>
<body>
<div id="output"></div>
<script src="../../build/vexflow-core-with-petaluma.js"></script>
<script type="module">
const factory = new Vex.Flow.Factory({ renderer: { elementId: 'output', width: 500, height: 200 } });
const score = factory.EasyScore();
const system = factory.System();
system
.addStave({
voices: [
score.voice(score.notes('C#5/q, B4, A4, G#4', { stem: 'up' })),
score.voice(score.notes('C#4/h, C#4', { stem: 'down' })),
],
})
.addClef('treble')
.addTimeSignature('4/4');
factory.draw();
</script>
</body>
</html>
3 changes: 2 additions & 1 deletion demos/node/canvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@

const { createCanvas } = require('canvas');
const Vex = require('../../build/vexflow-debug');

const VF = Vex.Flow;

const canvas = createCanvas(500, 500);

const renderer = new VF.Renderer(canvas, VF.Renderer.Backends.CANVAS);
const context = renderer.getContext();
context.setFont('Arial', 10, '').setBackgroundFillStyle('#eed');
context.setFont('Arial', 10).setBackgroundFillStyle('#eed');

const stave = new VF.Stave(10, 40, 400);
stave.addClef('treble');
Expand Down
18 changes: 8 additions & 10 deletions demos/node/customcontext.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@

/* eslint-disable no-console */

const { createCanvas } = require('canvas');
const Vex = require('../../build/vexflow-debug');

const VF = Vex.Flow;

// A custom Vex.Flow.RenderContext implementation.
// This is just a stub for demonstration purposes that console.logs all method
// calls and arguments.
// This is just a stub for demonstration purposes that console.logs method calls and arguments.
class CustomContext extends VF.RenderContext {
constructor() {
super();
this.font = '';
this.fillStyle = '';
this.strokeStyle = '';
}
Expand All @@ -30,14 +28,14 @@ class CustomContext extends VF.RenderContext {
this.log('clear');
}

setFont(family, size, weight = '') {
this.log('setFont', family, size, weight);
setFont(f, sz, wt, st) {
this.log('setFont', f, sz, wt, st);
return this;
}

setRawFont(font) {
this.log('setRawFont', font);
return this;
getFont() {
this.log(`getFont() => '10pt Arial'`);
return '10pt Arial';
}

setFillStyle(style) {
Expand Down Expand Up @@ -185,7 +183,7 @@ class CustomContext extends VF.RenderContext {

const renderer = new VF.Renderer(new CustomContext());
const context = renderer.getContext();
context.setFont('Arial', 10, '').setBackgroundFillStyle('#eed');
context.setFont('Arial', 10).setBackgroundFillStyle('#eed');

const stave = new VF.Stave(10, 40, 400);
stave.addClef('treble');
Expand Down
Loading