<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Barryvan &#187; Programming</title>
	<atom:link href="http://www.barryvan.com.au/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.barryvan.com.au</link>
	<description>Music, Programming, Design</description>
	<lastBuildDate>Sun, 08 Jan 2012 08:48:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>TrackPerformer step-by-step</title>
		<link>http://www.barryvan.com.au/2012/01/trackperformer-step-by-step/</link>
		<comments>http://www.barryvan.com.au/2012/01/trackperformer-step-by-step/#comments</comments>
		<pubDate>Sun, 08 Jan 2012 08:48:12 +0000</pubDate>
		<dc:creator>Barry van Oudtshoorn</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[TrackPerformer]]></category>

		<guid isPermaLink="false">http://www.barryvan.com.au/?p=672</guid>
		<description><![CDATA[I&#8217;ve had a request to put together a guide explaining exactly how to build a performance using TrackPerformer. This post will walk you through the process, from preparation to presentation. Please note that this guide assumes you are working with an Impulse Tracker or OpenMPT module; if you are not, you will have a bit [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve had a request to put together a guide explaining exactly how to build a performance using TrackPerformer. This post will walk you through the process, from preparation to presentation.</p>
<p>Please note that this guide assumes you are working with an Impulse Tracker or OpenMPT module; if you are not, you will have a bit more work to do.</p>
<h2>Ingredients</h2>
<p>To build your performance, you will need the following items:</p>
<ul>
<li>The original module file (IT or MPTM format)</li>
<li>The exported audio file (preferably in OGG, MP3, and M4A formats, for maximum cross-browser compatibility)</li>
<li>A copy of the ModReader source (which you can <a title="Download a ZIP file of the ModReader source" href="https://github.com/barryvan/modReader/zipball/master">download from GitHub</a>)</li>
<li>A copy of the TrackPerformer source (which you can also <a title="Download a ZIP file of the TrackPerformer source" href="https://github.com/barryvan/trackPerformer/zipball/master">download from GitHub</a>)</li>
<li>A decent plain text editor (not Word) &#8212; I recommed <a href="http://www.activestate.com/komodo-ide">Komodo IDE</a> or <a href="http://www.activestate.com/komodo-edit">Komodo Edit</a>.</li>
<li>A recent and decent web browser &#8212; Firefox, Chrome, or Opera work best.</li>
</ul>
<p>With these in hand, you&#8217;re ready to get going!</p>
<h2>Method</h2>
<h3>1. Set up</h3>
<p>If you haven&#8217;t already, extract TrackPerformer to the folder of your choice. When you do so, you&#8217;ll notice that there are several sub-directories: &#8220;Examples&#8221;, &#8220;Source&#8221;, and &#8220;Utilities&#8221;. Create a new directory, called &#8220;Performances&#8221;.</p>
<p>Copy the file &#8220;template.html&#8221; from the &#8220;Examples&#8221; directory, renaming it to the name of your track.</p>
<p>Next, copy your exported audio files into the &#8220;Performances&#8221; directory; ensure that they all have the same file name (bar the extension).</p>
<p>Create a new, blank file, with a &#8220;.js&#8221; extension and named the same as your track. Load this file in your editor.</p>
<p>Finally, load the HTML file in your editor, and add a &lt;script&gt; tag just before the closing &lt;/head&gt; tag that references your JS file. For example, if your JS file was named &#8220;purple.js&#8221;, you would type:</p>
<pre>&lt;script type="text/javascript" src="purple.js"&gt;&lt;/script&gt;</pre>
<h3> 2. Conversion</h3>
<p>The next step is to convert your file into a format that TrackPerformer understands. This means noting down when every note is played, and by which instrument. It also means extracting information such as the tempo, time signature, and song title.Fortunately, if you&#8217;re using an IT or MPTM module, the ModReader utility is able to perform this (rather tedious) step for you.</p>
<p><em>If you are not using a format that ModReader is able to convert, you will need to complete this step manually. If your file can be opened in OpenMPT, it is possible to use a JavaScript macro in Komodo IDE/Edit to facilitate this; otherwise, you will need to craft the entire lot by hand.</em></p>
<p>If you have not already done so, extract the ModReader zip file to a suitable location. Then, in your web browser, load the &#8220;index.html&#8221; file from that location.</p>
<p>Select the file you would like to convert. Note that ModReader does all of its processing on your computer &#8212; it doesn&#8217;t send your file anywhere, and won&#8217;t change its contents, either.</p>
<p>All going according to plan, there should now be a lot more text on-screen. Copy everything between the dashed lines (not including the lines), and paste it into your performance&#8217;s JS file. This is the TrackPerformer-compatible version of your module,in a format known as <a href="http://json.org/">JSON</a>.</p>
<h3>3. Write some JavaScript</h3>
<p>As I said earlier, ModReader gives you a JSON representation of your track, which is great. However, we need to now pass this representation through to TrackPerformer. To do this, we need to write some JavaScript to go around this JSON representation. Edit your JS file so that it looks something like this:</p>
<pre class="brush: javascript">window.addEvent(&#039;domready&#039;, function() {
	var controller = window.controller = new barryvan.tp.Controller({
		background: &#039;rgba(230,230,230,0.5)&#039;,
		meta: {
			colour: &#039;rgba(0,0,0,0.5)&#039;,
			visible: false
		}
	}, $(&#039;container&#039;) || document.body);
	controller.perform({
		title: &#039;Foo bar baz&#039;
		/* the rest of the track... */
	});
});</pre>
<p>What we&#8217;re doing here is creating a new Controller, and telling it to perform the track.</p>
<h3>4. Make some noise</h3>
<p>The next step is to point TrackPerformer at the MP3, OGG, and M4A exports of the music. To do this, find the line in your JS file that reads
<pre>"audio": ""</pre>
<p>. In the empty quotes, put in the filename of your audio (without any extension). If your audio is on the web, put in the full URL (again, without the extension). Your JS file will now look something like this:</p>
<pre class="brush: javascript">{
	/* snip */
	&quot;audio&quot;: &quot;mice&quot;
	/* snip */
}</pre>
<p>Now, load up your HTML file in your web browser. You should be able to listen to your track. Next up, we&#8217;ll add a performer.</p>
<h3>5. Add a performer</h3>
<p>Each instrument in your piece can have zero or more performers assigned to it. There are a variety of performers that you can use, each of which offers a unique visual representation of your music. Each performer has a variety of options which affect its function and appearance. These include colour, size, position, vitality, and many others.</p>
<p>Each performer is defined in a code block that looks something like this:</p>
<pre class="brush: javascript">{
	performer: barryvan.tp.performer.Oscillator,
	options: {
		colour: &#039;#f00&#039;,
		stepSize: 10,
		sustain: true,
		middle: 58
	}
}</pre>
<p>The block above means that we want an Oscillator <em>(performer: barryvan.tp.performer.Oscillator)</em>. We have set some of its options <em>(options: { &#8230; })</em> such that it is bright red <em>(colour: &#8216;#f00&#8242;)</em>, that a semitone is 10 pixels in size <em>(stepSize: 10)</em>, and that its middle note (vertically centred in the performance) is 58 <em>(middle: 58)</em>, or A#4.</p>
<p>If you look at your JS file, you should see a section labelled &#8220;instruments&#8221;, which will look something like this:</p>
<pre class="brush: javascript">&quot;instruments&quot;: [
	{
		&quot;name&quot;: &quot;Melody&quot;,
		&quot;performers&quot;: []
	}
]</pre>
<p>Put the performer&#8217;s code block between the [], like so:</p>
<pre class="brush: javascript">&quot;instruments&quot;: [
	{
		&quot;name&quot;: &quot;Melody&quot;,
		&quot;performers&quot;: [{
			performer: barryvan.tp.performer.Oscillator,
			options: {
				colour: &#039;#f00&#039;,
				stepSize: 10,
				sustain: true,
				middle: 58
			}
		}]
	}
]</pre>
<p>Now, if you reload your performance in your web browser, you should have something on-screen. You can add more performers to the other instruments in your piece in the same way. If you want more than one performer for the same instrument, you can simply place a comma after the closing brace of the performer block, and start the next one.</p>
<h3>6. Add some filters (optional)</h3>
<p>Filters can manipulate the entire presentation. They can, for example, shift pixels around, draw a grid, or simply calculate the framerate.</p>
<p>Filters are applied to each frame of the animation, and can be applied before or after the performers have been processed. Filters that are processed at the start of each frame go under &#8220;prefilters&#8221;; those processed at the end of each frame are entered under &#8220;postfilters&#8221;.</p>
<p>Let&#8217;s shift some pixels around using the &#8220;Pick&#8221; filter. Like performers, filters are defined in a block of code:</p>
<pre class="brush: javascript">{
	filter: barryvan.tp.filter.Pick,
	options: {
		fuzz: 2
	}
}</pre>
<p>We&#8217;ll add this into the &#8220;prefilters&#8221; section:</p>
<pre class="brush: javascript">&quot;prefilters&quot;: []</pre>
<p>becomes</p>
<pre class="brush: javascript">&quot;prefilters&quot;: [{
	filter: barryvan.tp.filter.Pick,
	options: {
		fuzz: 2
	}
}]</pre>
<p>If you reload your performance in your web browser, things should look a little more fuzzy.</p>
<p>Filters can have a huge impact on the overall &#8220;feel&#8221; of your performance. They can soften the performers&#8217; hard edges, and give the entire performance a more natural appearance.</p>
<h3>7. Present</h3>
<p>Once you&#8217;ve added more performers, adjusted colours, and fiddled with the CSS on your HTML file, you&#8217;re ready to take to the stage. Simply upload the &#8220;Source&#8221; directory and your performance to your webserver (making sure to keep relative paths intact), and publish the URL. You don&#8217;t need to do anything on the server: TrackPerformer is entirely client-side.</p>
<h3>8. Ask questions</h3>
<p>If you run into problems, or have a question, don&#8217;t hesitate to leave a comment or raise an issue on GitHub. You&#8217;re also more than welcome to fork the project, and build your own performers and filters &#8212; if they&#8217;re pulled back into the main TrackPerformer tree, then everyone else can use them, too!</p>
<h2>Appendix</h2>
<h3>A. Converting notes to numbers</h3>
<p>Notes are in the range C-0 to B-9, and are numbered from 0 to 119. To find the number for a particular note, use this formula: <i>x = note + (octave * 12)</i>. In this formula, the note C is 0, C# is 1, D is 2, and so on.</p>
<h3>B. TrackPerformer Wiki: performers, formats, etc.</h3>
<p>The <a href="https://github.com/barryvan/trackPerformer/wiki/_pages">TrackPerformer Wiki</a> has details on all of the <a href="https://github.com/barryvan/trackPerformer/wiki/Performers">performers</a>, the <a href="https://github.com/barryvan/trackPerformer/wiki/Performance-format">performance format</a>, the <a href="https://github.com/barryvan/trackPerformer/wiki/Filters">filters</a> that are available, and the <a href="https://github.com/barryvan/trackPerformer/wiki/Controller-options">controller options</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.barryvan.com.au/2012/01/trackperformer-step-by-step/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TrackPerformer update</title>
		<link>http://www.barryvan.com.au/2011/12/trackperformer-update/</link>
		<comments>http://www.barryvan.com.au/2011/12/trackperformer-update/#comments</comments>
		<pubDate>Sat, 17 Dec 2011 03:05:18 +0000</pubDate>
		<dc:creator>Barry van Oudtshoorn</dc:creator>
				<category><![CDATA[Albums]]></category>
		<category><![CDATA[Announcements]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[MooTools]]></category>
		<category><![CDATA[Music]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Web design]]></category>

		<guid isPermaLink="false">http://www.barryvan.com.au/?p=660</guid>
		<description><![CDATA[I&#8217;ve added in some really exciting new features to my TrackPerformer project, as well as three new performances: We Three Kings, Carol of the Bells, and Joy to the World. Filters It&#8217;s now possible to add filters, or effects, into the processing chain. These filters can be applied before any performers (pre-filters) or after all [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve added in some really exciting new features to my <a href="https://github.com/barryvan/trackPerformer">TrackPerformer</a> project, as well as three new performances: <strong><a href="http://barryvan.github.com/trackPerformer/kings.html">We Three Kings</a></strong>, <strong><a href="http://barryvan.github.com/trackPerformer/bells.html">Carol of the Bells</a></strong>, and <strong><a href="http://barryvan.github.com/trackPerformer/joy.html">Joy to the World</a></strong>.</p>
<h2>Filters</h2>
<p>It&#8217;s now possible to add filters, or effects, into the processing chain. These filters can be applied before any performers (pre-filters) or after all performers (post-filters). At the moment, the included filters are:</p>
<ul>
<li>FPS: Calculates the average framerate across the performance, optionally displaying it in a DOM element.</li>
<li>Grid: Draws a grid to the canvas. The grid may be a simple intersection grid (points), or lines. Both the X and Y axes may be independently configured.</li>
<li>Pick: Probably the most interesting (and processor-intensive) part of TrackPerformer. The Pick filter will randomly swap a pixel with one of its neighbours. It&#8217;s used at full intensity on both <a href="http://barryvan.github.com/trackPerformer/kings.html">We three Kings</a> and <a href="http://barryvan.github.com/trackPerformer/joy.html">Joy to the World</a>, and, when toned down a little for <a href="http://barryvan.github.com/trackPerformer/bells.html">Carol of the Bells</a>, provides a softening, organic effect.</li>
</ul>
<p>I&#8217;ve got some ideas for more filters down the track&#8230; The only difficulty is keeping performance acceptable: manipulation of the canvas pixel by pixel is quite slow in current browsers.</p>
<h2>Performers</h2>
<p>There are a couple of new performers, and some minor updates to some of the existing ones. The Oscillator performer, in particular, is rapidly becoming the most flexible and useful of the performers.</p>
<ul>
<li>There&#8217;s a new ShimmerGrid performer, which is great for adding texture and movement to the entire canvas. You can see it in action particularly well on <a href="http://barryvan.github.com/trackPerformer/joy.html">Joy to the World</a>.</li>
<li>The Swarm performer can now draw its particles as knots (like the SignalTracker), as well as as dots.</li>
<li>The Oscillator now has the ability to draw sustained notes, and to increase the longevity of notes. Take a look at <a href="http://barryvan.github.com/trackPerformer/bells.html">Carol of the Bells</a> to see these new options in use.</li>
<li>Notes can now be filtered based not only on their pitch, but also their velocity (volume).</li>
</ul>
<p>There are a couple of other changes here and there, but these are the main ones.</p>
<h2>We Three Kings</h2>
<p>The three new example tracks are all taken from <a href="http://barryvan.bandcamp.com/album/we-three-kings">We Three Kings</a>, my new Christmas remix album. Why not go and have a listen?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.barryvan.com.au/2011/12/trackperformer-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TrackPerformer</title>
		<link>http://www.barryvan.com.au/2011/10/trackperformer/</link>
		<comments>http://www.barryvan.com.au/2011/10/trackperformer/#comments</comments>
		<pubDate>Thu, 27 Oct 2011 13:05:15 +0000</pubDate>
		<dc:creator>Barry van Oudtshoorn</dc:creator>
				<category><![CDATA[Free music downloads]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[MooTools]]></category>
		<category><![CDATA[Music]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.barryvan.com.au/?p=645</guid>
		<description><![CDATA[TrackPerformer provides a visual stage for your music, using HTML5 canvas and audio. On that stage, performers &#8220;play&#8221; the instruments in the music visually. In other words, it&#8217;s a visualisation system for music, but based on the notation (the abstract) rather than the audio (the manifestation). Essentially, you take a piece of music, convert it [...]]]></description>
			<content:encoded><![CDATA[<p>TrackPerformer provides a visual stage for your music, using HTML5 canvas and audio. On that stage, performers &#8220;play&#8221; the instruments in the music visually. In other words, it&#8217;s a visualisation system for music, but based on the notation (the abstract) rather than the audio (the manifestation).</p>
<p>Essentially, you take a piece of music, convert it into a format that TrackPerformer understands (JSON), describe how you want it to be performed, and then watch! You can, of course, write your own performers.</p>
<div style="padding:8px;margin:0 24px;background:rgba(255,255,255,0.25);border:solid 1px;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;">Before going any further, let&#8217;s <a href="http://barryvan.github.com/trackPerformer/colony.html">see it in action</a>. The music is &#8220;Colony&#8221;, a new piece that I wrote about a week ago.</div>
<p>Note: You won&#8217;t be able to view the performance linked above in Internet Explorer, due to its over-aggressive script-blocking: the scripts served from GitHub have the wrong mime-type, so IE won&#8217;t let them run.</p>
<p><a href="https://github.com/barryvan/trackPerformer">Take a look at the project on GitHub</a> to see how it all fits together. TrackPerformer itself resides in the &#8220;Source&#8221; directory; in &#8220;Examples&#8221;, you&#8217;ll find <a href="http://barryvan.github.com/trackPerformer/colony.html">the performance of Colony</a>; in &#8220;Utilities&#8221;, there&#8217;s a JavaScript macro for Komodo IDE/Edit that will help you to translate copied-and-pasted OpenMPT pattern data into TrackPerformer&#8217;s JSON format.</p>
<p>You can find more information on <a href="https://github.com/barryvan/trackPerformer/wiki">the TrackPerformer wiki</a>, including an outline of the format, and some basic instructions for getting started. I&#8217;ll be adding more information to the wiki over the next few days, and I&#8217;ll post updates here too.</p>
<p>Let me know what you think!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.barryvan.com.au/2011/10/trackperformer/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>(Un)quoted HTML attributes</title>
		<link>http://www.barryvan.com.au/2011/08/unquoted-html-attributes/</link>
		<comments>http://www.barryvan.com.au/2011/08/unquoted-html-attributes/#comments</comments>
		<pubDate>Sun, 07 Aug 2011 07:23:22 +0000</pubDate>
		<dc:creator>Barry van Oudtshoorn</dc:creator>
				<category><![CDATA[HTML]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.barryvan.com.au/?p=607</guid>
		<description><![CDATA[In HTML, it&#8217;s perfectly valid to write something like this: &#60;p class=alpha&#62;Lorem ipsum dolor sit amet etc.&#60;/p&#62; Indeed, Internet Explorer 7 and 8 favour this approach. Whereas Firefox, for example, would return the above as &#60;p class=&#34;alpha&#34;&#62;Lorem ipsum dolor sit amet etc.&#60;/p&#62; when retrieving it using innerHTML, IE 7 &#38; 8 only quotes attributes that [...]]]></description>
			<content:encoded><![CDATA[<p>In HTML, it&#8217;s perfectly valid to write something like this:</p>
<pre class="brush: html">&lt;p class=alpha&gt;Lorem ipsum dolor sit amet etc.&lt;/p&gt;</pre>
<p>Indeed, Internet Explorer 7 and 8 favour this approach. Whereas Firefox, for example, would return the above as</p>
<pre class="brush: html">&lt;p class=&quot;alpha&quot;&gt;Lorem ipsum dolor sit amet etc.&lt;/p&gt;</pre>
<p>when retrieving it using innerHTML, IE 7 &amp; 8 only quotes attributes that satisfy certain criteria:</p>
<ul>
<li>Any attributes that contain spaces;</li>
<li>Some magic set of standard attributes, such as <i>href</i>;</li>
<li>Any custom attributes you may have specified.</li>
</ul>
<p>Unfortunately, however, this doesn&#8217;t constitute well-formed XML. In the software I develop at work, we produce PDFs that can include user-generated HTML. To do this, we use XSL:FO &#8212; an XML-based system. You can see where this is going: the backend requires valid XML, but the frontend is sending through HTML. The simplest way to fix this is with a simple regex, like so:</p>
<pre class="brush: javascript">var s = &#039;&lt;p class=alpha&gt;Lorem ipsum dolor sit amet etc.&lt;/p&gt;&#039;;
s = s.replace(/=([^&quot;&#039;`&gt;\s]+)/g, &#039;=&quot;$1&quot;&#039;);
// s === &#039;&lt;p class=&quot;alpha&quot;&gt;Lorem ipsum dolor sit amet etc.&lt;/p&gt;&#039;</pre>
<p>Bear in mind that this regex is by no means perfect. It will, for example, convert this:</p>
<pre class="brush: html">&lt;p class=alpha&gt;Lorem ipsum&lt;/p&gt;
&lt;p&gt;dolor sit=amet&lt;/p&gt;</pre>
<p>into this:</p>
<pre class="brush: html">&lt;p class=&quot;alpha&quot;&gt;Lorem ipsum&lt;/p&gt;
&lt;p&gt;dolor sit=&quot;amet&lt;/p&quot;&gt;.</pre>
<p>&#8230;which is obviously not what we want. I spent a while trying to come up with a regex that would solve this problem, but I stopped pretty soon. What&#8217;s really needed here is a parser: something that can take in the tag soup that Internet Explorer produces, and produce valid XHTML (which is valid XML). A quick search reveals myriad implementations in various languages &#8212; Python, Java, even JavaScript.</p>
<p>So, after all that, what&#8217;s the take-away from this post? Just this: web browsers (slightly older versions of Internet Explorer in particular) are imperfect. XML was borne out of HTML, and is much less forgiving; whether or not its strictness is a good thing is up for debate. I guess that it&#8217;s a bit like reading Shakespeare nowadays: you can pretty much understand it, but every now and then you have to reach for a dictionary to make sense of what&#8217;s going on. Of course, when you don&#8217;t understand something in Shakespeare, you don&#8217;t fall over in a heap, but let&#8217;s not stretch the analogy too far.</p>
<h2>In brief</h2>
<p>When retrieving the innerHTML of an element (or using contenteditable), Internet Explorer doesn&#8217;t always wrap attribute values in quotes. The solution to this is not a magnificently obtuse regex, but a tag-soup parser that can return valid XML.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.barryvan.com.au/2011/08/unquoted-html-attributes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CSSMin updated</title>
		<link>http://www.barryvan.com.au/2011/01/cssmin-updated/</link>
		<comments>http://www.barryvan.com.au/2011/01/cssmin-updated/#comments</comments>
		<pubDate>Thu, 13 Jan 2011 00:56:53 +0000</pubDate>
		<dc:creator>Barry van Oudtshoorn</dc:creator>
				<category><![CDATA[Announcements]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Web design]]></category>

		<guid isPermaLink="false">http://www.barryvan.com.au/?p=547</guid>
		<description><![CDATA[I&#8217;ve updated my CSSMin project with a couple of new features and bugfixes. Download or fork it on GitHub! What is it? CSSMin takes your CSS file and strips out everything that&#8217;s not needed &#8212; spaces, extra semicolons, redundant units, and so on. That&#8217;s great, but there are loads of programs that do that. A [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve updated my CSSMin project with a couple of new features and bugfixes. <a href="https://github.com/barryvan/CSSMin">Download or fork it on GitHub!</a></p>
<h2>What is it?</h2>
<p>CSSMin takes your CSS file and strips out everything that&#8217;s not needed &#8212; spaces, extra semicolons, redundant units, and so on. That&#8217;s great, but there are loads of programs that do that. A shell script could do that! So what makes CSSMin different?</p>
<p>When you deliver content over the web, best practice is to deliver it gzipped. CSSMin takes your CSS file, and optimises it for gzip compression. This means that there&#8217;s a smaller payload delivered over the wire, which results in a faster experience for your users. It does this optimisation by ensuring that the properties inside your selectors are ordered consistently (alphabetically) and in lower case. That way, the gzip algorithm can work at its best.</p>
<p>What this means in practice is that your gzipped CSSMin-ed files are significantly smaller than plain gzipped CSS, and noticeably smaller than files that have been compressed by other means (say, YUI).</p>
<h2>In this update:</h2>
<h3>Nested properties are now fully supported.</h3>
<p>This means that the following CSS:</p>
<pre class="brush: css">@-webkit-keyframes &#039;fadeUp&#039; {
  from { opacity: 0; }
  to { opacity: 1; }
}</pre>
<p>is compressed down to</p>
<pre class="brush: css">@-webkit-keyframes &#039;fadeUp&#039;{from{opacity:0}to{opacity:1}}</pre>
<p>Your nested properties will have their contents compressed with all of the other tricks in system, but their order will be retained.</p>
<p>Thanks to <a href="https://github.com/bloveridge">bloveridge</a> for reporting this bug and verifying the fix.</p>
<h3>Font weights are replaced by their numeric counterparts.</h3>
<pre class="brush: css">.alpha {
  font-weight: bold;
}
.beta {
  font-weight: normal;
}</pre>
<p>becomes</p>
<pre class="brush: css">.alpha{font-weight:700}.beta{font-weight:400}</pre>
<p>Values supported are &#8220;lighter&#8221;, &#8220;normal&#8221;, &#8220;bold&#8221;, and &#8220;bolder&#8221;.</p>
<h3>Quotes are stripped where possible.</h3>
<pre class="brush: css">.alpha {
  background: url(&#039;ponies.png&#039;);
  font-family: &#039;Times New Roman&#039;, &#039;Arial&#039;;
}</pre>
<p>becomes</p>
<pre class="brush: css">.alpha{background:url(ponies.png);font-family:&#039;Times New Roman&#039;,arial}</pre>
<h3>As much text as possible is changed to lower-case.</h3>
<p>Only selectors, quoted strings (such as &#8216;Times New Roman&#8217;) and url() values are left intact.</p>
<p>Note that this means that if you mix the case of your selectors (for example, SPAN and span), your compression will be sub-optimal.</p>
<h3>Thanks</h3>
<p>Some of the ideas for this update were inspired by <a href="http://www.lotterypost.com/css-compress.aspx">Lottery Post&#8217;s CSS Compressor</a>.</p>
<h2>Start using it!</h2>
<h3>Requirements</h3>
<p>You will need a recent version of Java and the Java compiler.</p>
<h3>Download</h3>
<p><a href="https://github.com/barryvan/CSSMin">Download or fork it on GitHub.</a></p>
<h3>Usage</h3>
<ol>
<li>Compile the Java:
<pre class="brush: php"># javac CSSMin.java</pre>
</li>
<li>Run your CSS through it:
<pre class="brush: php"># java CSSMin [input] [output]</pre>
</li>
</ol>
<p>If you don&#8217;t specify an output file, the result will be dumped to stdout. Warnings and errors are written to stderr.</p>
<h2>Results</h2>
<p>These are the results of compressing the main CSS file for one of the webapps I develop at work. Note that many of these compressors only offer an online service, which means that they can&#8217;t easily be used as part of your general build process.</p>
<table class="comparison">
<thead>
<tr>
<td>&nbsp;</td>
<td>Original size (bytes)</td>
<td>Gzipped size (bytes)</td>
</tr>
</thead>
<tbody>
<tr>
<td>Plain</td>
<td>81938</td>
<td>12291</td>
</tr>
<tr>
<td><a href="http://developer.yahoo.com/yui/compressor/">YUI</a></td>
<td>64434</td>
<td>10198</td>
</tr>
<tr>
<td><a href="http://www.lotterypost.com/css-compress.aspx">LotteryPost</a></td>
<td>63609</td>
<td>10165</td>
</tr>
<tr>
<td><a href="http://www.cssdrive.com/compressor/compress_advanced.php">CSS Drive</a></td>
<td>69275</td>
<td>10795</td>
</tr>
<tr>
<td><a href="https://github.com/barryvan/CSSMin">CSSMin</a></td>
<td>63791</td>
<td>9896</td>
</tr>
</tbody>
</table>
<h2>Feedback</h2>
<p>Let me know how you go with it &#8212; bug reports and feature requests are always welcome!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.barryvan.com.au/2011/01/cssmin-updated/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Theme update (again!)</title>
		<link>http://www.barryvan.com.au/2010/08/theme-update-again/</link>
		<comments>http://www.barryvan.com.au/2010/08/theme-update-again/#comments</comments>
		<pubDate>Mon, 23 Aug 2010 04:12:48 +0000</pubDate>
		<dc:creator>Barry van Oudtshoorn</dc:creator>
				<category><![CDATA[Announcements]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Web design]]></category>

		<guid isPermaLink="false">http://www.barryvan.com.au/?p=474</guid>
		<description><![CDATA[And so, for the third time this year, I&#8217;ve completely re-themed this site. Taking a very different tack from the last theme, I&#8217;ve tried to keep this one as simple as possible, with just a few subtle touches here and there to add interest. The palette is more subdued, which hopefully means that reading the [...]]]></description>
			<content:encoded><![CDATA[<p>And so, for the third time this year, I&#8217;ve completely re-themed this site. Taking a very different tack from the last theme, I&#8217;ve tried to keep this one as simple as possible, with just a few subtle touches here and there to add interest. The palette is more subdued, which hopefully means that reading the text is a more pleasant experience. I&#8217;ve also done away with the multi-column body text in favour of a fixed-width design.</p>
<p>At the same time, though, I have endeavoured to use some of the new features available in modern web browsers &#8212; gradients, shadows, transitions, generated content, and so on. I&#8217;m fairly happy with the result &#8212; I think it&#8217;s a clean, unobtrusive theme that&#8217;s not too in your face. Feedback and criticism welcome! <img src='http://www.barryvan.com.au/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.barryvan.com.au/2010/08/theme-update-again/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Paired sort in JavaScript</title>
		<link>http://www.barryvan.com.au/2010/08/paired-sort-in-javascript/</link>
		<comments>http://www.barryvan.com.au/2010/08/paired-sort-in-javascript/#comments</comments>
		<pubDate>Thu, 19 Aug 2010 01:42:06 +0000</pubDate>
		<dc:creator>Barry van Oudtshoorn</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[MooTools]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.barryvan.com.au/?p=467</guid>
		<description><![CDATA[Sometimes, you&#8217;ll have two arrays of associated data, and you&#8217;ll need to sort them. You can&#8217;t just call sort() on both arrays, because that will potentially break the associations between them. What you need is a way to sort one of the arrays, and shuffle the elements of the second array to match. Here&#8217;s a [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes, you&#8217;ll have two arrays of associated data, and you&#8217;ll need to sort them. You can&#8217;t just call sort() on both arrays, because that will potentially break the associations between them. What you need is a way to sort one of the arrays, and shuffle the elements of the second array to match. Here&#8217;s a simple MooTools function that does just that (using quicksort):</p>
<pre class="brush: javascript">Array.implement({
	pairedSort: function(other, reverse) {
		if (this.length === other.length) {
			for (var i = 0, len = this.length; i &lt; len; i++) {
				var curr = this[i];
				var currOth = other[i];
				var j = i - 1;
				while ((j &gt;= 0) &amp;&amp; (this[j] &gt; curr)) {
					this[j + 1] = this[j];
					other[j + 1] = other[j];
					j--;
				}
				this[j + 1] = curr;
				other[j + 1] = currOth;
			}
		}
		if (reverse) {
			this.reverse();
			other.reverse();
		}
		return this;
	}
});</pre>
<p>Using this function is quite straightforward:</p>
<pre class="brush: javascript">var alpha = [3,2,1,6,5,4];
var beta = [1,2,3,4,5,6];
alpha.pairedSort(beta);
// alpha == [1,2,3,4,5,6]
// beta == [3,2,1,6,5,4]</pre>
<p>When would this actually be useful? Let&#8217;s say you&#8217;ve got an object which maps numeric assessment scores to an alphabetic grade:</p>
<pre class="brush: javascript">var mapping = {
  &#039;A&#039;: 80,
  &#039;B&#039;: 60,
  &#039;C&#039;: 40,
  &#039;D&#039;: 20,
  &#039;E&#039;: 0
}</pre>
<p>Unfortunately, objects in JavaScript have no intrinsic order on their keys &#8212; this is because they&#8217;re essentially just hashmaps. What we need to do to be able to make use of these data, then, is create an array of keys, and one of values, and then sort them. The pairedSort() function allows us to do this easily. (In fact, it&#8217;s for this exact application that I wrote the method!)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.barryvan.com.au/2010/08/paired-sort-in-javascript/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>JS1K: Swarms</title>
		<link>http://www.barryvan.com.au/2010/08/js1k-swarms/</link>
		<comments>http://www.barryvan.com.au/2010/08/js1k-swarms/#comments</comments>
		<pubDate>Fri, 13 Aug 2010 03:35:04 +0000</pubDate>
		<dc:creator>Barry van Oudtshoorn</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.barryvan.com.au/?p=458</guid>
		<description><![CDATA[In the spirit of the demoscene, the JS1K competition is designed to make people push their boundaries. The competition requires entrants to write an interesting, appealing demo in JavaScript, using no more than 1024 characters (hence the name). Of course, I had to have a shot at it. (See the result!) I decided to revisit [...]]]></description>
			<content:encoded><![CDATA[<p>In the spirit of the <a href="http://en.wikipedia.org/wiki/Demoscene">demoscene</a>, the JS1K competition is designed to make people push their boundaries. The competition requires entrants to write an interesting, appealing <a href="http://en.wikipedia.org/wiki/Demo_%28computer_programming%29">demo</a> in JavaScript, using no more than 1024 characters (hence the name).</p>
<p>Of course, I had to have a shot at it. (<a href="http://js1k.com/demo/270">See the result!</a>) I decided to revisit one of my favourite toy projects: my swarms. What I came up with is this (linebreaks added for convenience):</p>
<pre class="brush: javascript">a=Math,b=a.random,c=[],j=document.getElementById(&quot;c&quot;),k=j.getContext(&quot;2d&quot;),m=window,n=(W=m.innerWidth)/2,q=(H=m.innerHeight)/2,r=M=1;function s(o,p,u,v){k.fillStyle=o;k.beginPath();k.arc(p,u,v,0,a.PI*2,0);k.closePath();k.fill()}function t(o,p){for(g=40;g--;)if(!c[g]){c[g]={x:o||n,y:p||q,d:o?b()*4-2:0,e:p?b()*4-2:0,b:1,a:0,c:b()&gt;.5};return}}with(j.style){position=&quot;fixed&quot;;top=left=0}j.width=W;j.height=H;for(f=40;f--;)c[f]=0;for(f=9;f--;)t(); m.setInterval(function(){k.fillStyle=&quot;rgba(9,9,9,.2)&quot;;k.fillRect(0,0,W,H);for(f=40;f--;)if(d=c[f])if(d.a&gt;1E3)c[f]=0;else{l=d.a/1E3;h=l*7;d.d+=b()*.1*(n-d.x&gt;1?1:n-d.x&lt;-1?-1:n-d.x);d.e+=b()*.1*(q-d.y&gt;1?1:q-d.y&lt;-1?-1:q-d.y);d.x+=d.d;d.y+=d.e;d.a++;i=d.c?&quot;rgba(49,153,255,&quot;:&quot;rgba(255,49,166,&quot;;h=1-l;s(i+h+&quot;)&quot;,d.x,d.y,1+l*12);s(i+h/2+&quot;)&quot;,d.x,d.y,1+l*16);d.b&amp;&amp;d.b--;if(d.b==0&amp;&amp;d.a&gt;250&amp;&amp;d.a&lt;750&amp;&amp;b()&gt;.9)for(g=40;g--&amp;&amp;!d.b;)if((e=c[g])&amp;&amp;e!=d&amp;&amp;e.a&gt;=d.a){i=a.sqrt(d.x-e.x,d.y-e.y);if(i&gt;-5&amp;&amp;i&lt;5&amp;&amp;d.c!=e.c){t(d.x, d.y);d.b=e.b=10}}}r=n&gt;W||n&lt;0?-r:r;M=q&gt;H||q&lt;0?-M:M;n+=r;q+=M},40);</pre>
<p>You can see the submission <a href="http://js1k.com/demo/270">here: http://js1k.com/demo/270</a>. To reduce the size, I first coded tightly, ran the uncompressed code through Google&#8217;s <a href="http://code.google.com/p/closure-compiler/">Closure Compiler</a>, then hand-tweaked the result to save a few more bytes. I&#8217;m quite pleased with the result! For the curious, the full, uncompressed, commented source is below:</p>
<pre class="brush: javascript">/* SWARMS (v1.7)
 * by Barry van Oudtshoorn (www.barryvan.com.au)
 * A re-implementation of http://www.barryvan.com.au/demos/swarms/swarms.html,
 * which in turn is a reimplementation of a Processing script that I wrote.
 *
 * Male and female particles move around a central point, gradually aging.
 * When they reach maturity, they may interact with a particle of the opposite
 * sex to spawn a new particle. As they grow old, they become larger and slower
 * until they eventually die.
 *
 * Revisions (really, these version numbers are all but meaningless!)
 * 1.0 (1023B)
 *     - Initial code.
 * 1.5 (1017B)
 *     - Moved to Closure compiler to reduce size
 *     - Some slight tweaks to particle movement
 *     - Canvas now positioned to get rid of annoying border (try fullscreen!)
 * 1.7 (1011B)
 *     - The swarm centre now moves around (simple bouncing). This allows the
 *         particles to pick up a bit more speed, and move in more interesting ways;
 *         where before they tended to just &#039;bubble&#039; in the middle of the screen,
 *         the swarm, as an entity, now appears more fluid and organic.
 *     - Bugfix to spawning: particles now actually have to be near to each other
 *         in BOTH axes to spawn, and both particles have to be of suitable age. This
 *         prevents billions of particles from spawning from a single one.
 *     - Reduced the total number of particles for aesthetic reasons
 *     - Did some more &quot;by-hand&quot; optimisations after running it through the closure
 *         compiler, like removing global variable declarations when I&#039;m not
 *         instantiating the variables there and then and removing the leading 0 on
 *         decimal values to conserve precious bytes. With each revision, despite
 *         adding functionality each time, the size is going down!
 *
 * Copyright 2010 Barry van Oudtshoorn.
 */

var z = function(a, b, c) { // Normalise a to between b and c
    return (a / (c - b));
},
h = function(a, b, c) { // Limx a to between b and c
    return (a &gt; b ? b : (a &lt; c ? c : a));
},
// I strip out all of the uninitialised declarations after compilation;
// they&#039;re globals anyway. I know it&#039;s not stylish, but it saves bytes!
r,s, // Particles that we&#039;re currently interested in
i,j, // Iterators
u,d, // Working variables
m = Math, // Alias
v = m.random, // Alias
p = [], // The particles
e = document.getElementById(&#039;c&#039;), // The canvas element
t = e.getContext(&#039;2d&#039;), // The context
n, // The normalised age of a particle
Q = window, // Alias
X = (W = Q.innerWidth)/2, // The swarm&#039;s COG
Y = (H = Q.innerHeight)/2,
N = M = 1, // The components of the velocity of the swarm&#039;s COG
q = function(a, b, c, f) { // Draw a blob
    t.fillStyle = a;
    t.beginPath();
    t.arc(b, c, f, 0, m.PI*2, 0);
    t.closePath();
    t.fill();
},

x = function() { // Global iterator
    //t.globalCompositeOperation = &#039;source-over&#039;; // This is prettier, but &quot;globalCompositeOperation&quot; takes too many bytes!
    t.fillStyle = &#039;rgba(9,9,9,.2)&#039;;
    t.fillRect(0,0,W,H);
    //t.globalCompositeOperation = &#039;lighter&#039;;

    for (i = 40; i--;) { // Loop over all of the particles
        if (r = p[i]) {
            if (r.a &gt; 1E3) {
                p[i] = 0; // Kill off old particles; use 0 because it&#039;s shorter than false, null, or using delete.
            } else {
                // Move the particle
                n = z(r.a, 0, 1E3);
                u = n * 7;
                r.X += v() * .1 * h(X - r.x, 1, -1); // Update the particle&#039;s velocity.
                r.Y += v() * .1 * h(Y - r.y, 1, -1);
                r.x += r.X; // Update the particle&#039;s coordinates based on its velocity.
                r.y += r.Y;
                r.a++; // Increment the particle&#039;s age

                // Draw the particle

                d = r.s ? &#039;rgba(49,153,255,&#039; : &#039;rgba(255,49,166,&#039;; // The colour of the particle
                u = 1 - n; // The opacity of the particle; n is the normalised age
                q(d + u + &#039;)&#039;, r.x, r.y, 1 + n * 12); // Draw the primary particle blob
                q(d + (u/2) + &#039;)&#039;, r.x, r.y, 1 + n * 16); // We draw a lighter, larger blob for a &#039;glow&#039; effect

                r.f &amp;&amp; r.f--; // If we&#039;ve spawned, decrement the cooldown.

                if (r.f == 0 &amp;&amp; r.a &gt; 250 &amp;&amp; r.a &lt; 750 &amp;&amp; v() &gt; 0.9) { // If we&#039;re the right age, check if we can spawn!
                    for (j = 40; j-- &amp;&amp; !r.f;) { // We have to loop over the particles again, and see if we&#039;re close enough to spawn.
                        if ((s = p[j]) &amp;&amp; s != r &amp;&amp; s.a &gt;= r.a) {
                            d = m.sqrt(r.x - s.x, r.y - s.y); // Two if statements to avoid this calculation if possible
                            if (d &gt; -5 &amp;&amp; d &lt; 5 &amp;&amp; r.s != s.s) { // Collision detection? What&#039;s that?
                                y(r.x, r.y); // Spawn a new particle!
                                r.f = s.f = 10; // Enforce the spawning cooldown
                            }
                        }
                    }
                }
            }
        }
    }

    // Bounce the swarm&#039;s COG around the canvas
    N = (X &gt; W || X &lt; 0 ? -N : N);
    M = (Y &gt; H || Y &lt; 0 ? -M : M);
    X += N;
    Y += M;
},

// Spawn a new particle. If sx and sy are defined, they will be its initial
// coordinates; otherwise, we just the COG. If sx and sy are defined, we also
// give the particle a random velocity; this means that they&#039;re &#039;flung out&#039;
// from their parents; at startup, though, we want them all nicely bunched.
y = function(sx,sy) {
    for (j = 40; j--;) {
        if (!p[j]) {
            p[j] = {
                x: sx || X, // The particle&#039;s coords
                y: sy || Y,
                X: sx ? v() * 4 - 2: 0, // The particles velocity
                Y: sy ? v() * 4 - 2 : 0,
                f: 1, // Cooldown after spawning
                a: 0, // The age of the particle
                s: v() &gt; .5 // The sex of the particle
            }
            return;
        }
    }
};

// Make the canvas fill the entire screen
with (e.style) {
    position = &#039;fixed&#039;;
    top = left = 0;
}
e.width = W; // Set the canvas width and height
e.height = H;

for (i = 40; i--;) p[i] = 0; // Populate initial particles
for (i = 9; i--;) y(); // Spawn eight particles. A number &lt; 10 saves a byte!

Q.setInterval(x, 40); // Make it go. </pre>
]]></content:encoded>
			<wfw:commentRss>http://www.barryvan.com.au/2010/08/js1k-swarms/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Generative Music</title>
		<link>http://www.barryvan.com.au/2010/03/generative-music/</link>
		<comments>http://www.barryvan.com.au/2010/03/generative-music/#comments</comments>
		<pubDate>Sun, 21 Mar 2010 08:08:11 +0000</pubDate>
		<dc:creator>Barry van Oudtshoorn</dc:creator>
				<category><![CDATA[Ambient]]></category>
		<category><![CDATA[Chillout]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[MooTools]]></category>
		<category><![CDATA[Music]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Web design]]></category>

		<guid isPermaLink="false">http://www.barryvan.com.au/?p=443</guid>
		<description><![CDATA[Continuing my HTML5 and canvas experiments, I&#8217;ve put together a generative music system. Essentially, a series of particles move across a field, occasionally triggering sounds &#8212; the sound triggered depends on their location in the field. There is, of course, a little bit more to it than that. Under the hood, I&#8217;ve got a series [...]]]></description>
			<content:encoded><![CDATA[<p>Continuing my HTML5 and canvas experiments, I&#8217;ve put together a generative music system. Essentially, a series of particles move across a field, occasionally triggering sounds &#8212; the sound triggered depends on their location in the field.</p>
<p>There is, of course, a little bit more to it than that. Under the hood, I&#8217;ve got a series of HTML5 Audio objects that are used to provide polyphonic audio using a simple round-robin algorithm (I encoded the audio in OGG, so you&#8217;ll need to use an OGG-friendly browser, like <a href="http://www.getfirefox.com">Firefox</a>). The particles are much simpler than those in my <a href="/2010/03/canvas-swarms/">previous canvas dalliance</a>, in that they don&#8217;t swarm, and their motion is more linear.</p>
<div class="screenshots">
<a href="/demos/generative.html"><br/><br />
<img alt="Generative Audio Screenshot" src="/wp-content/uploads/2010/03/generative.png" class="aligncenter size-full"/><br/><br />
View (and hear!) it live<br/><br />
</a>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.barryvan.com.au/2010/03/generative-music/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Canvas Swarms</title>
		<link>http://www.barryvan.com.au/2010/03/canvas-swarms/</link>
		<comments>http://www.barryvan.com.au/2010/03/canvas-swarms/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 00:27:18 +0000</pubDate>
		<dc:creator>Barry van Oudtshoorn</dc:creator>
				<category><![CDATA[HTML]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[MooTools]]></category>
		<category><![CDATA[Processing]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web design]]></category>

		<guid isPermaLink="false">http://www.barryvan.com.au/?p=440</guid>
		<description><![CDATA[I&#8217;ve been meaning to start playing with the HTML5 &#60;canvas&#62; element for a while now, and yesterday I took the opportunity. I translated a Processing sketch I made a while ago into JavaScript (with a few minor enhancements). View it live Essentially, 1 to 3 swarms of particles move around the canvas, reproducing when the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been meaning to start playing with the HTML5 &lt;canvas&gt; element for a while now, and yesterday I took the opportunity. I translated a Processing sketch I made a while ago into JavaScript (with a few minor enhancements).</p>
<div class="screenshots">
<a href="/demos/swarms/swarms.html"><br />
<img class="aligncenter size-full" src="/demos/swarms/swarms.png" alt="Swarms Screenshot"/><br />
View it live<br />
</a>
</div>
<p>Essentially, 1 to 3 swarms of particles move around the canvas, reproducing when the conditions are just right, and dying of old age. Quite simple, but the patterns produced can be really quite pretty.</p>
<p>One interesting thing that I discovered whilst doing this is that you can&#8217;t pass around a canvas&#8217; context at the instantiation of a MooTools class &#8212; it complains about wrapped natives. That&#8217;s why, if you like in the source JavaScript, you&#8217;ll see me pass the actual context around to various functions. I&#8217;d be interested in hearing if anyone has a workaround for this, because this is, well, a bit clunky.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.barryvan.com.au/2010/03/canvas-swarms/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

