<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: sustained</title>
    <description>The latest articles on DEV Community by sustained (@sustained).</description>
    <link>https://dev.to/sustained</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F139082%2Fc416728b-dac0-4e8d-b4b8-bd402bec933a.jpeg</url>
      <title>DEV Community: sustained</title>
      <link>https://dev.to/sustained</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sustained"/>
    <language>en</language>
    <item>
      <title>#10DaysofCode - AKA #100DaysofCode for people with focus, drive and commitment issues.</title>
      <dc:creator>sustained</dc:creator>
      <pubDate>Wed, 25 Sep 2019 23:31:44 +0000</pubDate>
      <link>https://dev.to/sustained/10daysofcode-aka-100daysofcode-for-people-with-focus-drive-and-commitment-issues-3hcm</link>
      <guid>https://dev.to/sustained/10daysofcode-aka-100daysofcode-for-people-with-focus-drive-and-commitment-issues-3hcm</guid>
      <description>&lt;h1&gt;
  
  
  Excuse me?
&lt;/h1&gt;

&lt;p&gt;Well 100 days is terrifying, don't you think? I did. That's why I invented a new Twitter hashtag (or maybe it existed all along but who cares).&lt;/p&gt;

&lt;p&gt;It's called #10DaysofCode - AKA #100DaysofCode for people with focus, drive, commitment [etc.] issues. Isn't it marvellous?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Feel free to join me, by the way - I'd be happy to follow along with your 10-day journey if 100 is too big and scary for you as well!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Okay, and?
&lt;/h1&gt;

&lt;p&gt;Well, I'll probably be writing about my &lt;em&gt;other&lt;/em&gt; (smaller and less ambitious) &lt;strong&gt;musical project&lt;/strong&gt; during my measly 10 days of code.&lt;/p&gt;

&lt;p&gt;Said project is going to be about Beethoven... and [his] Sonatas.&lt;/p&gt;

&lt;p&gt;So if you like those things, or if you enjoyed the last article, then there's a chance you'd be interested in my Twitter feed - for the next 10 days, at least (I always follow back!)...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you unfollow me after the 10 days is up, I won't hold it against you... much.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  More articles like the last one, please?
&lt;/h1&gt;

&lt;p&gt;Stay tuned for the next one is all I can say.&lt;/p&gt;

&lt;p&gt;It will more likely than not be about this &lt;em&gt;second&lt;/em&gt; musical project of mine and I intend to put as much time and effort into it as I did the last article, if not more.&lt;/p&gt;

&lt;p&gt;Especially considering that it was so well received (thank you!).&lt;/p&gt;

&lt;h1&gt;
  
  
  And now for some reassurance
&lt;/h1&gt;

&lt;p&gt;Please don't be worried that your feed is going to become clogged up with low-quality posts like this from me -&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I really want to reserve my dev.to profile for longer, funnier, more interesting, more well-researched and well-thought-out articles (like the last one)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For everything else, there's &lt;del&gt;Mastercard&lt;/del&gt; Twitter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/susDissonance"&gt;https://twitter.com/susDissonance&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>vue</category>
    </item>
    <item>
      <title>On building a Vue.js piano, Scriabin's synesthesia, synths/samplers in Tone.js, learning your scales and arpeggios and more!</title>
      <dc:creator>sustained</dc:creator>
      <pubDate>Tue, 10 Sep 2019 01:53:02 +0000</pubDate>
      <link>https://dev.to/sustained/sforzando-an-app-for-learning-and-experimenting-with-music-theory-harmony-composition-44cm</link>
      <guid>https://dev.to/sustained/sforzando-an-app-for-learning-and-experimenting-with-music-theory-harmony-composition-44cm</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Something missing or incorrect? This &lt;a href="https://github.com/sustained/dev.to-article-sources/"&gt;article's source is on Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Please feel free to &lt;a href="https://github.com/sustained/dev.to-article-sources/issues/new"&gt;open an issue&lt;/a&gt; or &lt;a href="https://github.com/sustained/dev.to-article-sources/compare"&gt;send a PR&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Sforzando
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fsforzando.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fsforzando.jpg" alt="A picture of the musical symbol known as sforzando which translates roughly to "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Table of Contents
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;All I see is blonde, brunette, redhead...&lt;/li&gt;
&lt;li&gt;
Introduction

&lt;ul&gt;
&lt;li&gt;What libraries are you using?&lt;/li&gt;
&lt;li&gt;Why the name "Sforzando"?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

My ideas and experimentation thus far

&lt;ul&gt;
&lt;li&gt;The Piano component&lt;/li&gt;
&lt;li&gt;
Playing some music with Tone.js

&lt;ul&gt;
&lt;li&gt;A brief distraction...&lt;/li&gt;
&lt;li&gt;To sample or to synthesize...&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Displaying the music on the piano

&lt;ul&gt;
&lt;li&gt;
A first attempt

&lt;ul&gt;
&lt;li&gt;What's with Tone.Draw?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;A second attempt&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;Bach to getting distracted - reading midi files&lt;/li&gt;

&lt;li&gt;

The colour of music

&lt;ul&gt;
&lt;li&gt;Clavier à lumieères&lt;/li&gt;
&lt;li&gt;Mapping sound waves to light waves&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Animated sheet music with SVG&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

What's next for Sforzando?

&lt;ul&gt;
&lt;li&gt;Reflection&lt;/li&gt;
&lt;li&gt;
Ideas for the future

&lt;ul&gt;
&lt;li&gt;Every truly cultured music student knows...&lt;/li&gt;
&lt;li&gt;The circle of li--err, fifths&lt;/li&gt;
&lt;li&gt;To send light into the darkness of men's hearts&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;Fin&lt;/li&gt;

&lt;li&gt;Ideas, suggestions, feedback?&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Back to top&lt;/p&gt;

