{"id":382,"date":"2015-07-10T23:50:00","date_gmt":"2015-07-10T23:50:00","guid":{"rendered":"https:\/\/www.sebastianlenton.com\/?p=382"},"modified":"2015-07-11T10:47:42","modified_gmt":"2015-07-11T10:47:42","slug":"local-storage-multi-window-javascript-apps","status":"publish","type":"post","link":"https:\/\/www.sebastianlenton.com\/2015\/07\/local-storage-multi-window-javascript-apps\/","title":{"rendered":"Fun With Local Storage: Multi-Window JavaScript Apps & Canvas Streaming"},"content":{"rendered":"

A short while ago I was invited to participate in\u00a0\u00b5Chip3<\/a>, an arts event curated by Antonio Roberts<\/a> & Sam Wray<\/a>\u00a0which involved chiptune, digital art, hacking, modified hardware and much\u00a0more. My role was to perform live visuals to accompany performances by some notable chiptune artists, so\u00a0I set about building a\u00a0custom browser-based visualiser based on the piece I produced<\/a> for the BYOB 2013 exhibition.<\/p>\n

Visualiser applications need to work across two windows (a control window with which you create and modify visuals,\u00a0which appear in a\u00a0display window), so working out how to produce an application able to function reliably in this way\u00a0was my first concern. I worried it would involve some fiddly work with a local server, but after some research\u00a0the solution proved straightforward: simply\u00a0store commands in local storage via\u00a0the command window,\u00a0which are\u00a0then\u00a0be detected by the display window using the\u00a0storage event listener.<\/p>\n

As well as\u00a0multi-window\u00a0web applications, local storage\u00a0can also be used to keep web\u00a0apps open in multiple tabs in sync with each other, or even to stream the output of a HTML5 canvas from one window to another. Read on for some demos…<\/p>\n

<\/p>\n

Below: a screenshot of the visualiser. The control window is on the left, the display on the right.<\/p>\n\"Multi-window\n

What Is Local Storage?<\/h2>\n

The clue is in the name: it’s a\u00a0capability of modern browsers which allows websites and applications to store persistent data\u00a0locally. Conceptually, it’s similar to cookies but without the drawbacks: up to 5MB per domain can usually\u00a0be stored (with some exceptions). Plus, unlike cookies nothing needs to be sent with HTTP requests. If you’re looking to learn more about local storage then read more\u00a0about it\u00a0here<\/a> and here<\/a>.<\/p>\n

Communicating Between Windows<\/h3>\n

Local storage can be used to communicate between windows using the “storage” Javascript event listener.\u00a0Whenever data is stored in one window an event can\u00a0be triggered in another\u00a0on the same domain, at which point in the second window you can get whatever has been stored and act upon it appropriately. This is key to creating a visualiser app that\u00a0allows control of a display window (projected to an audience) via a GUI visible only from the VJ’s laptop. “Commands” made with the GUI window\u00a0can be stored as a JSON object, which will then be\u00a0read and\u00a0acted upon by the display window. Find a very simple demo here<\/a>\u00a0(only tested in Chrome 43 at time of writing).<\/p>\n

Sending the Same Command\u00a0Repeatedly<\/h3>\n

One caveat of the storage JavaScript event listener is, it will only be triggered when new or unique data is stored. This means that you can’t send the same command repeatedly. For example, you can’t create\u00a0an application where a button can repeatedly be\u00a0pressed in one window, triggering\u00a0a repeating action in another. However, there is a very simple way around this: just\u00a0add some un-used random data into the stored JSON object. By doing this you can send the same command\u00a0as many times as you like.<\/p>\n

Using Local Storage to Stream\u00a0a HTML5 Canvas from One Window to Another<\/h3>\n

It’s possible to (ab)use local storage to stream the output from a HTML5 canvas from one window to another, in realtime. While this isn’t a technique I used when building my visualiser, it’s kind of interesting all the same\u00a0and could have a use somewhere- perhaps for if one needed\u00a0to stream the output of their display window back to their control window.<\/p>\n

To do this is fairly simple: when the canvas renders a frame, encode it as a base64 data URI. Store this in local storage, and then decode\u00a0and draw it into a canvas in the other window. Find a demo of this right here<\/a>.<\/p>\n

Conclusion<\/h2>\n

Find the code for the above demos on GitHub<\/a>. If you’ve any feedback or questions regarding\u00a0this post\u00a0then please drop me a line via twitter<\/a> or email<\/a>. I’m particularly curious to know if there\u00a0might be a\u00a0better method of streaming a canvas between two windows?<\/p>\n","protected":false},"excerpt":{"rendered":"

A short while ago I was invited to participate in\u00a0\u00b5Chip3, an arts event curated by Antonio Roberts & Sam Wray\u00a0which involved chiptune, digital art, hacking, modified hardware and much\u00a0more. My role was to perform live visuals to accompany performances by some notable chiptune artists, so\u00a0I set about building a\u00a0custom browser-based visualiser based on the piece… Read more »<\/a><\/p>\n","protected":false},"author":2,"featured_media":399,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"yoast_head":"\nLocal Storage: Multi-Window JavaScript Apps, Canvas Streaming<\/title>\n<meta name=\"description\" content=\"Read how I used local storage to build a multi-window browser-based JavaScript visualiser. You can also stream a HTML5 canvas between windows in realtime.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.sebastianlenton.com\/2015\/07\/local-storage-multi-window-javascript-apps\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Local Storage: Multi-Window JavaScript Apps, Canvas Streaming\" \/>\n<meta property=\"og:description\" content=\"Read how I used local storage to build a multi-window browser-based JavaScript visualiser. You can also stream a HTML5 canvas between windows in realtime.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.sebastianlenton.com\/2015\/07\/local-storage-multi-window-javascript-apps\/\" \/>\n<meta property=\"og:site_name\" content=\"Sebastian Lenton\" \/>\n<meta property=\"article:published_time\" content=\"2015-07-10T23:50:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2015-07-11T10:47:42+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.sebastianlenton.com\/wp-content\/uploads\/2015\/07\/blogheader-1100x785.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1100\" \/>\n\t<meta property=\"og:image:height\" content=\"785\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Seb Lenton\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@sebastianlenton\" \/>\n<meta name=\"twitter:site\" content=\"@sebastianlenton\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Seb Lenton\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.sebastianlenton.com\/2015\/07\/local-storage-multi-window-javascript-apps\/\",\"url\":\"https:\/\/www.sebastianlenton.com\/2015\/07\/local-storage-multi-window-javascript-apps\/\",\"name\":\"Local Storage: Multi-Window JavaScript Apps, Canvas Streaming\",\"isPartOf\":{\"@id\":\"https:\/\/www.sebastianlenton.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.sebastianlenton.com\/2015\/07\/local-storage-multi-window-javascript-apps\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.sebastianlenton.com\/2015\/07\/local-storage-multi-window-javascript-apps\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.sebastianlenton.com\/wp-content\/uploads\/2015\/07\/blogheader.jpg\",\"datePublished\":\"2015-07-10T23:50:00+00:00\",\"dateModified\":\"2015-07-11T10:47:42+00:00\",\"author\":{\"@id\":\"https:\/\/www.sebastianlenton.com\/#\/schema\/person\/07ad65c2a7050417b92f404e980c3be1\"},\"description\":\"Read how I used local storage to build a multi-window browser-based JavaScript visualiser. You can also stream a HTML5 canvas between windows in realtime.\",\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.sebastianlenton.com\/2015\/07\/local-storage-multi-window-javascript-apps\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\/\/www.sebastianlenton.com\/2015\/07\/local-storage-multi-window-javascript-apps\/#primaryimage\",\"url\":\"https:\/\/www.sebastianlenton.com\/wp-content\/uploads\/2015\/07\/blogheader.jpg\",\"contentUrl\":\"https:\/\/www.sebastianlenton.com\/wp-content\/uploads\/2015\/07\/blogheader.jpg\",\"width\":1831,\"height\":1306},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.sebastianlenton.com\/#website\",\"url\":\"https:\/\/www.sebastianlenton.com\/\",\"name\":\"Sebastian Lenton\",\"description\":\"Freelance web development & design, Birmingham UK\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.sebastianlenton.com\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-GB\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.sebastianlenton.com\/#\/schema\/person\/07ad65c2a7050417b92f404e980c3be1\",\"name\":\"Seb Lenton\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Local Storage: Multi-Window JavaScript Apps, Canvas Streaming","description":"Read how I used local storage to build a multi-window browser-based JavaScript visualiser. You can also stream a HTML5 canvas between windows in realtime.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.sebastianlenton.com\/2015\/07\/local-storage-multi-window-javascript-apps\/","og_locale":"en_GB","og_type":"article","og_title":"Local Storage: Multi-Window JavaScript Apps, Canvas Streaming","og_description":"Read how I used local storage to build a multi-window browser-based JavaScript visualiser. You can also stream a HTML5 canvas between windows in realtime.","og_url":"https:\/\/www.sebastianlenton.com\/2015\/07\/local-storage-multi-window-javascript-apps\/","og_site_name":"Sebastian Lenton","article_published_time":"2015-07-10T23:50:00+00:00","article_modified_time":"2015-07-11T10:47:42+00:00","og_image":[{"width":1100,"height":785,"url":"https:\/\/www.sebastianlenton.com\/wp-content\/uploads\/2015\/07\/blogheader-1100x785.jpg","type":"image\/jpeg"}],"author":"Seb Lenton","twitter_card":"summary_large_image","twitter_creator":"@sebastianlenton","twitter_site":"@sebastianlenton","twitter_misc":{"Written by":"Seb Lenton","Estimated reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.sebastianlenton.com\/2015\/07\/local-storage-multi-window-javascript-apps\/","url":"https:\/\/www.sebastianlenton.com\/2015\/07\/local-storage-multi-window-javascript-apps\/","name":"Local Storage: Multi-Window JavaScript Apps, Canvas Streaming","isPartOf":{"@id":"https:\/\/www.sebastianlenton.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.sebastianlenton.com\/2015\/07\/local-storage-multi-window-javascript-apps\/#primaryimage"},"image":{"@id":"https:\/\/www.sebastianlenton.com\/2015\/07\/local-storage-multi-window-javascript-apps\/#primaryimage"},"thumbnailUrl":"https:\/\/www.sebastianlenton.com\/wp-content\/uploads\/2015\/07\/blogheader.jpg","datePublished":"2015-07-10T23:50:00+00:00","dateModified":"2015-07-11T10:47:42+00:00","author":{"@id":"https:\/\/www.sebastianlenton.com\/#\/schema\/person\/07ad65c2a7050417b92f404e980c3be1"},"description":"Read how I used local storage to build a multi-window browser-based JavaScript visualiser. You can also stream a HTML5 canvas between windows in realtime.","inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.sebastianlenton.com\/2015\/07\/local-storage-multi-window-javascript-apps\/"]}]},{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/www.sebastianlenton.com\/2015\/07\/local-storage-multi-window-javascript-apps\/#primaryimage","url":"https:\/\/www.sebastianlenton.com\/wp-content\/uploads\/2015\/07\/blogheader.jpg","contentUrl":"https:\/\/www.sebastianlenton.com\/wp-content\/uploads\/2015\/07\/blogheader.jpg","width":1831,"height":1306},{"@type":"WebSite","@id":"https:\/\/www.sebastianlenton.com\/#website","url":"https:\/\/www.sebastianlenton.com\/","name":"Sebastian Lenton","description":"Freelance web development & design, Birmingham UK","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.sebastianlenton.com\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-GB"},{"@type":"Person","@id":"https:\/\/www.sebastianlenton.com\/#\/schema\/person\/07ad65c2a7050417b92f404e980c3be1","name":"Seb Lenton"}]}},"_links":{"self":[{"href":"https:\/\/www.sebastianlenton.com\/wp-json\/wp\/v2\/posts\/382"}],"collection":[{"href":"https:\/\/www.sebastianlenton.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sebastianlenton.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sebastianlenton.com\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sebastianlenton.com\/wp-json\/wp\/v2\/comments?post=382"}],"version-history":[{"count":0,"href":"https:\/\/www.sebastianlenton.com\/wp-json\/wp\/v2\/posts\/382\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.sebastianlenton.com\/wp-json\/wp\/v2\/media\/399"}],"wp:attachment":[{"href":"https:\/\/www.sebastianlenton.com\/wp-json\/wp\/v2\/media?parent=382"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sebastianlenton.com\/wp-json\/wp\/v2\/categories?post=382"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sebastianlenton.com\/wp-json\/wp\/v2\/tags?post=382"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}