<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Acko.net]]></title>
  <link href="http://acko.net/atom.xml" rel="self"/>
  <link href="http://acko.net/"/>
  <updated>2012-05-09T00:20:38-07:00</updated>
  <id>http://acko.net/</id>
  <author>
    <name><![CDATA[Steven Wittens]]></name>
    
  </author>

  
  <entry>
    <title type="html"><![CDATA[My JS1K Demo - The Making Of]]></title>
    <link href="http://acko.net/blog/js1k-demo-the-making-of/"/>
    <updated>2010-08-06T00:00:00-07:00</updated>
    <id>http://acko.net/blog/js1k-demo-the-making-of</id>
    <content type="html"><![CDATA[<div class='g8 i2 first'><div class='pad'>
  
<h1>My JS1K Demo - The Making Of</h1>

<p>If you haven't seen it yet, check out the <a href='http://js1k.com'>JS1K demo contest</a>. The goal is to do something neat in 1 kilobyte of JavaScript code.</p>
<p>I couldn't resist making one myself, so I pulled out my bag of tricks from my <a href='/design/avs'>Winamp music visualization</a> days and started coding. I'm really happy with how it turned out. And no, it won't work in Internet Explorer 8 or less.</p>

<p><em>Edit: OH SNAP! I just rewrote the demo to include volumetric light beams and still fit in 1K:</em></p>

</div></div><div class='g6'><div class='pad'>

<h3>Original Version</h3>
<p><iframe frameborder='0' height='345' id='1kjs' src='about:blank' style='background:#000;border:0' width='510' /></p>
<p><button id='1kjs-stop' onclick='$(&apos;#1kjs&apos;).attr(&apos;src&apos;,&apos;about:blank&apos;);$(this).hide();$(&apos;#1kjs-start&apos;).show();' style='display: none'>Stop Demo</button><button id='1kjs-start' onclick='$(&apos;#1kjs&apos;).attr(&apos;src&apos;,&apos;/files/making-of-js1k/1022b.html&apos;);$(this).hide();$(&apos;#1kjs-stop&apos;).show();'>Start Demo</button><button onclick='$(&apos;#1kjs&apos;).attr(&apos;src&apos;,&apos;/files/making-of-js1k/1022s.html&apos;);$(&apos;#1kjs-start&apos;).show();$(&apos;#1kjs-stop&apos;).hide();'>View Source</button></p>

</div></div><div class='g6'><div class='pad'>

<h3>Improved Version</h3>

<p><iframe frameborder='0' height='345' id='1kjs2' src='about:blank' style='background:#000;border:0' width='510' /></p>
<p><button id='1kjs2-stop' onclick='$(&apos;#1kjs2&apos;).attr(&apos;src&apos;,&apos;about:blank&apos;);$(this).hide();$(&apos;#1kjs2-start&apos;).show();' style='display: none'>Stop Demo</button><button id='1kjs2-start' onclick='$(&apos;#1kjs2&apos;).attr(&apos;src&apos;,&apos;/files/making-of-js1k/1024b.html&apos;);$(this).hide();$(&apos;#1kjs2-stop&apos;).show();'>Start Demo</button><button onclick='$(&apos;#1kjs2&apos;).attr(&apos;src&apos;,&apos;/files/making-of-js1k/1024s.html&apos;);$(&apos;#1kjs2-start&apos;).show();$(&apos;#1kjs2-stop&apos;).hide();'>View Source</button></p>

</div></div><div class='g8 i2'><div class='pad'>

<p>Now, whenever size is an issue, the best way to make a small program is to generate all data on the fly, i.e. procedurally. This saves valuable storage space. While this might seem like a black art, often it just comes down to clever use of (high school) math. And as is often the case, the best tricks are also the simplest, as they use the least amount of code.</p>
<p>To illustrate this, I'm going to break down my demo and show you all the major pieces and shortcuts used. Unlike the actual 1K demo, the code snippets here will feature legible spacing and descriptive variable names.</p>

<h3>Initialization</h3>

<p>JS1K's rules give you a Canvas tag to work with, so the first piece of code initializes it and makes it fill the window.</p>
<p>From then on, it just renders frames of the demo. There are four major parts to this:</p>
<ul>
<li>Animating the wires</li>
<li>Rotating and projecting the wires into the camera view</li>
<li>Coloring the wires</li>
<li>Animating the camera</li>
</ul>
<p>All of this is done 30 times per second, using a normal <code>setInterval</code> timer:</p>
<p class='codeblock'><code>setInterval(function () { ... }, 33);</code></p>

<h3>Drawing Wires</h3>

<p>The most obvious trick is that everything in the demo is drawn using only a single primitive: a line segment of varying color and stroke width. This allows the whole drawing process to be streamlined into two tight, nested loops. Each inner iteration draws a new line segment from where the previous one ended, while the outer iteration loops over the different wires.</p>
<p>The lines are blended additively, using the built-in 'lighten' mode, which means they can be drawn in any order. This avoids having to manually sort them back-to-front.</p>
<p>To simplify the perspective transformations, I use a coordinate system that places the point (0, 0) in the center of the canvas and ranges from -1 to 1 in both coordinates. This is a compact and convenient way of dealing with varying window sizes, without using up a lot of code:</p>
<p class='codeblock'><code>with (graphics) {<br />&nbsp; ratio = width / height;<br />&nbsp; globalCompositeOperation = &#039;lighter&#039;;<br />&nbsp; scale(width / 2 / ratio, height / 2);<br />&nbsp; translate(ratio, 1);<br />&nbsp; lineWidthFactor = 45 / height;<br />&nbsp; ...</code></p>
<p>I also add a correction <code>ratio</code> for non-square windows and calculate a reference line width <code>lineWidthFactor</code> for later.</p>
<p>Then there's the two nested <code>for</code> loops: one iterating over the wires, and one iterating over the individual points along each wire. In pseudo-code they look like:</p>
<p class='codeblock'><code>For (12 wires =&gt; wireIndex) {<br />&nbsp; Begin new wire<br />&nbsp; For (45 points along each wire =&gt; pointIndex) {<br />&nbsp;&nbsp;&nbsp; Calculate path of point on a sphere: (x,y,z)<br />&nbsp;&nbsp;&nbsp; Extrude outwards in swooshes: (x,y,z)<br />&nbsp;&nbsp;&nbsp; Translate and Rotate into camera view: (x,y,z)<br />&nbsp;&nbsp;&nbsp; Project to 2D: (x,y)<br />&nbsp;&nbsp;&nbsp; Calculate color, width and luminance of this line: (r,g,b) (w,l)<br />&nbsp;&nbsp;&nbsp; If (this point is in front of the camera) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If (the last point was visible) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Draw line segment from last point to (x,y)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; else {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Mark this point as invisible<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; Mark beginning of new line segment at (x,y)<br />&nbsp; }<br />}</code></p>

<h3>Mathbending</h3>

<p>To generate the wires, I start with a formula which generates a sinuous path on a sphere, using latitude/longitude. This controls the tip of each wire and looks like:</p>
<p class='codeblock'><code>offset = time - pointIndex * 0.03 - wireIndex * 3;<br />longitude = cos(offset + sin(offset * 0.31)) * 2<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + sin(offset * 0.83) * 3 + offset * 0.02;<br />latitude = sin(offset * 0.7) - cos(3 + offset * 0.23) * 3;</code></p>
<p>This is classic procedural coding at its best: take a time-based <code>offset</code> and plug it into a random mish-mash of easily available functions like cosine and sine. Tweak it until it 'does the right thing'. It's a very cheap way of creating interesting, organic looking patterns.</p>
<p>This is more art than science, and mostly just takes practice. Any time spent with a graphical calculator will definitely pay off, as you will know better which mathematical ingredients result in which shapes or patterns. Also, there are a couple of things you can do to maximize the appeal of these formulas.</p>
<p>First, always include some non-linear combinations of operators, e.g. nesting the sin() inside the cos() call. Combined, they are more interesting than when one is merely overlaid on the other. In this case, it turns regular oscillations into time-varying frequencies.</p>
<p>Second, always scale different wave periods using prime numbers. Because primes have no factors in common, this ensures that it takes a very long time before there is a perfect repetition of all the individual periods. Mathematically, the <a href='http://www.wolframalpha.com/input/?i=%28least+common+multiple+of+%28100+31+83+70+23%29%29+%2F+100'>least common multiple of the chosen periods</a> is huge (414253 units ~ 4.8 hours). Plotting the longitude/latitude for <code>offset = 0..600</code> you get:</p>
<p><img alt='a pseudo-random set of oscillations' src='/files/making-of-js1k/js1k-2.jpg' title='Looks pretty random' /></p>
<p>The graph looks like a random tangled curve, with no apparent structure, which makes for motions that never seem to repeat. If however, you reduce each constant to only a single significant digit (e.g. 0.31 -> 0.3, 0.83 -> 0.8), then suddenly repetition becomes apparent:</p>
<p><img alt='a not so pseudo-random set of oscillations' src='/files/making-of-js1k/js1k-3.jpg' title='Not so random' /></p>
<p>This is because the least common multiple has <a href='http://www.wolframalpha.com/input/?i=%28least+common+multiple+of+%28100+30+80+70+20%29%29+%2F+100'>dropped to 84 units ~ 3.5 seconds</a>. Note that both formulas have the same code complexity, but radically different results. This is why all procedural coding involves some degree of creative fine tuning.</p>
<h3>Extrusion</h3>

<p>Given the formula for the tip of each wire, I can generate the rest of the wire by sweeping its tail behind it, delayed in time. This is why <code>pointIndex</code> appears as a negative in the formula for <code>offset</code> above. At the same time, I move the points outwards to create long tails.</p>
<p>I also need to convert from lat/long to regular 3D XYZ, which is done using the <a href='http://en.wikipedia.org/wiki/Spherical_coordinate_system'>spherical coordinate transform</a>:</p>
<p><img alt='spherical coordinates' src='/files/making-of-js1k/js1k-4.jpg' /><center>Source: <a href='http://en.wikipedia.org/wiki/File:Coord_system_SE_0.svg'>Wikipedia</a></center></p>
<p class='codeblock'><code>distance = f.sqrt(pointIndex+.2);<br />x = cos(longitude) * cos(latitude) * distance;<br />y = sin(longitude) * cos(latitude) * distance;<br />z = sin(latitude) * distance;</code></p>
<p>You might notice that rather than making <code>distance</code> a straight up function of the length <code>pointIndex</code> along the wire, I applied a square root. This is another one of those procedural tricks that seems arbitrary, but actually serves an important visual purpose. This is what the square root looks like (solid curve):</p>
<p><img alt='square root' src='/files/making-of-js1k/js1k-5.jpg' /></p>
<p>The dotted curve is the square root's derivative, i.e. it indicates the slope of the solid curve. Because the slope goes down with increasing distance, this trick has the effect of slowing down the outward motion of the wires the further they get. In practice, this means the wires are more tense in the middle, and more slack on the outside. It adds just enough faux-physics to make the effect visually appealing.</p>
<h3>Rotation and Projection</h3>

<p>Once I have absolute 3D coordinates for a point on a wire, I have to render it from the camera's point of view. This is done by moving the origin to the camera's position (X,Y,Z), and applying two rotations: one around the vertical (yaw) and one around the horizontal (pitch). It's like spinning on a wheely chair, while tilting your head up/down.</p>
<p class='codeblock'><code>x -= X; y -= Y; z -= Z;<br /><br />x2 = x * cos(yaw) + z * sin(yaw);<br />y2 = y;<br />z2 = z * cos(yaw) - x * sin(yaw);<br /><br />x3 = x2;<br />y3 = y2 * cos(pitch) + z2 * sin(pitch);<br />z3 = z2 * cos(pitch) - y2 * sin(pitch);</code></p>
<p>The camera-relative coordinates are projected in perspective by dividing by Z — the further away an object, the smaller it is. Lines with negative Z are behind the camera and shouldn't be drawn. The width of the line is also scaled proportional to distance, and the first line segment of each wire is drawn thicker, so it looks like a plug of some kind:</p>
<p class='codeblock'><code>plug = !pointIndex;<br />lineWidth = lineWidthFactor * (2 + plug) / z3;<br />x = x3 / z3;<br />y = y3 / z3;<br /><br />lineTo(x, y);<br />if (z3 &gt; 0.1) {<br />&nbsp; if (lastPointVisible) {<br />&nbsp;&nbsp;&nbsp; stroke();<br />&nbsp; }<br />&nbsp; else {<br />&nbsp;&nbsp;&nbsp; lastPointVisible = true;<br />&nbsp; }<br />}<br />else {<br />&nbsp; lastPointVisible = false;<br />}<br />beginPath();<br />moveTo(x, y);</code></p>
<h3>Coloring</h3>
<p>Each line segment also needs an appropriate coloring. Again, I used some trial and error to find a simple formula that works well. It uses a sine wave to rotate overall luminance in and out of the (Red, Green, Blue) channels in a deliberately skewed fashion, and shifts the R component slowly over time. This results in a nice varied palette that isn't overly saturated.</p>
<p class='codeblock'><code>pulse = max(0, sin(time * 6 - pointIndex / 8) - 0.95) * 70;<br />luminance = round(45 - pointIndex) * (1 + plug + pulse);<br />strokeStyle=&#039;rgb(&#039; + <br />&nbsp; round(luminance * (sin(plug + wireIndex + time * 0.15) + 1)) + &#039;,&#039; + <br />&nbsp; round(luminance * (plug + sin(wireIndex - 1) + 1)) + &#039;,&#039; +<br />&nbsp; round(luminance * (plug + sin(wireIndex - 1.3) + 1)) +<br />&nbsp; &#039;)&#039;;</code></p>
<p>Here, <code>pulse</code> causes bright pulses to run across the wires. I start with a regular sine wave over the length of the wire, but truncate off everything but the last 5% of each crest to turn it into a sparse pulse train:</p>
<p><img alt='sine pulse train' src='/files/making-of-js1k/js1k-6.jpg' /></p>
<h3>Camera Motion</h3>

<p>With the main visual in place, almost all my code budget is gone, leaving very little room for the camera. I need a simple way to create consistent motion of the camera's X, Y and Z coordinates. So, I use a neat low-tech trick: repeated interpolation. It looks like this:</p>
<p class='codeblock'><code>sample += (target - sample) * fraction</code></p>
<p><code>target</code> is set to a random value. Then, every frame, <code>sample</code> is moved a certain fraction towards it (e.g. <code>0.1</code>). This turns <code>sample</code> into a smoothed version of <code>target</code>. Technically, this is a <em>one-pole low-pass filter</em>.</p>
<p>This works even better when you apply it twice in a row, with an intermediate value being interpolated as well:</p>
<p class='codeblock'><code>intermediate += (target - intermediate) * fraction<br />sample += (intermediate - sample) * fraction</code></p>
<p>A sample run with <code>target</code> being changed at random might look like this:</p>
<p><img alt='sine pulse train' src='/files/making-of-js1k/js1k-7.jpg' /></p>
<p>You can see that with each interpolation pass, more discontinuities get filtered out. First, jumps are turned into kinks. Then, those are smoothed out into nice bumps.</p>
<p>In my demo, this principle is applied separately to the camera's X, Y and Z positions. Every ~2.5 seconds a new target position is chosen:</p>
<p class='codeblock'><code>if (frames++ &gt; 70) {<br />&nbsp; Xt = random() * 18 - 9;<br />&nbsp; Yt = random() * 18 - 9;<br />&nbsp; Zt = random() * 18 - 9;<br />&nbsp; frames = 0;<br />}<br /><br />function interpolate(a,b) {<br />&nbsp; return a + (b-a) * 0.04;<br />}<br /><br />Xi = interpolate(Xi, Xt);<br />Yi = interpolate(Yi, Yt);<br />Zi = interpolate(Zi, Zt);<br /><br />X&nbsp; = interpolate(X,&nbsp; Xi);<br />Y&nbsp; = interpolate(Y,&nbsp; Yi);<br />Z&nbsp; = interpolate(Z,&nbsp; Zi);</code></p>
<p>The resulting path is completely smooth and feels quite dynamic.</p>
<h3>Camera Rotation</h3>

<p>The final piece is orienting the camera properly. The simplest solution would be to point the camera straight at the center of the object, by calculating the appropriate <code>pitch</code> and <code>yaw</code> directly off the camera's position (X,Y,Z):</p>
<p class='codeblock'><code>yaw&nbsp;&nbsp; = atan2(Z, -X);<br />pitch = atan2(Y, sqrt(X * X + Z * Z));</code></p>
<p>However, this gives the demo a very static, artificial appearance. What's better is making the camera point in the right direction, but with just enough freedom to pan around a bit.</p>
<p>Unfortunately, the 1K limit is unforgiving, and I don't have any space to waste on more 'magic' formulas or interpolations. So instead, I cheat by replacing the formulas above with:</p>
<p class='codeblock'><code>yaw&nbsp;&nbsp; = atan2(Z, -X * 2);<br />pitch = atan2(Y * 2, sqrt(X * X + Z * Z));</code></p>
<p>By multiplying X and Y by 2 strategically, the formula is 'wrong', but the error is limited to about 45 degrees and varies smoothly. Essentially, I gave the camera a lazy eye, and got the perfect dynamic motion with only 4 bytes extra!</p>
<h3>Addendum</h3>

<p>After seeing the other demos in the contest, I wasn't so sure about my entry, so I started working on a version 2. The main difference is the addition of glowy light beams around the object.</p>
<p>As you might suspect, I'm cheating massively here: rather than do physically correct light scattering calculations, I'm just using a 2D effect. Thankfully it comes out looking great.</p>
<p>Essentially, I take the rendered image, and process it in a second Canvas that is hidden. This new image is then layered on the original.</p>
<p>I take the image and repeatedly blend it with a zoomed out copy of itself. With every pass the number of copies doubles, and the zoom factor is squared every time. After 3 passes, the image has been smeared out into an 8 = 2<sup>3</sup> 'tap' radial blur. I lock the zooming to the center of the 3D object. This makes the beams look like they're part of the 3D world rather than drawn on later.</p>
<p>For additional speed, the beam image is processed at half the resolution. As a side effect, the scaling down acts like a slight blur filter for the beams.</p>
<p>Unfortunately, this effect was not very compact, as it required a lot of drawing mode changes and context switches. I had no room for it  in the source code.</p>
<p>So, I had to squeeze out some more room in the original. First, I simplified the various formulas to the bare minimum required for interesting visuals. I replaced the camera code with a much simpler one, and started aggressively shaving off every single byte I could find. Then I got creative, and ended up recreating the secondary canvas every frame just to avoid switching back its state to the default.</p>
<p>Eventually, after a lot of bit twiddling, a version came out that was 1024 bytes long. I had to do a lot of unholy things to get it to fit, but I think the end result is worth it ;). </p>
<h3>Closing Thoughts</h3>

<p>I've long been a fan of the demo scene, and fondly remember <a href='http://www.youtube.com/watch?v=dQveVMQDJlg'>Second Reality</a> in 1993 as my introduction to the genre. Since then, I've always looked at math as a tool to be mastered and wielded rather than subject matter to be absorbed.</p>
<p>With this blog post, I hope to inspire you to take the plunge and see where some simple formulas can take you.</p>

</div></div>]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Making Worlds: Introduction]]></title>
    <link href="http://acko.net/blog/making-worlds-introduction/"/>
    <updated>2009-08-22T00:00:00-07:00</updated>
    <id>http://acko.net/blog/making-worlds-introduction</id>
    <content type="html"><![CDATA[<div class='g8 i2 first'><div class='pad'><h1>Making Worlds: Introduction</h1><p>For the past year or so I've been reacquainting myself with an old friend: C++.
</p>

<p>
More specifically, I've been exploring graphics programming again, this time with the luxurious flexibility of the modern GPU at my fingertips. To get me started, I shopped around for an open source engine to play with. After trying Irrlicht and finding its promises to be a bit lacking, <a href='http://www.ogre3d.org'>Ogre</a> turned out to be a really good choice. Though its architecture is a bit intimidating at first, it is all the more sound. More importantly, it seems to have a relatively healthy open-source community around it.
</p>

<p>
So with Ogre as my weapon of choice, I've started a new project: Making Worlds. More specifically, I want to procedurally generate a 3D planet, viewable from outer space as well as the ground (at flight-sim levels of detail), which can be rendered real-time on recent graphics hardware.
</p>

<p>
Why? Because I really like procedural content generation. It's an odd discipline where anything goes, and techniques from across mathematics, engineering and physics are applied. Then, you add a good dose of creativity and artistic sense, and perhaps mix in some real-world data too, until you find something that looks right.
</p>

<p>
Plus, far from being an exercise in pointlessness, procedural content is <a href='http://www.escapistmagazine.com/articles/view/columns/experienced-points/6418-The-Future-is-Procedural'>gaining in popularity</a>, especially for video games.
</p>

<p>
So, in the style of Shamus Young's excellent <a href='http://www.shamusyoung.com/twentysidedtale/?p=2940'>Procedural city</a> series, I'm going to start blogging about Making Planets. Unlike him however, I'm not going to adhere to a strict schedule.
</p>

<p>
<img alt='Geosphere' src='/files/making-worlds/geosphere.png' />
</p>

<p>
Here's a teaser for the first installment.
</p>

</div></div>]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Noir meets web]]></title>
    <link href="http://acko.net/blog/noir-meets-web/"/>
    <updated>2008-10-23T00:00:00-07:00</updated>
    <id>http://acko.net/blog/noir-meets-web</id>
    <content type="html"><![CDATA[<div class='g8 i2 first'><div class='pad'><h1>Noir meets web</h1><p>After 4 years of LeuvenSpeelt.be aka the <em>Interfacultair Theaterfestival</em> at my old university, the organisers are calling it quits. I was their resident web monkey, and designed a <a href='/tag/theater'>new site and poster every year</a>. I always saw these designs as an opportunity to explore unconventional web design, as the sites were low on content and high on marketing — essentially being fancy brochures with a news feed.
</p>

<p>
With a track record of originality, I figured we should end it in style, so I whipped up a new page which explains the reasons for quitting (i.e. the politics) and highlights the work done with a timeline and some photos.
</p>

<p class='tc'>
<a href='/files/leuvenspeelt/2009/index.html'><img alt='' src='/files/leuvenspeelt/itf2009.jpg' /></a>
</p>

<p>
I wanted the reader to get a sense of ambiguity and dread that comes with ending big projects, so for inspiration I looked to Film Noir, known for its mystery and shady morals. The scene is meant to look like the desk of the typical private detective, who is trying to make sense of a case.
</p>

<p>
The end result was pretty close to how I imagined it, though the limitations of the web as a medium required me to tone down the contrast quite a bit for readability. This makes it lose some of the noir-ness, but overall the cohesion of the piece is still right. Because it's just a good-bye page, it probably won't get as much exposure as the previous editions, but it's the thought that counts.
</p>

<p>
I think it's a fitting end to a project that, more than anything else, has taught me about graphical design and style.
</p>

<p>
Tools used: 3D Studio Max (with Mental Ray), Photoshop, TextMate
</p></div></div>]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Safe String Theory for the Web]]></title>
    <link href="http://acko.net/blog/safe-string-theory-for-the-web/"/>
    <updated>2008-04-03T00:00:00-07:00</updated>
    <id>http://acko.net/blog/safe-string-theory-for-the-web</id>
    <content type="html"><![CDATA[<div class='g8 i2 first'><div class='pad'><h1>Safe String Theory for the Web</h1><p>One of the major things that really bugs me about the web is how poor the average web programmer handles strings. Here we are, changing the way the world works on top of text based protocols and languages like HTTP, MIME, JavaScript and CSS, yet some of the biggest issues that <a href='http://drupal.org/security'>still plague us</a> are cross-site scripting and mangled text due to aggressive filtering, mismatched encodings or overzealous escaping.
</p>

<p>
Almost <a href='http://acko.net/blog/xss-friends-text-handling-in-php-applications'>two years ago</a> I said I'd write down some formal notes on how to avoid issues like XSS, but I never actually posted anything. See, once I sat down to actually try and untangle the do's and don'ts, I found it extremely hard to build up a big coherent picture.
</p>

<p>
But here we are now, and I'm going to try anyway. The text is aimed at people who have had to deal with these issues, who are looking for a bit of formalism to frame their own solutions in.
</p>

<style type='text/css'>
p.string {
  text-align: center;
  margin-top: 0.5em;
  margin-bottom: 0.5em;
}
span.letter {
  padding: 0.125em 0.25em;
  border: 1px solid #ccc;
  margin-right: -1px;
  background: #eee;
}
span.marked {
  background: #ffc;
}
div.context {
  font-size: 0.8em;
  margin-top: -0.5em;
  margin-bottom: 0.625em;
}
span.ugc {
  color: #34a;
}
div.code {
  padding: 0.5em;
  border: 1px solid #ccc;
  background: #eee;
}
table {
  margin: 0.5em auto;
}
</style>

<h2>The problem</h2>

<p>
At the most fundamental level, all the issues mentioned above come down to this: you are building a string for output to a client of some sort, and one or more pieces of data you are using is triggering unknown effects, because it has an unexpected meaning to the client.
</p>

<p>
For example this little PHP snippet, repeated in variations across the web:
</p>

<p class='codeblock'>
<code>&lt;?php&nbsp;print&nbsp;$user-&gt;name&nbsp;?&gt;'s&nbsp;profile</code>
</p>

<p>
If <code>$user-&gt;name</code> contains JavaScript, your users are screwed.
</p>

<p>
What this really comes down is concatenation of data, or more literally, strings. So with that in mind, let's take a closer look at...
</p>

<h2>The humble string</h2>

<p>
What exactly is a string? It seems like a trivial question and I'm sure I'll come across as slightly nutty and overly analytic, but I really think a lot of people don't really know a good answer to this. Here's mine:
</p>

<blockquote><p>
A string is an <strong>arbitrary sequence</strong> (1) of characters composed from a <strong>given character set</strong> (2), which acquires meaning when placed in an <strong>appropriate context</strong> (3).
</p></blockquote>

<p>
This definition covers three important aspects of strings:
</p>

<ol>
  <li>They have no intrinsic restrictions on their content.</li>
  <li>They are useless blobs of data unless you know which symbols it represents.</li>
  <li>The represented symbols are meaningless unless you know the context to interpret them in.</li>
</ol>

<p>
This is a much more high-level concept than what you encounter in e.g. C++, where the definition is more akin to:
</p>

<blockquote><p>
A string is an arbitrary sequence of bytes/words/dwords, in most cases terminated by a null byte/word/dword.
</p></blockquote>

<p>
I think this latter definition is mostly useless for learning how to deal with strings, because it only describes their form, not their function.
</p>

<p>
So let's take a closer look at the three points above.
</p>

<h2>1. Representation of Symbols</h2>

<blockquote>
<p>
They are useless blobs of data unless you know which symbols it represents.
</p>
</blockquote>

<p>
This issue is relatively well known these days and is commonly described as <em>encodings</em> and <em>character sets</em>. A character set is simply a huge, numbered list of characters to draw from. An encoding is a mechanism for turning characters into sequences of bits. Theoretically they are independent of eachother, but in practice, they are coupled together and the two terms are used interchangeably to describe a particular encoding/character set pair.
</p>

<p>
You can't say much about them these days without delving into Unicode. Fortunately, Joel Spolski has already written up a great <a href='http://www.joelonsoftware.com/articles/Unicode.html'>crash course on Unicode</a>, which explains much better than I could.
</p>

<p>
For the purposes of security though, encodings and character sets are mostly irrelevant, as the problems occur regardless of which you use. All you need to do is be consistent, making sure your code can't get confused about which encoding it's working with. So below, we'll talk about strings above the encoding level, as sequences of known characters. Like so:
</p>

<p class='string'><span class='letter'>S</span><span class='letter'>t</span><span class='letter'>r</span><span class='letter'>i</span><span class='letter'>n</span><span class='letter'>g</span><span class='letter'>&nbsp;</span><span class='letter'>T</span><span class='letter'>h</span><span class='letter'>e</span><span class='letter'>o</span><span class='letter'>r</span><span class='letter'>y</span>
</p>

<h2>2. Arbitrary content</h2>

<blockquote><p>
They have no intrinsic restrictions on their content.
</p></blockquote>

<p>
The second point seems self-evident, but can be rephrased into an important mantra for coding practices: there are no restrictions on a string's contents except those you enforce yourself. This makes strings fast and efficient, but also a possible carrier of unexpected data.
</p>

<p>
The typical response to this danger is to apply a strict filtering to any textual inputs your program has and before doing anything else to the data. The idea is to remove anything that may be interpreted later as unwanted mark-up or dangerous code. On the web, this usually means stripping out anything that looks like an HTML tag, doing funky things with ampersands and getting rid of quotes. While this is an approach that is often advocated as an effective and bulletproof solution, it is rather short-sighted, inflexible and restricted in scope, and I strongly oppose it.
</p>

<p>
This is of course very different from regular input validation, like ensuring a selected value is one of a given list of options, or checking if a given input is numeric and in the accepted range. These are different from regular textual inputs, because the desired result is in fact not a string, but either a more restricted data type (like an integer) or a more abstract reference to an existing, internal object.
</p>

<p>
To understand why textual strings are such poor candidates for input validation, we need to look at the third point.
</p>

<h2>3. Different contexts</h2>

<p>
<blockquote>The represented symbols are meaningless unless you know the context to interpret them in.</blockquote>
</p>

<p>
Context, or the lack of it, is essentially the cause of issues such as SQL injection, XSS and HTTP hijacking. And, I think it is exactly because it is so essential to processing strings, that it is often taken as self-evident and forgotten.
</p>

<p>
Let's go back to our example string:
</p>

<p class='string'><span class='letter'>S</span><span class='letter'>t</span><span class='letter'>r</span><span class='letter'>i</span><span class='letter'>n</span><span class='letter'>g</span><span class='letter'>&nbsp;</span><span class='letter'>T</span><span class='letter'>h</span><span class='letter'>e</span><span class='letter'>o</span><span class='letter'>r</span><span class='letter'>y</span>
</p>

<p>
Everyone will see this string represents two English words. That's because people are great at deriving context from free floating pieces of data. However even with natural languages, confusion can arise. Take for example this string:
</p>

<p class='string'><span class='letter'>B</span><span class='letter'>o</span><span class='letter'>n</span><span class='letter'>j</span><span class='letter'>o</span><span class='letter'>u</span><span class='letter'>r</span>
</p>

<p>
Is it a French greeting? Sure. But it is also the name used by Apple for its zero-configuration network stack. We can only know which one is meant, by knowing more about the <em>context it is used in</em>.
</p>

<p>
Now why bother with this trivial exercise? Because the web is all about textual protocols and languages. While people are great at deriving contexts automatically, computers aren't, and generally rely on strict semantics.
</p>

<p>
Imagine a discussion forum, and people post topics with the following subjects:
</p>

<p class='string'><span class='letter'>&lt;</span><span class='letter'>b</span><span class='letter'>&gt;</span><span class='letter'>O</span><span class='letter'>M</span><span class='letter'>G</span><span class='letter'>!</span><span class='letter'>!</span><span class='letter'>!</span><span class='letter'>&lt;</span><span class='letter'>/</span><span class='letter'>b</span><span class='letter'>&gt;</span>
</p>

<p class='string'><span class='letter'>&lt;</span><span class='letter'>b</span><span class='letter'>&gt;</span><span class='letter'>&nbsp;</span><span class='letter'>i</span><span class='letter'>s</span><span class='letter'>&nbsp;</span><span class='letter'>d</span><span class='letter'>e</span><span class='letter'>p</span><span class='letter'>r</span><span class='letter'>e</span><span class='letter'>c</span><span class='letter'>a</span><span class='letter'>t</span><span class='letter'>e</span><span class='letter'>d</span>
</p>

<p>
Each string contains the character <span class='letter'>&lt;</span> in a slightly different context. The first uses it as part of intended bold tags. The second seems to use the same bold tag, but is actually just talking <em>about</em> the tag instead of using it for markup. More formally, we can say the first string is written in an <em>HTML context</em>, the second in a <em>plain-text context</em>.
</p>

<p>
If we were to try and display these strings in the wrong context, we'd see tags printed when they should be interpreted, or text marked up when it should be shown as is.
</p>

<h3>Context conversion</h3>

<p>
To unify the two strings above, we can convert the plain-text string to HTML without loss of meaning, like so:
</p>

<p class='string'><span class='letter marked'>&lt;</span><span class='letter'>b</span><span class='letter marked'>&gt;</span><span class='letter'>&nbsp;</span><span class='letter'>i</span><span class='letter'>s</span><span class='letter'>&nbsp;</span><span class='letter'>d</span><span class='letter'>e</span><span class='letter'>p</span><span class='letter'>r</span><span class='letter'>e</span><span class='letter'>c</span><span class='letter'>a</span><span class='letter'>t</span><span class='letter'>e</span><span class='letter'>d</span>
</p>

<p class='string'><span class='letter marked'>&amp;</span><span class='letter marked'>l</span><span class='letter marked'>t</span><span class='letter marked'>;</span><span class='letter'>b</span><span class='letter marked'>&amp;</span><span class='letter marked'>g</span><span class='letter marked'>t</span><span class='letter marked'>;</span><span class='letter'>&nbsp;</span><span class='letter'>i</span><span class='letter'>s</span><span class='letter'>&nbsp;</span><span class='letter'>d</span><span class='letter'>e</span><span class='letter'>p</span><span class='letter'>r</span><span class='letter'>e</span><span class='letter'>c</span><span class='letter'>a</span><span class='letter'>t</span><span class='letter'>e</span><span class='letter'>d</span>
</p>

<p>
This kind of context conversion is commonplace under the term <em>escaping</em> and in this case, will replace any character that has a special meaning in HTML with its escaped equivalent. This ensures the resulting string still means the same thing in the new context.
</p>

<h2>On the Web, Contexts happen</h2>

<p>
Usually, the lesson above of escaping input to HTML-safe text is where the discussion about XSS ends. However, armed with only the knowledge that <em>HTML-special characters must be escaped</em> to be safe, it can be hard to see why in fact you should not just filter all your data on input to ensure it contains none of these pesky characters in the first place. After all, how many people really need to use angle brackets and ampersands anyway?
</p>

<p>
Well, first of all, I think that's underestimating certain users. The following subject might not be so rare on a message board, yet would be mangled by typical aggressive character stripping:
</p>

<p class='string'><span class='letter'>&lt;</span><span class='letter'>_</span><span class='letter'>&lt;</span><span class='letter'>&nbsp;</span><span class='letter'>s</span><span class='letter'>o</span><span class='letter'>&nbsp;</span><span class='letter'>s</span><span class='letter'>a</span><span class='letter'>d</span>
</p>

<p>
More fundamentally though, it implies that there is only one kind of string context used on the web. Nothing could be further from the truth. Let's look at three different, common contexts.
</p>

<h3>HTML</h3>

<p>
We take a simple snippet of HTML by itself with some assumed user-generated text in it:
</p>

<p class='codeblock'>
<code>  &lt;span title=&quot;<span class='ugc'>attribute text</span>&quot;&gt;<span class='ugc'>inline text</span>&lt;/span&gt;
</code>
</p>

<p>
We look at some different segments of the snippet, and look at what 'forbidden characters' would break or change the semantics of each.
</p>

<p>
<table>
  <thead>
    <tr>
      <th>Snippet</th>
      <th>Forbidden</th>
      <th>Escaped as</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><span style='color: #34a;'>attribute text</span></td>
      <td><span class='letter'>"</span><span class='letter'>&amp;</span></td>
      <td>&amp;quot; &amp;amp;</td>
    </tr>
    <tr>
      <td><span class='ugc'>inline text</span></td>
      <td><span class='letter'>&lt;</span><span class='letter'>&amp;</span></td>
      <td>&amp;lt; &amp;amp;</td>
    </tr>
  </tbody>
</table>
</p>

<p>
For example, quotes are disallowed in attribute text values, because otherwise a string with a quote could alter the meaning of the HTML snippet considerably:
</p>

<p class='codeblock'>
<code>  &lt;span title=&quot;<span class='ugc'>attribute with injected&quot; property=&quot;doEvil() </span>&quot;&gt;<span class='ugc'>inline text</span>&lt;/a&gt;
</code>
</p>

<p>
Note:
</p>

<ul>
<li>All ampersands need to be escaped (including those in URLs) for it to validate. HTML's stricter cousin XML will refuse to parse unescaped ampersands as well, and even requires that apostrophes be escaped too.</li>
<li>XSS attacks do not necessarily involve angle-brackets. In the attribute context, all you need is a <span class='letter'>"</span> to wreak havoc.</li>
</ul>

<h3>URLs</h3>

<p>
The situation is more complicated with URLs. The common HTTP URL for example:
</p>

<p class='codeblock'>
<code>  http://<span class='ugc'>user</span>:<span class='ugc'>password</span>@<span class='ugc'>host.com</span>/<span class='ugc'>path/</span>?<span class='ugc'>variable</span>=<span class='ugc'>value</span>&amp;<span class='ugc'>foo</span>=<span class='ugc'>bar</span>#
  </code>
</p>

<p>
<table>
  <thead>
    <tr>
      <th>Snippet</th>
      <th>Forbidden</th>
      <th>Escaped as</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>(all)</td>
      <td><span class='letter'>&lt;</span><span class='letter'>&gt;</span><span class='letter'>"</span><span class='letter'>#</span><span class='letter'>%</span><span class='letter'>{</span><span class='letter'>}</span><span class='letter'>|</span><span class='letter'>\</span><span class='letter'>^</span><span class='letter'>~</span><span class='letter'>[</span><span class='letter'>]</span><span class='letter'>`</span><span class='letter'> </span> (and non-printables)</td>
      <td>%3C %3E %22 %23 ...</td>
    </tr>
    <tr>
      <td><span class='ugc'>user</span></td>
      <td><span class='letter'>@</span><span class='letter'>:</span></td>
      <td>%40 %3A</td>
    </tr>
    <tr>
      <td><span class='ugc'>password</span></td>
      <td><span class='letter'>:</span></td>
      <td>%3A</td>
    </tr>
    <tr>
      <td><span class='ugc'>host.com</span></td>
      <td><span class='letter'>/</span><span class='letter'>@</span></td>
      <td>disallowed</td>
    </tr>
    <tr>
      <td><span class='ugc'>path</span></td>
      <td><span class='letter'>?</span></td>
      <td>%3F</td>
    </tr>
    <tr>
      <td><span class='ugc'>variable</span></td>
      <td><span class='letter'>&amp;</span><span class='letter'>=</span></td>
      <td>%26 %3D</td>
    </tr>
    <tr>
      <td><span class='ugc'>value</span></td>
      <td><span class='letter'>&amp;</span><span class='letter'>+</span></td>
      <td>%26 %2B</td>
    </tr>
  </tbody>
</table>
</p>

<p>
Note:
</p>

<ul>
  <li>Many forget that a <span class='letter'>+</span> in a query value actually means a space, not a plus.</li>
  <li>Even completely valid URLs can still be malicious, through the <code>javascript://</code> protocol.</li>
  <li>Defined by <a href='http://www.faqs.org/rfcs/rfc1738.html'>RFC 1738</a> and <a href='http://www.faqs.org/rfcs/rfc2616.html'>RFC 2616</a>.</li>
</ul>

<h3>MIME headers</h3>

<p>
Several protocols such as HTTP and SMTP employ the same mechanism of providing metadata for pieces of content. This includes data such as e-mail subjects, senders, cookie headers or HTTP redirects, likely to contain user-generated data.
</p>

<p class='codeblock'>
<code>  Subject: <span class='ugc'>message subject</span><br />
  Content-Type: text/html; charset=utf-8
  </code>
</p>

<p>
<table>
  <thead>
    <tr>
      <th>Snippet</th>
      <th>Forbidden</th>
      <th>Escaped as</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><span class='ugc'>message subject</span></td>
      <td><span class='letter'><em style='opacity: 0.7'>CR</em></span><span class='letter'><em style='opacity: 0.7'>LF</em></span> (if not followed by space), <span class='letter'>(</span><span class='letter'>)</span><span class='letter'>&lt;</span><span class='letter'>></span><span class='letter'>@</span><span class='letter'>,</span><span class='letter'>;</span><span class='letter'>:</span><span class='letter'>\</span><span class='letter'>"</span><span class='letter'>/</span><span class='letter'>[</span><span class='letter'>]</span><span class='letter'>?</span><span class='letter'>=</span>
       + any non-printable</td>
      <td><span style='white-space: nowrap'>=?UTF-8?B?...?=</span></td>
    </tr>
  </tbody>
</table>
</p>

<p>Note:</p>

<ul>
  <li>CRLF sequences without trailing space start a new field and can be used for header injection.</li>
  <li>Lines should be wrapped at 80 columns with CRLF + space.</li>
  <li>Defined by <a href='http://www.faqs.org/rfcs/rfc2045.html'>RFC 2045</a>.</li>
</ul>

<h2>Lolwut?</h2>

<p>
If the above three tables seem complicated and confusing, that's normal. It should be obvious that each of the three contexts is unique and has its own special range of 'forbidden characters' for user input (and even some sub-contexts). From this perspective, it would be impossible to define a safe <em>input</em> filtering mechanism for text on the web that didn't destroy almost all legitimate content.
</p>

<p>
You would have to filter or escape only for a single context, which would create a situation where the exact same approach to a problem can be safe in some cases, but unsafe in others, thus promoting bad coding practices.
</p>

<p>
With the selection above, I also ignored other important contexts (notably JS/JSON or SQL). However, the fact that I was able to make my point using only old school Web 1.0 techniques should show how this problem becomes even hairier in today's Web 2.0.
</p>

<h2>So what then?</h2>

<p>
The right way around string incompatibilities is to use appropriate conversions to change content from one context to another without changing its meaning, and do so when <em>outputting</em> text in a particular instance. We already did it above for the plain-text example, but similar conversions can be made in almost every other instance. Most web languages (like PHP) contain pre-built and tested functions for doing this.
</p>

<p>
Whenever you put strings together, you need to ask yourself what context the strings are in. If they are not the same, an appropriate conversion needs to be made, or you can run into bugs or worse, exploits.
</p>

<p>
For the snippet at the very beginning, the appropriate fix is:
</p>

<p class='codeblock'>
<code>&lt;?php&nbsp;print&nbsp;htmlspecialchars($user-&gt;name)&nbsp;?&gt;'s&nbsp;profile</code>
</p>

<p>
The trick is in understanding why that call goes <em>there</em>, and not somewhere else.
</p>

<p>
<em>Update: Google's DocType wiki has an excellent section with instructions for <a href='http://code.google.com/p/doctype-mirror/wiki/ArticleXSS'>escaping for various contexts</a></em>.
</p>

</div></div>]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Farbtastic Color Picker]]></title>
    <link href="http://acko.net/blog/farbtastic-jquery-color-picker-plug-in/"/>
    <updated>2006-07-14T00:00:00-07:00</updated>
    <id>http://acko.net/blog/farbtastic-jquery-color-picker-plug-in</id>
    <content type="html"><![CDATA[<div class='g8 i2 first'><div class='pad'>
  
<h1>Farbtastic Color Picker</h1>
<h2>jQuery Plug-in</h2>

<p>
Farbtastic is a <a href='http://www.jquery.com/'>jQuery</a> plug-in that can add one or more color picker widgets into a page through JavaScript. Each widget is then linked to an existing element (e.g. a text field) and will update the element's value when a color is selected.
</p>

<p>
<a href='/files/farbtastic/farbtastic12.zip'>Download Farbtastic 1.2</a> - January 8, 2007 (License: <a href='http://www.gnu.org/copyleft/gpl.html'>GPL</a>).
</p>

</div></div><div class='g5 i2'><div class='pad'>

<h2>Demo</h2>

<p>
Farbtastic uses layered transparent PNGs to render a saturation/luminance gradient inside of a hue circle. No Flash, no pixel sized divs.
</p>

<p>
Click and drag over the selector to try it out.
</p>

<p>
<form action=''>
  <div class='form-item'><label for='color'>Color:</label><input id='color' name='color' style='width: 195px' type='text' value='#123456' /></div>
</form>
</p>

</div></div><div class='g3'><div class='pad m3'>

<link href='/files/farbtastic/demo/farbtastic.css' media='screen' rel='stylesheet' type='text/css' />

<script charset='utf-8' src='/files/farbtastic/demo/farbtastic.js' type='text/javascript' />

<script charset='utf-8' type='text/javascript'>
  setTimeout(function() {
    jQuery.farbtastic('#picker').linkTo('#color');
  }, 100);
</script>

<div id='picker' />

</div></div><div class='g8 i2'><div class='pad'>

<h2>Basic Usage</h2>
<ol>
<li>
  <p>Include farbtastic.js and farbtastic.css in your HTML:</p>
<p class='codeblock'>
<code>&lt;script&nbsp;type=&quot;text/javascript&quot;&nbsp;src=&quot;farbtastic.js&quot;&gt;&lt;/script&gt;<br />
&lt;link&nbsp;rel=&quot;stylesheet&quot;&nbsp;href=&quot;farbtastic.css&quot;&nbsp;type=&quot;text/css&quot;&nbsp;/&gt;
</code></p>
</li><li>
  <p>Add a placeholder div and a text field to your HTML, and give each an ID:</p>
<p class='codeblock'><code>&lt;form&gt;&lt;input&nbsp;type=&quot;text&quot;&nbsp;id=&quot;color&quot;&nbsp;name=&quot;color&quot;&nbsp;value=&quot;#123456&quot;&nbsp;/&gt;&lt;/form&gt;<br />
&lt;div&nbsp;id=&quot;colorpicker&quot;&gt;&lt;/div&gt;<br />
</code></p>
</li>
<li>
  <p>Add a ready() handler to the document which initializes the color picker and link it to the text field with the following syntax:</p>
<p class='codeblock'><code>&lt;script&nbsp;type=&quot;text/javascript&quot;&gt;<br />
&nbsp;&nbsp;$(document).ready(function()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;$('#colorpicker').farbtastic('#color');<br />
&nbsp;&nbsp;});<br />
&lt;/script&gt;<br />
</code></p>
</li></ol>

<p>
See demo1.html and demo2.html for an example (jquery.js is not included!).
</p>

<h2>Styling</h2>

<p>
The color picker is a block-level element and is 195x195 pixels large. You can control the position by styling your placeholder (e.g. floating it).
</p>

<p>
Note that the black/white gradients inside wheel.png and mask.png were generated programmatically and cannot be recreated easily in an image editing program.
</p>

<h2>Advanced Usage</h2>

<h3>jQuery Method</h3>
<dl>
<dt>$(...).farbtastic()
$(...).farbtastic(callback)</dt>
<dd>This creates color pickers in the selected objects. <code>callback</code> is optional and can be a:
<ul>
<li><em>DOM Node</em>, <em>jQuery object</em> or <em>jQuery selector</em>: the color picker will be linked to the selected element(s) by syncing the value (for form elements) and color (all elements).</li>
<li><p><em>Function</em>: this function will be called whenever the user chooses a different color. It should have the following signature:
</p>

<p class='codeblock'><code>function&nbsp;callback(color)&nbsp;{&nbsp;...&nbsp;}</code>
</p>

<p>
With <code>color</code> the chosen color in hex representation (e.g. '#123456').
</p>
</li>
</ul>
</dd>
</dl>

<h3>Object</h3>
<dl>
<dt>$.farbtastic(placeholder)
$.farbtastic(placeholder, callback)
</dt>
<dd><p>Invoking <code>$.farbtastic(placeholder)</code> is the same as using <code>$(placeholder).farbtastic()</code> except that the Farbtastic object is returned instead of the jQuery object. This allows you to use the Farbtastic methods and properties below.
</p>

<p>
Note that there is only one Farbtastic object per placeholder. If you call <code>$.farbtastic(placeholder)</code> twice <em>with the same placeholder</em>, you will get the same object back each time.
</p>

<p>
The optional <code>callback</code> argument behaves exactly as for the jQuery method.
</p>
</dd>
</dl>

<h3>Methods</h3>
<dl>
<dt>.linkTo(callback)</dt>
<dd>Allows you to set a new callback. Any existing callbacks are removed. See above for the meaning of <code>callback</code>.</dd>
<dt>.setColor(string)</dt>
<dd>Sets the picker color to the given color in hex representation (e.g. '#123456').</dd>
<dt>.setColor([h, s, l])</dt>
<dd>Sets the picker color to the given color in normalized HSL (0..1 scale).</dd>
</dl>

<h3>Properties</h3>
<dl>
<dt>.linked</dt>
<dd>The elements (jQuery object) or callback function this picker is linked to.</dd>
<dt>.color</dt>
<dd>Current color in hex representation (e.g. '#123456').</dd>
<dt>.hsl</dt>
<dd>Current color in normalized HSL (e.g. [0.3, 0.4, 0.5]).</dd>
</dl>

</div></div>]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Advanced Visualization Studio]]></title>
    <link href="http://acko.net/blog/avs/"/>
    <updated>2003-10-29T00:00:00-08:00</updated>
    <id>http://acko.net/blog/avs</id>
    <content type="html"><![CDATA[<div class='g8 first'><div class='pad'><h1>Advanced Visualization Studio</h1><p><h2>What is AVS</h2>

<p>
<p><acronym title='Advanced Visualisation Studio'>AVS</acronym> is a music visualisation plug-in for <a href='http://www.winamp.com/'>Winamp</a>. Unlike most plug-ins however, AVS allows you to play around and make your own visuals, from a set of pluggable components combined with a scripting system. In the early 2000s, AVS was considered one of the most awesome, most flexible music visualisers on the planet, and the resulting variety in visuals (called <i>presets</i>) was amazing.</p>

<p>Even more, AVS allows you to compose and preview presets completely real-time and with script code, updating even between individual keystrokes. This stroke of genius turned it into an eminently accessible tool that drew the attention of enthusiasts from around the world. In forum communities such as Winamp.com and DeviantArt, coders and non-coders hung out and shared presets of ever increasing complexity and style.</p>

<p>Over the years I've made several <a href='http://www.winamp.com/user/details/84800'>critically acclaimed</a> packs of AVS presets and plug-ins, many of which are included in the official Winamp distribution. My visuals are trademarked by technical complexity: 3D rollercoasters, convincing dancers, sci-fi shootouts, cartoony rendering, etc. along with good music response.</p>

<h2>Links</h2>
<ul>
<li><a href='http://forums.winamp.com/showthread.php?threadid=82567'>AVS <abbr title='Frequently Asked Questions'>FAQ</abbr></a> - At the Winamp.com AVS forums.</li>
<li><a href='http://browse.deviantart.com/visualization/avspresets/'>AVS presets at DeviantArt.com</a></li>
<li><a href='http://www.visbot.net'>VISBOT</a> - The most stylish presets on the planet.</li>
<li><a href='http://www.winamp.com/plugins/browse.php?ctype=P&amp;category=11'>Winamp.com AVS section</a> - AVS presets at Winamp.com (overall quality not so good).</li>
</ul>
</p>

<h2>My Presets</h2>

<p>Enjoy these packs of presets, packaged in a self-extracting installer. Ordered chronologically, most recent on top.</p>
<p><em>Thanks to Yathosho of <a href='http://visbot.net/'>Visbot.net</a> for repackaging these in an admin-aware installer.</em></p>
<ul>
 <li><aside class='l c mb1'><a href='/files/avs/WhackoRevisited.exe' title='Download Whacko Revisited'><img alt='Whacko Revisited' src='/files/avs/whackorev.png' /></a></aside>
<a href='/files/WhackoRevisited.exe'>Whacko Revisited - March 20th, 2004</a><br />A pack consisting of remixes and remakes of presets from the Whacko series, released for my 20th birthday. Featuring <a href='http://duo.deviantart.com/'>Duo</a>, <a href='http://el-vis.deviantart.com/'>El-vis</a>, <a href='http://fsk.deviantart.com/'>Fšk</a>, <a href='http://jheriko.deviantart.com/'>Jheriko</a>, <a href='http://montana38.deviantart.com/'>Montana</a>, <a href='http://nemoorange.deviantart.com/'>NemoOrange</a>, <a href='http://raz001.deviantart.com/'>Raz</a>, <a href='http://skupers.deviantart.com/'>Skupers</a>, <a href='http://tuggummi.deviantart.com/'>Tuggummi</a>, <a href='http://yathosho.deviantart.com/'>Yathosho</a>, <a href='http://zevensoft.deviantart.com/'>Zevensoft</a>.</li>
 <li><aside class='l c mb1'><a href='/files/avs/FinalWhack.exe' title='Download Final Whack'><img alt='Final Whack' src='/files/avs/final-whack.png' /></a></aside>
<a href='/files/avs/FinalWhack.exe'>Final Whack</a> - Dec 16, 2003<br />My biggest (and best?) pack of visuals, featuring some of the grooviest effects ever seen in AVS: a wicked rollercoaster, a zeppelin in the clouds, a trippy landscape, etc.<br />
<small>Featured at <a href='http://www.deviantart.com/deviation/4257879/'>DeviantArt</a> on 2003-12-17. Requires Winamp 5+.</small></li>
 <li><aside class='l c mb1'><a href='/files/avs/whacko6avs.exe' title='Download Whacko AVS VI'><img alt='Whacko AVS VI' src='/files/avs/whacko6.jpg' /></a></aside>
<a href='/files/avs/whacko6avs.exe'>Whacko AVS VI</a> - Nov 29, 2002<br />The last of the Whacko series, featuring a Star Wars scene, a Mars preset and more. This pack also contained the first release of the Colormap <abbr title='AVS Plug-in Effect'>APE</abbr>, giving preset makers a lot more options for tweaking colors.<br />
<small>Featured at Winamp.com and DeviantArt</small>.</li>
 <li><a href='/files/avs/whacko5avs.exe'>Whacko AVS V</a> - Aug 13, 2002<br />The fifth episode of Whacko AVS, with yet more yummy effects. Highlights include a funny, drunken dancer and a hypnotic fountain.</li>
 <li><a href='/files/avs/whacko1-4avs.exe'>Whacko AVS I-VI</a><br />The first four episodes of Whacko AVS, combined into one package. Not as good as my most recent stuff of course, but everyone has to start somewhere!</li>
</ul>
</p>

<h2>My <acronym title='AVS Plug-in Effect'>APE</acronym>s</h2>
<p>AVS can be extended by writing your own components. I've made several multi-purpose <acronym title='AVS Plug-in Effect'>APE</acronym>s which you can download here.</p>
<p>Note: my Texer II, Color Map, ChannelShift, Color Reduction and Multiplier <acronym title='AVS Plug-in Effect'>APE</acronym>s are already included with Winamp5.</p>
<p><b>Note: All these APEs are unsupported. Use them at your own risk. Redistribution outside of AVS packs is not permitted.</b>
</p>

<p>Available for download:</p>
<ul><li><a href='/files/avs/picture2.zip'>Picture II</a><br />
Improved picture renderer. Can read BMP and JPEG, supports all AVS blend modes, subdirectories and bilinear filtering.</li>
<li><a href='/files/avs/vjcontrol.zip'>VJ Control</a><br />
Gives you a bunch of sliders, buttons and checkboxes for controlling presets interactively.</li>
<li><a href='/files/avs/avsgrabber2.zip'>AVSGrabber</a> - 2.0 alpha<br />
Captures AVS presets to AVI. Insert into the preset to use it. For experimental audio capturing, use the provided out_grab.dll as output in Winamp.
</li>
</ul>

</div></div><aside class='r g4 m4'><div class='pad m4'>
  <img alt='' src='/files/avs/avs09.jpg' />
  <img alt='' src='/files/avs/avs08.jpg' />
  <img alt='' src='/files/avs/avs06.jpg' />
  <img alt='' src='/files/avs/avs01.jpg' />
  <img alt='' src='/files/avs/avs02.jpg' />
  <img alt='' src='/files/avs/avs03.jpg' />
  <img alt='' src='/files/avs/avs04.jpg' />
  <img alt='' src='/files/avs/avs05.jpg' />
  <img alt='' src='/files/avs/avs07.jpg' />
</div></aside>]]></content>
  </entry>
  
</feed>