&lt;h1&gt;
  
  
  All I see is blonde, brunette, redhead...
&lt;/h1&gt;

&lt;p&gt;This article is fairly code-heavy but if you're not a programmer there are &lt;strong&gt;definitely&lt;/strong&gt; at least a few sections which you will still be able to appreciate, especially if &lt;a href="https://dev.toany-actual-ideas-then"&gt;you're a&lt;/a&gt; musician, or are just interested in music.&lt;/p&gt;

&lt;p&gt;I'd even argue that the above linked sections are more interesting than the code-related ones. :)&lt;/p&gt;

&lt;p&gt;Back to top&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fmatrix.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fmatrix.jpeg" alt="A picture of the famous scrolling code scene from the film The Matrix - many overlapping columns, neverending green streams, of alien-looking characters."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;All I see is 90s-era special effects.&lt;/em&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Yawn!&lt;/strong&gt; The introduction is probably the most boring section - just a heads up.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This article is an introduction to one of my (many) pet projects - Sforzando.&lt;/p&gt;

&lt;p&gt;The initial prototype was lost due to me forgetting to back up a small handful of files and folders when upgrading my OS (yep...) - only video recordings survived.&lt;/p&gt;

&lt;p&gt;I intend to bring it back, with force. Or should I say, with forzando. :)&lt;/p&gt;

&lt;p&gt;I'm not 100% sure what it will become but basically I imagine some kind of app that allows you to &lt;strong&gt;experiment with music theory, harmony and composition in a varied and very interactive manner&lt;/strong&gt;. It's still very much in the &lt;strong&gt;early&lt;/strong&gt; prototype phase.&lt;/p&gt;

&lt;p&gt;Like most of my projects, my reasons for creating it are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;simply because I'm interested in music theory, harmony and composition&lt;/li&gt;
&lt;li&gt;to experiment with new ideas, techniques, technologies etc.&lt;/li&gt;
&lt;li&gt;because I'll surely learn &lt;em&gt;something&lt;/em&gt; from it and I like to learn&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unlike most of my projects, I decided to open-source it. For many years I was afraid of sharing my code but if I want to get hired then I need to start writing about and sharing my projects (as well as contributing to other people's projects), so.&lt;/p&gt;

&lt;h2&gt;
  
  
  What libraries are you using?
&lt;/h2&gt;

&lt;p&gt;The most noteworthy are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/tonaljs/tonal" rel="noopener noreferrer"&gt;TonalJS&lt;/a&gt;, a music theory library.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Tonejs/Tone.js" rel="noopener noreferrer"&gt;ToneJS&lt;/a&gt;, a web audio framework.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/vuejs/vue" rel="noopener noreferrer"&gt;VuejS&lt;/a&gt;, a UI library.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why the name?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Sforzando_(musical_direction)" rel="noopener noreferrer"&gt;Sforzando is a musical term&lt;/a&gt; (so, Italian) which as far as I know means something like "sudden force". It accentuates a note - basically instructing the player to play it louder/harder than the other surrounding notes, so that it &lt;strong&gt;stands out&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;My hope is that the app, too, can stand out from other similar apps, at least eventually! For that reason it felt like a good name.&lt;/p&gt;

&lt;p&gt;Back to top&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fpiano.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fpiano.jpeg" alt="An image of an upright acoustic piano, taken in Kontich, Belgium, taken from the right/high side of the piano. The notes blur more and more as the octaves go down."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I've got 88 keys and somehow I still struggle to open my door.&lt;/em&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  My ideas and experimentation thus far
&lt;/h1&gt;

&lt;h2&gt;
  
  
  The Piano component
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fpiano-component.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fpiano-component.png" alt="A screenshot of a browser window with the Vue devtools opened and the Sforzando Piano Vue component highlighted. The piano stretches from A1 to C#5. Various data and computed properties can be seen in the dev tools, such as octave-start, octave-end, numOctaves, pianoState and more."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To start with, I set out to create a UI component which generates a piano.&lt;/p&gt;

&lt;p&gt;I looked around on CodePen, JSFiddle and CodeSandbox for ideas and inspiration for a while and then off I went, with the task of creating my own.&lt;/p&gt;

&lt;p&gt;It's entirely dynamic, so you can tell it at which octave it should start and end at and such things as these.&lt;/p&gt;

&lt;p&gt;It uses (mostly) &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout" rel="noopener noreferrer"&gt;CSS grid&lt;/a&gt; and a bit of &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox" rel="noopener noreferrer"&gt;Flexbox&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Usage:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;piano&lt;/span&gt;
  &lt;span class="na"&gt;octave-start=&lt;/span&gt;&lt;span class="s"&gt;"3"&lt;/span&gt;
  &lt;span class="na"&gt;octave-end=&lt;/span&gt;&lt;span class="s"&gt;"6"&lt;/span&gt;
  &lt;span class="na"&gt;note-start=&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt;
  &lt;span class="na"&gt;note-end=&lt;/span&gt;&lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Back to top&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Playing some music with Tone.js
&lt;/h2&gt;

&lt;p&gt;Now that I had a dynamic piano component, my next goal was to get Tone.js to play some music (and then to display said music on the piano).&lt;/p&gt;

&lt;h3&gt;
  
  
  A brief distraction...
&lt;/h3&gt;

