0xfe / vexflow

A JavaScript library for rendering music notation and guitar tablature.
http://www.vexflow.com
Other
3.87k stars 660 forks source link

Default Styles Strawman #573

Open gristow opened 7 years ago

gristow commented 7 years ago

This is related to #569 -- especially @mscuthbert's and my back and forth on default stave line & ledger line styles. In particular, it's made me realize that many of these things are a matter of taste, and we should allow an easy way to configure them.

I've been working to standardize the api for styling elements across the codebase and many (most) elements now implement setStyle(styleObject) and getStyle().

I'm exploring adding the static methods setDefaultStyle(styleObject) and getDefaultStyle() on elements, which would allow things like:

const VF = Vex.Flow;
VF.Stave.setDefaultStyle({ strokeStyle: '#000000' });
VF.StaveNote.setDefaultFlagStyle({ fillStyle: 'orange' });

const note = new VF.StaveNote({ keys: ['c/4'], duration: '8' })
  .setStyle({ shadowColor: 'blue', shadowBlur: 15 });
  .setKeyStyle(0, { fillStyle: 'purple' }
...
note.setContext(ctx).draw(); // draws a purple note with an orange flag on a blue shadow

I've got this implemented on a branch for StaveNote, Stave, NoteHead, Stem and Beam but before I go much further I wanted to check in and see if this seems like a logical API structure to everyone?

Here's the working branch: https://github.com/gristow/vexflow/tree/house-styles

0xfe commented 7 years ago

Thanks @gristow. I think it's easy to get messy with this API -- if unchecked we could end up with a whole bunch of setDefault* methods.

Right now we have a few places to put defaults:

For something like this, perhaps it should go into Flow. it would be great if all the stylistic defaults were in one place -- this would not just give users one place to customize things, but also the ability to create themes that can be swapped easily.

Taking this a step further, we could have a new src/theme.js that houses all the stylistic defaults. Thoughts?

gristow commented 7 years ago

Yes, @0xfe, that makes more sense, and seems much cleaner.

The only advantage I see to using setDefaultStyle methods is that we can easily open up that API to include all the supported context styling tricks (shadowColor, shadowBlur, even opacity & other canvas & SVG supported elements, etc...). But: it seems really unlikely a user would by default want these as a basic style, and they could always use the element's setStyle method each time if it were really needed.

For src/theme.js do you imagine it exporting a big configuration object, almost like a JSON file? Along the lines of:

export default {
  stave: {
    color: '#999999',
    thickness: 1,
    ledgerLineColor: '#000000',
    ledgerLineThickness: 1.5,
  },
};
mscuthbert commented 7 years ago

this last way would make importing the <defaults> tag from MusicXML quite easy in the future.

0xfe commented 7 years ago

@gristow Yes, that's kind of how I imagine it.