&lt;p&gt;So, like any other non-distractible person, I went straight to the piano and wrote a chord progression:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cm (&lt;code&gt;i&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;G (&lt;code&gt;V&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Bb (&lt;code&gt;VII&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;F (&lt;code&gt;V / VII&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Ab (&lt;code&gt;VI&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Cm (&lt;code&gt;i&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;F#dim7 (&lt;code&gt;vii° / V&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Gsus4 (&lt;code&gt;Vsus4&lt;/code&gt;), G (&lt;code&gt;V&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;...it's nothing special but the goal here isn't to write good music.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; It's very possible that my harmonic analysis &lt;em&gt;of my own chord progression&lt;/em&gt; is incorrect...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I then broke those chords up into some basic arpeggios, here they are represented as code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;D#2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;G2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;G2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;D#2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;B1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;D2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;G2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;B2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;G2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;D2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A#1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;D2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;F2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A#2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;F2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;D2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;F2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;F2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;G#1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;D#2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;G#2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;D#2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;G1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;D#2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;G2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;D#2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;F#1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;D#2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;F#2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;D#2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;G1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;D2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;G2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;D2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;B1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I chose the key of C minor, of course, because &lt;a href="https://en.wikipedia.org/wiki/Beethoven_and_C_minor" rel="noopener noreferrer"&gt;it's the only actual good key&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/swen0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Back to top&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fbeethoven-approves.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fbeethoven-approves.jpeg" alt="A large metallic statue of Ludwig van Beethoven with several smaller golden statues scattered around it. The large status is covered in a patina - a layer of green-ish oxidation that often forms on metals like copper and brass. The smaller statues are golden and out-of-focus."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Beethoven's reaction to my choice of key.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  To sample or to synthesize...
&lt;/h3&gt;

&lt;p&gt;Synthesizers are cool and all (oh who am I kidding - they're freaking awesome) and my chord progression sounded perfectly swell when pumped into a synthesizer (see above).&lt;/p&gt;

&lt;p&gt;But I quickly decided I wanted to use real piano samples (mostly because I am a pianist myself - the sound is just comfortable to my ears), so I &lt;a href="http://vis.versilstudios.net/vsco-community.html" rel="noopener noreferrer"&gt;found some free samples&lt;/a&gt; and hooked them up:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/see7r"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Excellent, with little effort our little chord progression sounds even nicer.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What's a synthesizer?&lt;/strong&gt; If you'd like to learn about synthesizers then check out Ableton's new &lt;a href="https://www.ableton.com/en/blog/learn-music-in-your-browser/" rel="noopener noreferrer"&gt;Learning Music&lt;/a&gt; website...&lt;/p&gt;

&lt;p&gt;...after reading this article, of course.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Back to top&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Forchestra.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Forchestra.jpeg" alt="The string section of an orchestra as seen from above, in the middle of playing some music."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Q: What's the definition of a semitone? A: Two violinists playing in unison.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Displaying the music on the piano
&lt;/h2&gt;

&lt;p&gt;Now I needed a way to highlight the active note on my piano.&lt;/p&gt;

&lt;h3&gt;
  
  
  A first attempt
&lt;/h3&gt;

&lt;p&gt;My initial implementation of this was &lt;em&gt;heresy&lt;/em&gt; - DOM manipulation... in Vue.js! Shudder. But I wasn't really sure how else I could make it work.&lt;/p&gt;

&lt;p&gt;Anyway, it ended up looking a little something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Transport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scheduleRepeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;sampler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;triggerAttackRelease&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activeNote&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;8n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;Draw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;notes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;li.note&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nb"&gt;document&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`li.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activeNote&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;step&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I know, it's really bad isn't it? But it worked for an initial proof-of-concept implementation. Well, mostly...&lt;/p&gt;

&lt;p&gt;It was one note out-of-sync and so I had to add a hack - a computed property that returned the &lt;em&gt;previous note&lt;/em&gt; and then I added the class to &lt;em&gt;that&lt;/em&gt; instead.&lt;/p&gt;

&lt;p&gt;Yep, who imagined that it could get any worse?&lt;/p&gt;

&lt;p&gt;Fear not dear reader, we can do much better than this... and we will, in a moment.&lt;/p&gt;

&lt;h4&gt;
  
  
  What's with Tone.Draw?
&lt;/h4&gt;

&lt;p&gt;Just in case you were wondering - the callbacks passed to &lt;code&gt;Transport.schedule&lt;/code&gt; are ran in a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers" rel="noopener noreferrer"&gt;Web Worker&lt;/a&gt; and the entire library (really any music app or library, in fact) is &lt;em&gt;really time-sensitive/performance-critical&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;If we were to do anything heavy in the callback it could (and probably would) destroy performance. Additionally, the events can be scheduled far in advance of you actually &lt;em&gt;hearing them&lt;/em&gt;, or can be ran in a background tab (when there's not even anything to see).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Tone.Draw&lt;/code&gt; addresses this problem by making use of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame" rel="noopener noreferrer"&gt;requestAnimationFrame&lt;/a&gt;. It will trigger our drawing code &lt;em&gt;as close to the Tone event as possible&lt;/em&gt;. Maybe slightly before or after. But always very, very close.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Back to top&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fbad-code.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fbad-code.jpeg" alt="A picture of badly formatted/indented computer code. It is enough to make your eye's bleed. Luckily for you, this text won't do that."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Even the above code is better than DOM manipulation in Vue.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  A second attempt
&lt;/h3&gt;

&lt;p&gt;I reached out for advice and someone suggested to me the idea of using &lt;a href="https://vuejs.org/v2/api/#Vue-observable" rel="noopener noreferrer"&gt;Vue.observable&lt;/a&gt; to store the active key state.&lt;/p&gt;

&lt;p&gt;For those not in the know, &lt;code&gt;Vue.observable&lt;/code&gt; is what is used to make your &lt;code&gt;data&lt;/code&gt; reactive internally - tl;dr: it's magic.&lt;/p&gt;

&lt;p&gt;Here's what I ended up with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createRange&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./music&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;notes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;noteMap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pianoState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;noteMap&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;pianoState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;note&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;pianoState&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It constructs an object that looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A#0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;B0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="c1"&gt;// etc.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;That's one key-value pair for every note on a grand piano (A0-C8, 88 keys)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If a key is &lt;code&gt;true&lt;/code&gt; then that note is being "held" (and therefore it should be highlighted) and if it's &lt;code&gt;false&lt;/code&gt; then the opposite is true.&lt;/p&gt;

&lt;p&gt;Because it's a Vue-wrapped reactive object we can use this in computed properties and such and it will trigger a re-render whenever it changes - perfect!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Back to top&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Freaction.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Freaction.jpeg" alt="A picture of a beaker submerged in some kind of glass container which contains a liquid. It looks like science is afoot. We should probably take a step back."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;According to preliminary analysis, Vue reactivity is 172,643% more interesting than the above reaction.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Bach to getting distracted - reading midi files
&lt;/h2&gt;

&lt;p&gt;I decided that in order to put this system to the test I'd need to throw some &lt;em&gt;real&lt;/em&gt; music at it and so &lt;a href="https://en.wikipedia.org/wiki/Prelude_and_Fugue_in_C_major,_BWV_846" rel="noopener noreferrer"&gt;I choose a Bach prelude - the most famous one, in fact&lt;/a&gt;. You've probably heard it before.&lt;/p&gt;

&lt;p&gt;Hooking up midi to my sampler was rather simple and ended up looking something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;midi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tracks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;track&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;track&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;note&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Transport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;piano&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;triggerAttackRelease&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;Tone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;velocity&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;Tone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, we'd also need to hook this up to our new &lt;code&gt;Vue.observable&lt;/code&gt;-powered reactive piano state.&lt;/p&gt;

&lt;p&gt;After a few attempts I settled on this method with 3x separate &lt;code&gt;Transport.schedule&lt;/code&gt; calls. Somehow it seems to work better than the other methods I tried and honestly I don't understand why:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;midi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tracks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;track&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;track&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;note&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Transport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;piano&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;triggerAttackRelease&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;Tone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;velocity&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;Tone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;Transport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;Draw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;pianoState&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;Tone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;Transport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;Draw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;pianoState&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;duration&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;Tone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Back to top&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fsynth.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fsynth.jpeg" alt="A picture of a midi keyboard as seen from the side, sitting by a window, on a table. An empty street can be seen in the background."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I want one. I want one. I want one.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The colour of music
&lt;/h2&gt;

&lt;p&gt;So, I had it sort of working on a basic level but all the notes were highlighted red and it was awful.&lt;/p&gt;

&lt;p&gt;Off to Google I went to see if there were any existing techniques for mapping frequencies to colours.&lt;/p&gt;

&lt;h3&gt;
  
  
  Clavier à lumieères
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fscriabin_circle.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fscriabin_circle.jpg" alt="A picture of a midi keyboard as seen from the side, sitting by a window, on a table. An empty street can be seen in the background."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A Russian composer called &lt;a href="https://en.wikipedia.org/wiki/Alexander_Scriabin" rel="noopener noreferrer"&gt;Alexandar Scriabin&lt;/a&gt; is purported to have suffered from the condition &lt;a href="https://en.wikipedia.org/wiki/Synesthesia" rel="noopener noreferrer"&gt;Synesthesia&lt;/a&gt;. If you haven't heard of it, it can essentially be summed up as when the "wires" relating to two senses get crossed.&lt;/p&gt;

&lt;p&gt;For Scriabin, it was his sense of hearing and sight that were affected and so to him - &lt;strong&gt;musical notes had colour.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Based on this, he developed a system - &lt;strong&gt;Clavier à lumieères&lt;/strong&gt; (Keyboard with lights).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In his autobiographical Recollections, &lt;a href="https://en.wikipedia.org/wiki/Sergei_Rachmaninoff" rel="noopener noreferrer"&gt;Sergei Rachmaninoff&lt;/a&gt; recorded a conversation he had had with Scriabin and &lt;a href="https://en.wikipedia.org/wiki/Nikolai_Rimsky-Korsakov" rel="noopener noreferrer"&gt;Nikolai Rimsky-Korsakov&lt;/a&gt; &lt;strong&gt;about Scriabin's association of colour and music.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Rachmaninoff was surprised to find that Rimsky-Korsakov agreed with Scriabin on associations of musical keys with colors; himself skeptical, Rachmaninoff made the obvious objection that the two composers did not always agree on the colours involved.&lt;/p&gt;

&lt;p&gt;Both maintained that &lt;strong&gt;the key of D major was golden-brown; but Scriabin linked E-flat major with red-purple, while Rimsky-Korsakov favored blue.&lt;/strong&gt; However, Rimsky-Korsakov protested that a passage in Rachmaninoff's opera The Miserly Knight accorded with their claim: the scene in which the Old Baron opens treasure chests to reveal gold and jewels glittering in torchlight is written in D major.&lt;/p&gt;

&lt;p&gt;Scriabin told Rachmaninoff that "your intuition has unconsciously followed the laws whose very existence you have tried to deny.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source:&lt;/strong&gt; Wikipedia&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's a really cool system and I'd like to find some way to use it in my app, however I settled on another technique...&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Back to top&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fscriabin_keyboard.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fscriabin_keyboard.png" alt="One octave of a piano keyboard with the keys coloured according to Alexander Scriabin's perception of the notes due to his condition - Synesthesia."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How to get your young child interested in learning piano 101.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Mapping sound waves to light waves
&lt;/h3&gt;

&lt;p&gt;As you may or may not know, sound is basically vibrations and we measure vibrations by using &lt;a href="https://en.wikipedia.org/wiki/Hertz" rel="noopener noreferrer"&gt;Hertz&lt;/a&gt; (cycles per second).&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the note A4 (A above middle C) is 440 Hz&lt;/li&gt;
&lt;li&gt;the note A5 (the next A up) is 880 Hz&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Light is made of waves and waves have a length, which we measure using &lt;a href="https://en.wikipedia.org/wiki/Nanometre" rel="noopener noreferrer"&gt;nanometres&lt;/a&gt; (at least for the visible spectrum, which lies between 400-700nm).&lt;/p&gt;

&lt;p&gt;If we convert that to hertz then we get 430-750THz (1Hz = 10&lt;sup&gt;12&lt;/sup&gt;Hz).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Ouch!&lt;/strong&gt; That's a lot of Hertz.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sorry about that. Where was I? Ah, yes.&lt;/p&gt;

&lt;p&gt;So, basically we can &lt;strong&gt;directly map sound frequency to light.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I tried to implement the algorithm myself but ran into some problems, so I just copy-pasted some colour values.&lt;/p&gt;

&lt;p&gt;Unfortunately for you, that means that the sandbox I was going to put here does not exist. :(&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fcss-light-sound-colours.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fcss-light-sound-colours.png" alt="A screenshot of the CSS that maps the notes to colours, in the same order as the visible light spectrum, starting at F sharp (a deep red) and going to F (a deep purple)."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Behold the power of copy-paste.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Animated sheet music with SVG
&lt;/h2&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/go4pm"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Another thing I've (just barely) started experimenting with is generating &lt;a href="https://developer.mozilla.org/en-US/docs/Web/SVG" rel="noopener noreferrer"&gt;SVG&lt;/a&gt; with &lt;a href="https://musescore.org/en" rel="noopener noreferrer"&gt;MuseScore&lt;/a&gt; and then animating it. &lt;/p&gt;

&lt;p&gt;Additionally I played around with generating my own SVG-based sheet music from scratch.&lt;/p&gt;

&lt;p&gt;This experimentation was actually for &lt;a href="https://github.com/sustained/die-sonaten" rel="noopener noreferrer"&gt;another very early musical project of mine&lt;/a&gt; but that doesn't matter as said experimentation will undoubtedly make its way into this project, too, in some way, shape or form.&lt;/p&gt;

&lt;p&gt;I have to say though, I've actually never worked with SVG before, so it's all very new to me but based on my very limited exposure - it's very cool.&lt;/p&gt;

&lt;p&gt;Also, you should definitely check out &lt;a href="https://svgjs.com/" rel="noopener noreferrer"&gt;SVG.js&lt;/a&gt; and &lt;a href="https://animejs.com/" rel="noopener noreferrer"&gt;Anime.js&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Back to top&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Frainbow.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Frainbow.jpeg" alt="A picture of a rainbow, taken in Maui, Hawaii. The sky is quite cloudy. There are lush green rolling plains along with a small amount of hilly or even somewhat mountaineous terrain."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;There's a land that I heard of once in a lullaby...&lt;/em&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  What's next for Sforzando?
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Reflection
&lt;/h2&gt;

&lt;p&gt;Unfortunately, many of my projects end up dead and buried; often hidden away in private repositories.&lt;/p&gt;

&lt;p&gt;This generally happens because of one or more of the following reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I'm being too grandiose with my vision

&lt;ul&gt;
&lt;li&gt;and/or scope creep - trying to add too much, too quickly&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Rewriting the entire project too early on

&lt;ul&gt;
&lt;li&gt;and/or changing technology choices part way through&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Struggling with how to architect the API, or the schema etc.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;But I really would like to keep working on this one. Out of all of my projects, old and new, it's probably my second favourite idea.&lt;/p&gt;

&lt;p&gt;And I'm deeply passionate about music.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So here's what I intend to do...&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, I'll keep experimenting with random ideas like animating SVGs and parsing MIDI files and whatever else comes to mind but simultaneously I am going to devote some time and effort to actually &lt;strong&gt;planning&lt;/strong&gt; and &lt;strong&gt;designing&lt;/strong&gt; the app this time around, instead of just blindly coding away for several months until I have some undocumented and unmaintainable organicly-grown beast that even I don't fully understand.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Back to top&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Ideas for the future
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Every truly cultured music student knows...
&lt;/h3&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/khvaIwonxUk"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I'd like to add a bunch of stuff relating to chords, scales, arpeggios etc. as soon as possible (the initial prototype had it).&lt;/p&gt;

&lt;p&gt;In terms of the actual musical (i.e. sound-making) part of the app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an arpeggiator that can generate and play arpeggios&lt;/li&gt;
&lt;li&gt;a way to have the app play scales for you&lt;/li&gt;
&lt;li&gt;a system to play common harmonic sequences/progressions&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As well as learning/visual aids:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;something to help with learning chord inversions&lt;/li&gt;
&lt;li&gt;learn key signatures using the circle of fifths as a guide&lt;/li&gt;
&lt;li&gt;fingering charts for scales&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not to mention compositional aids:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;highlight instrument ranges on the piano component&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Back to top&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The circle of li--err, fifths
&lt;/h3&gt;

&lt;p&gt;I've been working on a circle of fifths component (also SVG) and I have various ideas relating to the visualisation of harmonic progressions, of diatonic harmony, of key signatures and so much more using it.&lt;/p&gt;

&lt;p&gt;Honestly the circle of fifths is the most fascinating thing ever and I highly recommend learning about it. &lt;/p&gt;

&lt;p&gt;And don't stop until you &lt;strong&gt;understand&lt;/strong&gt; it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Back to top&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fcircle-of-fifths.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fcircle-of-fifths.png" alt="A circle of fifths - a visual aid for understanding the relationship between keys. At 12 o'clock we have C Major and a minor, both with zero accidentals. Going clockwise by intervals of perfect fifths adds a sharp to the key signature - G (1 sharp), D (2 sharps) whereas going anti-clockwise by intervals of perfect fourths adds a flat - F (1 flat), Bb (2 flats) etc."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Theory of Everything............ of Music™.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  To send light into the darkness of men's hearts
&lt;/h3&gt;

&lt;p&gt;I'd definitely like for this to be a useful for &lt;strong&gt;musical composition&lt;/strong&gt; if at all possible but I'm not really sure how that is going to work.&lt;/p&gt;

&lt;p&gt;Traditionally and personally I always favoured apps like &lt;a href="http://www.sibelius.com/products/avid_scorch/index.html" rel="noopener noreferrer"&gt;Sibelius&lt;/a&gt; and &lt;a href="https://www.finalemusic.com/" rel="noopener noreferrer"&gt;Finale&lt;/a&gt; but lately I've been turning to paper more and more, mostly because those apps aren't available for my Operating System and I find it hard to work with &lt;a href="https://musescore.org/" rel="noopener noreferrer"&gt;MuseScore&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The other day though I started playing with Sequencers and Digital Audio Workstations and I have to say I really like some of their ideas and wouldn't mind stealing a couple.&lt;/p&gt;

&lt;p&gt;In any case, music composition is something I'm trying to get back into and so I'll absolutely be &lt;a href="https://en.wikipedia.org/wiki/Eating_your_own_dog_food" rel="noopener noreferrer"&gt;dogfooding&lt;/a&gt; this app/tool when it gets to a more usable state.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Back to top&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fcomposer.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsustained%2Fdev.to-article-sources%2Fmaster%2Fmedia%2Fsforzando-an-interactive-music-theory-harmony-learning-experimentation-app%2Fcomposer.jpeg" alt="An aging hand reaching out to touch a manuscript."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I don't have anything witty left to say.&lt;/em&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Fin
&lt;/h1&gt;

&lt;p&gt;If you enjoyed this article and would like me to write more then &lt;strong&gt;please&lt;/strong&gt; show some love because it took several &lt;strong&gt;hours&lt;/strong&gt; to put this together and I could have spent that time working on my projects instead, or writing music, or whatever else.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Back to top&lt;/em&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Ideas, suggestions, feedback?
&lt;/h1&gt;

&lt;p&gt;Feel free to message me on here or reply to the article but otherwise I'm always reachable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;on Discord (sustained#2329)&lt;/li&gt;
&lt;li&gt;on Github (sustained)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;I'd especially be interested to hear from you if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you're a music teacher/student and have ideas&lt;/li&gt;
&lt;li&gt;you have feedback on how I can improve my writing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Otherwise, &lt;a href="https://dev.to/sustained"&gt;follow me&lt;/a&gt; for more posts (probably) about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This app&lt;/li&gt;
&lt;li&gt;My other projects&lt;/li&gt;
&lt;li&gt;Vue.js, Laravel and other neat technologies&lt;/li&gt;
&lt;li&gt;Music composition and production&lt;/li&gt;
&lt;li&gt;Language learning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Back to top&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Links
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/sustained/sforzando" rel="noopener noreferrer"&gt;Source code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://sforzando.herokuapp.com/" rel="noopener noreferrer"&gt;Live demo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Mobile is 100% untested (at this early stage).&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.sustained.name/projects/sforzando/" rel="noopener noreferrer"&gt;Project page&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Information on my website is out of date.&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Back to top&lt;/em&gt;&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Something missing or incorrect? This &lt;a href="https://github.com/sustained/dev.to-article-sources/"&gt;article's source is on Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Please feel free to &lt;a href="https://github.com/sustained/dev.to-article-sources/issues/new"&gt;open an issue&lt;/a&gt; or &lt;a href="https://github.com/sustained/dev.to-article-sources/compare"&gt;send a PR&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>vue</category>
      <category>music</category>
    </item>
    <item>
      <title>Laravel + Vue = ❤️</title>
      <dc:creator>sustained</dc:creator>
      <pubDate>Tue, 03 Sep 2019 17:05:10 +0000</pubDate>
      <link>https://dev.to/sustained/laravel-vue-4530</link>
      <guid>https://dev.to/sustained/laravel-vue-4530</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Something missing or incorrect? This &lt;a href="https://github.com/sustained/dev.to-article-sources/"&gt;article's source is on Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Please feel free to &lt;a href="https://github.com/sustained/dev.to-article-sources/issues/new"&gt;open an issue&lt;/a&gt; or &lt;a href="https://github.com/sustained/dev.to-article-sources/compare"&gt;send a PR&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Table of Contents
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;
Reasons to use Vue and Laravel together

&lt;ul&gt;
&lt;li&gt;Scaffolded by default&lt;/li&gt;
&lt;li&gt;Laravel Mix&lt;/li&gt;
&lt;li&gt;Widespread community adoption&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
Common gotchas when using Vue and Laravel together

&lt;ul&gt;
&lt;li&gt;Blade and Vue interpolation syntax&lt;/li&gt;
&lt;li&gt;Passing PHP variables as Vue component props&lt;/li&gt;
&lt;li&gt;
Laravel router and vue-router

&lt;ul&gt;
&lt;li&gt;
Setting it all up

&lt;ul&gt;
&lt;li&gt;Install vue-router&lt;/li&gt;
&lt;li&gt;Create a router instance and some routes&lt;/li&gt;
&lt;li&gt;Create a simple App component&lt;/li&gt;
&lt;li&gt;Create a few page components&lt;/li&gt;
&lt;li&gt;Configure the root Vue instance&lt;/li&gt;
&lt;li&gt;Configure the Laravel router&lt;/li&gt;
&lt;li&gt;Create the controller and action&lt;/li&gt;
&lt;li&gt;Create the view&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Lack of Webpack aliases when using Laravel Mix&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Thanks and good bye&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Recently the excellent Vue Community guide was released. A guide on all things Vue - written for the Vue community, by the Vue community.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dobromir-hristov/vuecommunity"&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://vue-community.org/"&gt;Website&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article's stuture will mirror exactly the layout of &lt;a href="https://vue-community.org/guide/learning/how-to-learn-vue.html#laravel"&gt;the Laravel section of the Vue Community guide&lt;/a&gt;, heading for heading.&lt;/p&gt;

&lt;p&gt;The intent is to provide a living resource (i.e. it will be updated over time if/when necessary) that goes into far greater detail (including code samples/demos) than the guide (which is intended to be more concise and easier to digest).&lt;/p&gt;

&lt;p&gt;Back to top&lt;/p&gt;

&lt;h1&gt;
  
  
  Reasons to use Vue and Laravel together
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Scaffolded by default
&lt;/h2&gt;

&lt;p&gt;A default install of Laravel &lt;a href="https://laravel.com/docs/frontend#writing-vue-components"&gt;has everything you need&lt;/a&gt; to begin enhancing your server-rendered (Blade) templates with Vue components. No setup necessary.&lt;/p&gt;

&lt;p&gt;After having created a Laravel project, you'll be provided with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;bootstrap.js&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;loads some libraries such as lodash, axios and Popper&lt;/li&gt;
&lt;li&gt;configures axios for CSRF&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;app.js&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;makes Vue globally available&lt;/li&gt;
&lt;li&gt;registers the &lt;code&gt;ExampleComponent.vue&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;provides example code on how to automatically register Vue components&lt;/li&gt;
&lt;li&gt;initialises Vue&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ExampleComponent.vue&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You are of course free to customise these files to your needs such as by removing unneeded/unwanted libraries.&lt;/p&gt;

&lt;p&gt;Back to top&lt;/p&gt;

&lt;h2&gt;
  
  
  Laravel Mix
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://laravel.com/docs/mix"&gt;Laravel Mix&lt;/a&gt;--a fluid API on top of Webpack, also included in the box--takes much of the pain out of asset compiling for you, so you can focus on authoring your Vue components.&lt;/p&gt;

&lt;p&gt;You simply need to run &lt;code&gt;npm run watch&lt;/code&gt; and then you can get straight to work on writing your Vue components!&lt;/p&gt;

&lt;p&gt;It's not quite &lt;a href="https://cli.vuejs.org/"&gt;@vue/cli&lt;/a&gt;-levels of awesome but it's actually a really nice library and I do recommend it. It's also not at all tied to Laravel in any way- you can use it in any project.&lt;/p&gt;

&lt;p&gt;Back to top&lt;/p&gt;

&lt;h2&gt;
  
  
  Widespread community adoption
&lt;/h2&gt;

&lt;p&gt;Several prominent members of the Laravel community are proponents of Vue (and its ecosystem).&lt;/p&gt;

&lt;p&gt;This includes but is not limited to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/taylorotwell"&gt;Taylor Otwell&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Founder (and Benevolent Dictator for Life) of Laravel itself&lt;/li&gt;
&lt;li&gt;Known user of Laravel and Vue&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/adamwathan"&gt;Adam Wathan&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Author of &lt;a href="https://tailwindcss.com/"&gt;TailwindCSS&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Creator of the &lt;a href="https://adamwathan.me/advanced-vue-component-design/"&gt;Advanced Vue Component Design course&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Known user of Laravel and Vue&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/jeffrey_way"&gt;Jeffrey Way&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Author of &lt;a href="https://leanpub.com/u/jeffreyway"&gt;Laravel Testing Decoded&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Reoccuring speaker at &lt;a href="https://laracon.eu/"&gt;Laracon&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Creator of &lt;a href="https://laracasts.com"&gt;several Laravel/Vue courses&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Known user of Laravel and Vue&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This advocacy and support of Vue, as far as I can tell, extends to the Laravel community as a whole, meaning that a majority of Laravel developers will likely be more comfortable and familiar with Vue than say React or Angular.&lt;/p&gt;

&lt;p&gt;Naturally, then, it follows that there will be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;more resources to help you learn (guides, tutorials, articles)&lt;/li&gt;
&lt;li&gt;more people who have experience with Vue+Laravel (help, support, guidance)&lt;/li&gt;
&lt;li&gt;in general a healthy ecosystem (plugins, boilerplates, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Back to top&lt;/p&gt;

&lt;h1&gt;
  
  
  Common gotchas when using Vue and Laravel together
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Blade and Vue interpolation syntax
&lt;/h2&gt;

&lt;p&gt;As you may be aware both &lt;a href="https://laravel.com/docs/blade#displaying-data"&gt;Blade templates&lt;/a&gt; and &lt;a href="https://vuejs.org/v2/guide/#Declarative-Rendering"&gt;Vue templates&lt;/a&gt; use moustache syntax (i.e. &lt;code&gt;{{ message }}&lt;/code&gt;) for variable interpolation, which presents a problem.&lt;/p&gt;

&lt;p&gt;Fortunately the solution is simple - just prepend an &lt;code&gt;@&lt;/code&gt; to the moustache statement. This will &lt;a href="https://laravel.com/docs/blade#blade-and-javascript-frameworks"&gt;instruct the Blade template rendering engine&lt;/a&gt; to ignore this statement, leaving it to be later processed by Vue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;You have @{{ messageCount }} new message(s).&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need to escape several moustache statements, you may instead use the &lt;code&gt;@verbatim&lt;/code&gt; directive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@verbatim
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Welcome {{ user.name }} ({{ user.id }})!&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Your last visit was: {{ user.lastVisit }}.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
@endverbatim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Back to top&lt;/p&gt;

&lt;h2&gt;
  
  
  Passing PHP variables as Vue component props
&lt;/h2&gt;

&lt;p&gt;If you ever need to pass a Blade variable as a &lt;a href="https://vuejs.org/v2/guide/components-props.html"&gt;prop&lt;/a&gt; into a &lt;a href="https://vuejs.org/v2/guide/components.html"&gt;Vue component&lt;/a&gt; from within a &lt;a href="https://laravel.com/docs/blade"&gt;Blade template&lt;/a&gt; then you may be tempted to reach for &lt;code&gt;json_encode&lt;/code&gt; however you should instead use the &lt;code&gt;@json&lt;/code&gt; directive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;user-profile&lt;/span&gt; &lt;span class="na"&gt;:user=&lt;/span&gt;&lt;span class="s"&gt;'@json($user)'&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Back to top&lt;/p&gt;

&lt;h2&gt;
  
  
  Laravel router and vue-router
&lt;/h2&gt;

&lt;p&gt;You can absolutely use &lt;a href="https://laravel.com/docs/routing"&gt;Laravel router&lt;/a&gt; and &lt;a href="https://router.vuejs.org/"&gt;vue-router&lt;/a&gt; together without too much effort.&lt;/p&gt;

&lt;p&gt;Perhaps you want vue-router to handle &lt;strong&gt;all&lt;/strong&gt; routing; or for it to handle only some and for Laravel to handle the others; or to serve multiple SPAs using one Laravel app. All of this and more is possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting it all up
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; This section presumes a relatively basic understanding of Vue, vue-router, Laravel and the command line.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The boilerplate provided by Laravel does not include vue-router but it won't be much trouble to set up.&lt;/p&gt;

&lt;h4&gt;
  
  
  Install vue-router
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;vue-router &lt;span class="nt"&gt;--save&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Create a router instance and some routes
&lt;/h4&gt;

&lt;p&gt;Create &lt;code&gt;resources/js/router.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;VueRouter&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue-router&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;PageHome&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./pages/Home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;PageAbout&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./pages/About&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;VueRouter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;VueRouter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;history&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PageHome&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/about&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PageAbout&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Create a simple App component
&lt;/h4&gt;

&lt;p&gt;Create &lt;code&gt;resources/js/components/App.vue&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;nav&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;router-link&lt;/span&gt; &lt;span class="na"&gt;to=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/router-link&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;

                &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;router-link&lt;/span&gt; &lt;span class="na"&gt;to=&lt;/span&gt;&lt;span class="s"&gt;"/about"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;About&lt;span class="nt"&gt;&amp;lt;/router-link&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;router-view&amp;gt;&amp;lt;/router-view&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Create a few page components
&lt;/h4&gt;

&lt;p&gt;Create &lt;code&gt;resources/js/pages/Home.vue&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;resources/js/pages/About.vue&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;About&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Configure the root Vue instance
&lt;/h4&gt;

&lt;p&gt;Modify &lt;code&gt;resources/js/app.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./router&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;               &lt;span class="c1"&gt;// &amp;lt;-- register router with Vue&lt;/span&gt;
    &lt;span class="na"&gt;render&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- render App component&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Configure the Laravel router
&lt;/h4&gt;

&lt;p&gt;This is the important part - we need to instruct Laravel to route all requests to the &lt;code&gt;index&lt;/code&gt; action on the &lt;code&gt;SPAController&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Replace &lt;code&gt;routes/web.php&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/{vue}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'SPAController@index'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'vue'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'.*'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Any routes registered before this catch-all will still function.&lt;/p&gt;

&lt;p&gt;This is how we are able to handle some routes with Laravel and others with vue-router.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Create the controller and action
&lt;/h4&gt;

&lt;p&gt;Create &lt;code&gt;app/Http/Controllers/SPAController.php&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Http\Controllers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Http\Request&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SPAController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Controller&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"spa"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Create the view
&lt;/h4&gt;

&lt;p&gt;Create &lt;code&gt;resources/views/spa.blade.php&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"{{ str_replace('_', '-', app()-&amp;gt;getLocale()) }}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"csrf-token"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"{{ csrf_token() }}"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Laravel + Vue = ❤️&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{ asset('css/app.css') }}"&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"{{ asset('js/app.js') }}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it! You are now serving a Vue SPA with Laravel and vue-router is in charge of all routing (except for any routes which were defined before the catch-all, which will be handled by Laravel!).&lt;/p&gt;

&lt;p&gt;Back to top&lt;/p&gt;

&lt;h2&gt;
  
  
  Lack of Webpack aliases when using Laravel Mix
&lt;/h2&gt;

&lt;p&gt;If you've used &lt;a href="https://cli.vuejs.org/"&gt;vue-cli&lt;/a&gt; then you'll probably be familiar with (and used to using) aliases &lt;a href="https://cli.vuejs.org/guide/html-and-static-assets.html#url-transform-rules"&gt;such as &lt;code&gt;@&lt;/code&gt; and &lt;code&gt;~&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Unfortunately this is not setup by default. Fortunately for us - &lt;a href="https://laravel-mix.com/extensions/alias"&gt;there's a plugin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Back to top&lt;/p&gt;




&lt;h1&gt;
  
  
  Thanks and good bye
&lt;/h1&gt;

&lt;p&gt;Thanks for reading and enjoy developing with Laravel and Vue.&lt;/p&gt;

&lt;p&gt;Also, be sure to check out the &lt;a href="https://vue-community.org/"&gt;new Vue Community&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Something missing or incorrect? This &lt;a href="https://github.com/sustained/dev.to-article-sources/"&gt;article's source is on Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Please feel free to &lt;a href="https://github.com/sustained/dev.to-article-sources/issues/new"&gt;open an issue&lt;/a&gt; or &lt;a href="https://github.com/sustained/dev.to-article-sources/compare"&gt;send a PR&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Back to top&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>vue</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
