<?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>Extremely Satisfactory Totalitarianism</title>
	<atom:link href="http://extremelysatisfactorytotalitarianism.com/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://extremelysatisfactorytotalitarianism.com/blog</link>
	<description></description>
	<lastBuildDate>Sat, 04 Sep 2010 07:16:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>We Can Do Anything But Keep Things In Perspective</title>
		<link>http://extremelysatisfactorytotalitarianism.com/blog/?p=1402</link>
		<comments>http://extremelysatisfactorytotalitarianism.com/blog/?p=1402#comments</comments>
		<pubDate>Fri, 25 Jun 2010 01:40:19 +0000</pubDate>
		<dc:creator>Brendan Kenny</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[demo]]></category>
		<category><![CDATA[graphics]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[ie]]></category>
		<category><![CDATA[interaction]]></category>
		<category><![CDATA[interface]]></category>
		<category><![CDATA[ns]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[standards]]></category>
		<category><![CDATA[transforms]]></category>
		<category><![CDATA[webkit]]></category>

		<guid isPermaLink="false">http://extremelysatisfactorytotalitarianism.com/blog/?p=1402</guid>
		<description><![CDATA[I&#8217;ve been playing around with using 2D transformations to enable 3D effects, even (or especially) in browsers without support for the latter. There have been a few examples of this kind—putting text and images and even video on isometric cubes, &#8230; <a href="http://extremelysatisfactorytotalitarianism.com/blog/?p=1402">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><img class="size-full wp-image-1995 aligncenter" title="cube" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/06/cube_top.png" alt="" width="560" height="105" /></p>
<p>I&#8217;ve been playing around with using 2D transformations to enable 3D effects, even (or especially) in browsers without support for the latter. There have been a few examples of this kind—putting text and images and even video on <a title="3D transforms in Firefox 3.5 - the isocube - Mozilla Hacks" href="http://hacks.mozilla.org/2009/06/3d-transforms-isocube/">isometric cubes</a>, for the most part—but I think we, as a community, have not gone far enough in the pursuit of the hideous. I&#8217;m here to help.</p>
<p>This demo does border on abuse of the format—probably better done with SVG or not at all—but as an outputted, interactive image it (vaguely) suggests something important. Before a particular problem, before identifying the needs of our users, before creating elegant interfaces, and before good visual design, I believe we need to ensure the delivery of that first promise of techno-utopianism: putting whatever the hell we want to on the screen.</p>
<p>To be perfectly clear, all the things I listed first are far more important than that ability, but we shouldn&#8217;t be limited before we begin. Limits inspire creativity, but they also circumscribe what is possible; <em>I</em> want to be in charge of that. If I want a giant blinking triangle covering half my text, then by golly, there should be a giant blinking triangle there. Just because something shouldn&#8217;t be done doesn&#8217;t mean it shouldn&#8217;t be doable.</p>
<p style="text-align: center;"><a href="http://extremelysatisfactorytotalitarianism.com/projects/experiments/2010/06/isometry/"><img class="size-full wp-image-1998" style="padding-right: 10px; vertical-align: middle;" title="This one won't even crash your browser!" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/06/cube_demo.png" alt="" width="147" height="147" /></a><a title="This one won't even crash your browser!" href="http://extremelysatisfactorytotalitarianism.com/projects/experiments/2010/06/isometry/"><strong>Demo: Isometry</strong></a></p>
<h3>Interaction</h3>
<p>Browser interaction techniques have historically been so poor that we are still astounded when the simplest of interfaces match some intuitive sense of physicality. Luckily, things are changing. There is an increasing belief in a kind of manifest destiny for the web, the idea that we can make any kind of interface that we set our mind to, but we&#8217;re just now getting around to it (we might also have been waiting for the right local storage api).</p>
<p>Deluded or not, I&#8217;m of this mind as well, and I was interested in experimenting with the mechanics of interacting with three-dimensional objects, specifically through the web browser. All interfaces are abstractions and therefore lossy (surjective, if you&#8217;re into that), but the 2D interface to a 3D scene ends up serving two masters, since the whole point is to mimic a physical interaction through a mouse and keyboard. A qualitatively-optimized mapping still needs to be made between data and interface, something as expressive as possible within the parameters available, but here it has to not only convince us that those degrees of freedom are sufficient for the task at hand, it has to simultaneously match our sense of the way things actually move in the real world. Otherwise: frustration.</p>
<p>Which is all a long way of saying that most 3D interfaces are terrible. If it&#8217;s just decoration, fine, but if you&#8217;re trying to perfectly map a physical task to the mouse, you&#8217;re doing computers wrong, and if mouse movements relate inconsistently to what&#8217;s happening on screen, your users hate you.</p>
<p>This demo just plays around with some ideas—there is no real task to accomplish—but it&#8217;s easy to see where it is not entirely successful. However, meaningful criticism would require a program that was meant to do something, which this one wasn&#8217;t. I will say, though, that the technical side of things is easier than you might think. So embrace our collective destiny, don&#8217;t be afraid of creating the next blink tag or flash banner ad, and stop waiting for the perfect version of local storage.</p>
<p>Also, those native-app developers told me you guys look like dorks, so you&#8217;d better get on that.</p>
<h3>Projection</h3>
<p>While waiting for the WebGL promised land to arrive, I wanted a reliable way of making 3D transformations work at interactive rates across all the major browsers, even accounting for those aging software renderers. The process turns out to be pretty simple and without any real hacks; every frame created dynamically here can be recreated statically with some plain, vendor-prefixed CSS. Now, &#8220;real hacks&#8221; is relative—especially depending on how you feel about &#8220;-ms-filter&#8221;—and I don&#8217;t explicitly support IE versions prior to 8, but it&#8217;s a start.</p>
<p>The key is the <a title="Orthographic projection" href="http://en.wikipedia.org/wiki/Orthographic_projection">orthographic projection</a>, one way of projecting a three-dimensional scene onto a two-dimensional surface (in this case, the screen). Since orthographic projections map 3D parallel lines to 2D parallel lines, objects do not shrink as they recede from a viewer. This can cause a somewhat unsettling effect—a pretty cool testament to the sophistication of our visual system—but is also one more tool to be <a title="SXSW 2010 Logo" href="http://sxsw.com/sites/all/themes/sxsw/images/sxsw2010.gif">exploited</a> by <a title="Homepage of the Official M.C. Escher Website" href="http://www.mcescher.com/">artists</a>. In a nutshell, the animation system keeps track of the 3D transformations per element, then does a simple projection before applying it to that element&#8217;s style property. I&#8217;ll post more on the math and implementation details shortly.</p>
<h3>Known Issues</h3>
<p>I want to make the core feature set work across browsers as reliably as possible. If you have an issue, please let me know about it and the platform it happened on.</p>
<p><strong>[IE]</strong></p>
<ul>
<li>Internet Explorer&#8217;s <a title="On the Behavior of 2d Transformations in Internet Explorer" href="http://extremelysatisfactorytotalitarianism.com/blog/?p=1002">matrix filter</a> has proven surprisingly stable and performant, but this demo appears to be pushing it to its limit. Transformations nested three or four deep, especially on elements with untransformed siblings, cause background colors to bleed through in some circumstances. This is not an issue in IE9 Preview 2.
<p style="text-align: center;"><img class="size-full wp-image-2014" style="padding-right: 10px;" title="Regular Background" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/06/IE_bground_before.png" alt="" width="147" height="147" /><img class="size-full wp-image-2015" title="Bleeding Background" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/06/IE_bground_after.png" alt="" width="147" height="147" /></p>
</li>
<li>Unfortunately, the nested transform necessary for the recursive side is ignored altogether. This is not corrected in IE9. The transform is there, but unperformed, even though transforms nested within <em>that</em> transform are executed correctly. I&#8217;m hopeful that a knock in the right place will get it working.</li>
<li>Like most of us, IE9 Preview 3 <a title="Microsoft Connect | Feature test for filters triggers script error" href="https://connect.microsoft.com/IE/feedback/details/570464/feature-test-for-filters-triggers-script-error">isn&#8217;t a big fan of filters</a> and won&#8217;t run this. If filters are removed from IE9 permanently (when in standards mode) and CSS3 transforms are not added, I don&#8217;t believe there is a replacement.</li>
</ul>
<p><strong>[Embedacube™]</strong></p>
<ul>
<li>The Embedacube™ feature saves the state of the cube just before you press the button; press it again to save the state after the first press (but before the second press).</li>
<li>An Embedacube™ cube currently only works in the browser version (Firefox, IE, etc) in which it was created.</li>
<li>Some style information is currently lost in the Embedacube™ process.</li>
</ul>
<p><strong>[Webkit]</strong></p>
<ul>
<li>Safari on the Mac and Chromium on Windows (<a title="Accelerated compositing and 3D CSS transforms" href="http://groups.google.com/a/chromium.org/group/chromium-dev/browse_thread/thread/945e0f0a53584a37">with startup flag</a>) both support hardware accelerated 3D transforms. Unfortunately, this demo interacted with <code>-webkit-transform-style</code> and the subsequent stacking order differently than I anticipated, so I&#8217;ve forced them back to 2D for now. Performance suffers a bit, but their software renderer is pretty good, especially for such a simple scene. I am investigating how deeply I have to change things in order to get accelerated 3D transforms working properly, and hope to have the change pushed soon.</li>
<li>CSS transitions are another feature currently unused that should map well to this demo and provide a good performance boost.</li>
</ul>
<p><strong>[Mobile]</strong></p>
<ul>
<li>In a few tests, mobile performance on this page has been good. However, my testing equipment is limited, so touch events, for instance, are not currently acted upon.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://extremelysatisfactorytotalitarianism.com/blog/?feed=rss2&amp;p=1402</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Transform Rewrite: Dancing Trees and Errant Pixels</title>
		<link>http://extremelysatisfactorytotalitarianism.com/blog/?p=1763</link>
		<comments>http://extremelysatisfactorytotalitarianism.com/blog/?p=1763#comments</comments>
		<pubDate>Mon, 31 May 2010 16:44:44 +0000</pubDate>
		<dc:creator>Brendan Kenny</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[demo]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[graphics]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[ie]]></category>
		<category><![CDATA[ns]]></category>
		<category><![CDATA[opera]]></category>
		<category><![CDATA[transforms]]></category>
		<category><![CDATA[webkit]]></category>
		<category><![CDATA[WebKitCSSMatrix]]></category>

		<guid isPermaLink="false">http://extremelysatisfactorytotalitarianism.com/blog/?p=1763</guid>
		<description><![CDATA[Two months later, I&#8217;ve finally had some time to finish a rewrite of my &#8220;CSS3&#8243; transform/transformed element GWT module. I&#8217;m pretty pleased with its new state and don&#8217;t anticipate the need for any more major changes in the near future. &#8230; <a href="http://extremelysatisfactorytotalitarianism.com/blog/?p=1763">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><img class="aligncenter size-full wp-image-1764" title="our gloom-pleased eyes" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/05/eyes.png" alt="" width="560" height="105" /><br />
Two months later, I&#8217;ve finally had some time to finish a rewrite of my &#8220;CSS3&#8243; transform/transformed element GWT module. I&#8217;m pretty pleased with its new state and don&#8217;t anticipate the need for any more major changes in the near future. It&#8217;s still definitely in beta, but I&#8217;m sufficiently confident in it that I&#8217;ve <a title="Changes - gwt-ns - Project Hosting on Google Code" href="https://code.google.com/p/gwt-ns/source/list">checked in the code</a>, generated <a title="Transforms Javadoc" href="http://gwt-ns.googlecode.com/svn-history/r61/trunk/javadoc/index.html">javadocs</a>, written a sample app, and <a title="Downloads - gwt-ns - Project Hosting on Google Code" href="https://code.google.com/p/gwt-ns/downloads/list">uploaded a zipped jar</a> which includes all the aforementioned. Though checking out the code via Subversion doesn&#8217;t seem to have been too high a barrier before now for some, hopefully this will encourage others to take a peak.</p>
<h3>It&#8217;s so bad</h3>
<p><a title="Web Worker Example: The Rationals" href="http://extremelysatisfactorytotalitarianism.com/blog/?p=645">Once again</a>, I needed to write a simple demo for a module, something obvious in effect, intent, and execution. I&#8217;m usually terrible at these—hemming and hawing over details irrelevant to the point of a piece—so I gave myself two hours to come up with something and code it. I didn&#8217;t quite make it (there was some hemming and hawing), but it was close.</p>
<p>I don&#8217;t remember exactly how some initial thoughts on nested spinning boxes lead to this, but I think it turned out pretty well, if a little crude. Conveniently, it ended up using the major parts of the library that most need demonstrating—creation, element transformation, and the use of standalone transforms—which I&#8217;ll talk about below. There was also only a single browser workaround needed: current versions of IE don&#8217;t support border-radius, so the shadows needed some slight repositioning.</p>
<p>But I&#8217;ll get to all that. Go look. Firefox ends up winning for rendering quality (and was used for most of these screenshots), but all the browsers do pretty well keeping up:</p>
<p style="text-align: center;"><a href="http://extremelysatisfactorytotalitarianism.com/projects/ns/transformtree/"><img class="size-full wp-image-1770 alignnone" style="padding-right: 10px; vertical-align: middle;" title="firefox: looks good. other browsers: study this picture, now do that." src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/05/demo_l.png" alt="" width="147" height="147" /></a><a title="Transforming Trees" href="http://extremelysatisfactorytotalitarianism.com/projects/ns/transformtree/"><strong>Demo: Transforming Trees</strong></a></p>
<p>If it doesn&#8217;t really strike a chord, try running <a title="Super Mario Bros. 3 Music - World Map 1: Grass Land" href="http://www.youtube.com/watch?v=xK3FnQA0kOE">this</a> in the background at the same time. Hey, I never said it was going to change someone&#8217;s life or scrub oil off the wetlands. Two (and a half) hours, remember?</p>
<h3>Overview</h3>
<p>The source for the demo is over in the <a title="transformtree - gwt-ns- Project Hosting on Google Code" href="https://code.google.com/p/gwt-ns/source/browse/trunk/demos/transformtree/src/gwt/ns/demo/transformtree/">usual place</a>, but I&#8217;ll go through the important parts here, concentrating on the actual application of transforms.<span id="more-1763"></span></p>
<p>Most everything happens in TreesWidget.java, except for this line in the gwt.xml module file:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;inherits</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;gwt.ns.transformedelement.TransformedElement&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

<p>The project also needs to inherit from the Transforms module, but in this case TransformedElement has already done so.</p>
<p>Execution is divided up into initialization and an animation loop. The TransformedElements are created in the Widget&#8217;s constructor. In order to animate transforms efficiently in Internet Explorer, several data points about an element need to persist across frames, and so are kept in a TransformedElement object. See <a title="On the Behavior of 2d Transformations in Internet Explorer" href="http://extremelysatisfactorytotalitarianism.com/blog/?p=1002">these</a> <a title="On the Behavior of 2d Transformations in Internet Explorer, Part 2" href="http://extremelysatisfactorytotalitarianism.com/blog/?p=922">posts</a> for more about how this works. For a static transformation, the object can be discarded after creation; the transform will persist like any other style.</p>
<p>An <code>update()</code> method is then called from a timer, updating as often as it can.</p>
<h3>Trees: TransformedElement</h3>
<p>TreesWidget initializes the two tree DIV elements by wrapping them with TransformedElement objects:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">bigTree <span style="color: #339933;">=</span> TransformedElement.<span style="color: #006633;">wrap</span><span style="color: #009900;">&#40;</span>bigTreeDiv<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
littleTree <span style="color: #339933;">=</span> TransformedElement.<span style="color: #006633;">wrap</span><span style="color: #009900;">&#40;</span>littleTreeDiv<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>As with all dancing trees, movement starts at the trunk, so the transform origin should be located there. The helpful folks writing and implementing the CSS3 transform spec have seen fit to give a <a title="The ‘transform-origin’ Property" href="http://www.w3.org/TR/css3-2d-transforms/#transform-origin-property">built-in property to position the origin</a> for just such a purpose. In this case, the origins need to remain in the middle of each tree, but moved to their base:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">bigTree.<span style="color: #006633;">setOriginPercentage</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">50</span>, <span style="color: #cc66cc;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
littleTree.<span style="color: #006633;">setOriginPercentage</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">50</span>, <span style="color: #cc66cc;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><img class="aligncenter size-full wp-image-1874" title="trees transformed" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/05/trees_transformed.png" alt="" width="560" height="546" /></p>
<p>That&#8217;s all the initialization the trees need. In the animation loop, the trees sway back and forth while simultaneously crouching down and stretching up (is there a good antonym for crouching?). The parameters for each cycle are calculated and, since they are not cumulative, applied to the tree after its transform is reset to the identity.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> update<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">// calculate scaleX, scaleY, bigSkewAngle...</span>
&nbsp;
  bigTree.<span style="color: #006633;">setToIdentityTransform</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  bigTree.<span style="color: #006633;">scale</span><span style="color: #009900;">&#40;</span>scaleX, scaleY<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  bigTree.<span style="color: #006633;">skewX</span><span style="color: #009900;">&#40;</span>bigSkewAngle<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// animate littleTree</span>
  <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>That&#8217;s it.</p>
<h3>Shadows: TransformedElement + Standalone Transform</h3>
<p>A shadow can go a long way toward tying objects to each other and the background, giving a sense of physicality where there is none. Shadows often don&#8217;t have to be anywhere near realistic to fill that role, but in this case the limits of border-radius prevented me from creating simple blob shadows. Since the shadows were squished, the radii allowed by the browser were rather small, and so the shadows were less blobular and more rectangular.</p>
<p>Nothing a little over-engineering can&#8217;t solve!</p>
<p>The shadows used are actually exact style copies of the trees (except that, since all browsers that currently support browser-radius do so with obvious rendering cracks, expanded heights and widths are used in lieu of borders). The shadows are initialized just like the trees, since they too will transform about the trees&#8217; bases.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">bigShadow <span style="color: #339933;">=</span> TransformedElement.<span style="color: #006633;">wrap</span><span style="color: #009900;">&#40;</span>bigShadowDiv<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
littleShadow <span style="color: #339933;">=</span> TransformedElement.<span style="color: #006633;">wrap</span><span style="color: #009900;">&#40;</span>littleShadowDiv<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
bigShadow.<span style="color: #006633;">setOriginPercentage</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">50</span>, <span style="color: #cc66cc;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
littleShadow.<span style="color: #006633;">setOriginPercentage</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">50</span>, <span style="color: #cc66cc;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><img class="aligncenter size-full wp-image-1881" title="the eyes usually look like eyes to me, but sometimes they remind me of Oedipus Rex (the eye-stabbing part, not the other thing)" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/05/trees_shadow_untransformed.png" alt="" width="560" height="546" /></p>
<p>Looks a bit like box-shadow.</p>
<p>Now for the trickery. We want a shadow at the base of the trees, coming toward the viewer at a slight angle, and squished to fit in the space available at the bottom (short because our trees do their best dancing at mid-day). That&#8217;s the more literal interpretation of the transform that is about to be applied. However—if you&#8217;re into this sort of thing—the transform can also be thought of as projecting the shape of the tree toward the viewer onto a slightly tilted plane.</p>
<p>The two descriptions are equivalent. I usually take any excuse I can get to play around with matrices for an afternoon, but in this case I only cared about the general effect, so I just flubbed around with the numbers until the scene looked right.</p>
<p>The shadows are going to dance with the trees, but the shadow positioning transform is never going to change. This gives a good excuse to create a canned transform that we can apply at any time. This saves a good bit of computation in each frame, but also allows the creation of this &#8220;shadow space&#8221; to be kept out of the animation method, where we don&#8217;t really care about its specifics any longer.</p>
<p>Like TransformedElements, Transforms are created from a factory method. This allows the library to delegate to native objects like WebKitCSSMatrix on platforms which support them. While the math will never come for free, some operations will be performed much more quickly in mobile browsers, for instance.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Transform shadowTransform <span style="color: #339933;">=</span> Transform.<span style="color: #006633;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// small translation so overlapping with trees</span>
shadowTransform.<span style="color: #006633;">translate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// angled</span>
shadowTransform.<span style="color: #006633;">skewX</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">1.122</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// squished and toward the viewer (reflected)</span>
shadowTransform.<span style="color: #006633;">scale</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, <span style="color: #339933;">-</span>.12<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Finally, the transform and animation are applied to the shadows. At some point, everybody has difficulty with the order in which transforms should be applied. There are several ways to conceptualize the process: some like the idea that they are applied in &#8220;reverse order,&#8221; but I like to think of each transform as applied in the coordinate space created by the previous transformation.</p>
<p>In this case, we want to add the skew and scale animation to the shadows <em>within</em> the shadow space. If you&#8217;re a reverse-order kind of person, this means that the shadows are first skewed and scaled, just like the trees, and then projected onto the &#8220;ground.&#8221; It&#8217;s the same thing:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> update<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">// animate trees</span>
&nbsp;
  bigShadow.<span style="color: #006633;">setTransform</span><span style="color: #009900;">&#40;</span>shadowTransform<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  bigShadow.<span style="color: #006633;">scale</span><span style="color: #009900;">&#40;</span>scaleX, scaleY<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  bigShadow.<span style="color: #006633;">skewX</span><span style="color: #009900;">&#40;</span>bigSkewAngle<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// animate littleShadow</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p style="text-align: center;"><a href="http://extremelysatisfactorytotalitarianism.com/projects/ns/transformtree/"><img class="size-full wp-image-1888 aligncenter" title="final result" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/05/trees_shadow_transformed.png" alt="" width="560" height="546" /></a></p>
<p>The source is, again, all in the project repository, but here are the pertinent files. I&#8217;m linking to the versions as of this writing so things don&#8217;t get confusing; be sure to check if there are more recent revisions:</p>
<p style="padding-left: 30px;"><a title="TransformTree.gwt.xml" href="https://code.google.com/p/gwt-ns/source/browse/trunk/demos/transformtree/src/gwt/ns/demo/transformtree/TransformTree.gwt.xml?r=58">TransformTree.gwt.xml</a><br />
<a title="TreesWidget.java" href="https://code.google.com/p/gwt-ns/source/browse/trunk/demos/transformtree/src/gwt/ns/demo/transformtree/client/TreesWidget.java?r=59"> TreesWidget.java</a><br />
<a title="TreesWidget.ui.xml" href="https://code.google.com/p/gwt-ns/source/browse/trunk/demos/transformtree/src/gwt/ns/demo/transformtree/client/TreesWidget.ui.xml?r=62"> TreesWidget.ui.xml</a></p>
<h3 id="halloshame">Hall of Shame</h3>
<p>I can&#8217;t resist comparing the rendering results between browsers. The actual transforms hold up well across platforms, which is nice, but border-radius results definitely leave something to be desired.</p>
<p>Internet Explorer remains kind of cute in its differently-abledness. WebKit and Opera are lagging Firefox in quality here, to varying degrees. Some of the disparity can be attributed to using a different radius for each corner, but gaps rear their ugly heads everywhere. This can be more than a little distracting when light colors are peaking around dark borders, or vice versa.</p>
<p>Please note that all of these screenshots come from a Windows machine. I hear that Snow Leopard&#8217;s Safari can fully hardware accelerate transforms, and I&#8217;m sure it also renders border-radius flawlessly and spends idle cycles scrubbing the wetlands*. Regardless, there are enough errant pixels here to drive anyone crazy.</p>
<p><strong>Chrome 6.0.401.1 dev</strong><br />
<img class="aligncenter size-full wp-image-1895" title="Rendering - Chrome" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/05/comparison_chrome.png" alt="" width="560" height="146" /></p>
<p><strong>Firefox 3.6.4</strong><br />
<img class="aligncenter size-full wp-image-1896" title="Rendering - Firefox" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/05/comparison_firefox.png" alt="" width="560" height="146" /></p>
<p><strong>Internet Explorer 8</strong><br />
<img class="aligncenter size-full wp-image-1897" title="Rendering - IE8" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/05/comparison_ie8.png" alt="" width="560" height="146" /></p>
<p><strong>Internet Explorer 9 Platform Preview 2 (v1.9.7.7.66.6000)</strong><br />
<img class="aligncenter size-full wp-image-1898" title="Rendering - IE9" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/05/comparison_ie9.png" alt="" width="560" height="146" /></p>
<p><strong>Opera 10.53</strong><br />
<img class="aligncenter size-full wp-image-1899" title="Rendering - Opera" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/05/comparison_opera.png" alt="" width="560" height="146" /></p>
<p><strong>Safari 4.0.5 (531.22.7)</strong><br />
<img class="aligncenter size-full wp-image-1900" title="Rendering - Safari" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/05/comparison_safari.png" alt="" width="560" height="146" /></p>
<p>*though I read in a forum post that Opera could do that before WebKit even filed a bug for it.</p>
]]></content:encoded>
			<wfw:commentRss>http://extremelysatisfactorytotalitarianism.com/blog/?feed=rss2&amp;p=1763</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I Guess In Theory That Needs Fixing</title>
		<link>http://extremelysatisfactorytotalitarianism.com/blog/?p=1790</link>
		<comments>http://extremelysatisfactorytotalitarianism.com/blog/?p=1790#comments</comments>
		<pubDate>Sat, 15 May 2010 00:27:40 +0000</pubDate>
		<dc:creator>Brendan Kenny</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[graphics]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[ns]]></category>
		<category><![CDATA[standards]]></category>
		<category><![CDATA[transforms]]></category>
		<category><![CDATA[w3c]]></category>
		<category><![CDATA[webkit]]></category>
		<category><![CDATA[WebKitCSSMatrix]]></category>

		<guid isPermaLink="false">http://extremelysatisfactorytotalitarianism.com/blog/?p=1790</guid>
		<description><![CDATA[If you pay close attention, you&#8217;ll notice that the &#8220;demos&#8221; or &#8220;experiments&#8221; that people like us inflict on the world tend to be most intriguing just before you actually see them run, when they&#8217;re just a thumbnail, in a list, &#8230; <a href="http://extremelysatisfactorytotalitarianism.com/blog/?p=1790">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you pay close attention, you&#8217;ll notice that the &#8220;demos&#8221; or &#8220;experiments&#8221; that people like us inflict on the world tend to be most intriguing just before you actually see them run, when they&#8217;re just a thumbnail, in a list, on some gallery page.</p>
<p>I have to add a corollary, of sorts: apparently my work is a lot more interesting when I&#8217;m using matrix operations in one way but the browser thinks I&#8217;m using them in another.</p>
<p style="text-align: center;"><a href="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/05/clock_oops.png"><img class="aligncenter size-full wp-image-1792" style="border: 1px solid black;" title="crazy cakes" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/05/clock_smaller.png" alt="" width="400" height="533" /></a></p>
<p>There&#8217;s a lesson in there somewhere.</p>
<p>Just about <a title="Projects - Extremely Satisfactory Totalitarianism" href="http://extremelysatisfactorytotalitarianism.com/blog/?page_id=1455">every little application</a> I&#8217;ve written using transforms needs to be recompiled and rereleased, but these are the dangers of using still-developing standards. In the meantime, you&#8217;ll get some entertaining results (perhaps more so than before) in a nightly WebKit or nightly/dev Chrome release. They recently switched the order of WebKitCSSMatrix multiplication to the &#8220;right&#8221; way (unless you did computer graphics in the 80s), but kept <a title="CSS 3D Transforms Module Level 3 - CSSMatrix" href="http://www.w3.org/TR/css3-3d-transforms/#cssmatrix-interface">matrix entry access</a> the same (e.g. &#8220;m14&#8243; is the entry in the fourth row, first column).</p>
<p>The result is that a simple transform is unaffected (I*M = M*I), a more complex transform is kind of backwards but recognizable, and a transform where I get tricky—manipulating a matrix directly and then mixing it with one of the first two—goes satisfyingly nuts.</p>
<p>Some back story: about two and a half weeks ago, I sent <a title="Harmonizing CSSMatrix and SVGMatrix [2D]" href="http://lists.w3.org/Archives/Public/public-fx/2010AprJun/0022.html">an email</a> to a W3C mailing list asking for clarification on what the SVG- and CSSMatrix notation/order &#8220;should&#8221; be. I got no response on the list. Too long winded? Probably, but it turns out it was because some WebKit developers recognized the issue as a bug in their implementation, <a title="Bug 38337 - CSSMatrix.multiply() method works backwards relative to SVGMatrix" href="https://bugs.webkit.org/show_bug.cgi?id=38337">filed it</a>, and—before I even thought to check Bugzilla a few days later—had <a title="Changeset 58584" href="http://trac.webkit.org/changeset/58584">landed the change</a>.</p>
<p>Here we should all thank Simon Fraser and Chris Marrin over at Apple, not only for fixes like this, but for their involvement (with others, of course) in making CSS transforms exist in the first place. But not only are they quick, they have also been incredibly open (if a bit busy) to discussing how to get the standard right. I may be the only developer using this object outside of a mobile browser (it&#8217;s probable), but I&#8217;m still a nobody; it&#8217;s nice for that not to matter.</p>
<p>If you&#8217;re actually using my library and are worried about the unstable behavior: existing code will continue to work perfectly with all officially released browsers. As of yesterday, <a title="Downloads - gwt-ns - Project Hosting on Google Code" href="https://code.google.com/p/gwt-ns/downloads/list">the latest version</a> also takes care of pre-release browsers, on top of adding a bunch of new and faster features you&#8217;ll want to use anway. There is <a title="Bug 38953 - CSSMatrix value attributes (m11-m44) should be transposed" href="https://bugs.webkit.org/show_bug.cgi?id=38953">one last WebKit bug</a> I&#8217;m waiting on, which will change either the spec or their implementation. CSSMatrix is a pretty small interface—there&#8217;s not much left to clarify—so I&#8217;m hopeful that things will settle down after that.</p>
<p>This is the price we pay for riding the bleeding edge, but don&#8217;t discount the fact that your project really might be better a little broken. Thumbnails help, too.</p>
]]></content:encoded>
			<wfw:commentRss>http://extremelysatisfactorytotalitarianism.com/blog/?feed=rss2&amp;p=1790</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Firefox Ethology</title>
		<link>http://extremelysatisfactorytotalitarianism.com/blog/?p=1719</link>
		<comments>http://extremelysatisfactorytotalitarianism.com/blog/?p=1719#comments</comments>
		<pubDate>Wed, 28 Apr 2010 19:51:14 +0000</pubDate>
		<dc:creator>Brendan Kenny</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[bugzilla]]></category>
		<category><![CDATA[ethology]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[gwtbox2d]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[ns]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[spidermonkey]]></category>
		<category><![CDATA[tracemonkey]]></category>
		<category><![CDATA[Web Workers]]></category>

		<guid isPermaLink="false">http://extremelysatisfactorytotalitarianism.com/blog/?p=1719</guid>
		<description><![CDATA[Barely related: I&#8217;ve written a design document (of sorts) for my implementation of web workers in GWT. Like the library itself, the document is fairly rough, but it does give a pretty good overview of the current state of things. &#8230; <a href="http://extremelysatisfactorytotalitarianism.com/blog/?p=1719">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Barely related: I&#8217;ve written a design document (of sorts) for my implementation of web workers in GWT. Like the library itself, the document is fairly rough, but it does give a pretty good overview of the current state of things. It&#8217;s actually in a Wave, for better formatting and the hope of some feedback, so if you&#8217;d like to take a look and can&#8217;t, drop me a line and I can send you an invite. You can find the link to the wave in <a title="RFC: Web worker proposal and proof of concept - Google Web Toolkit Contributors | Google Groups" href="http://groups.google.com/group/google-web-toolkit-contributors/browse_thread/thread/72575f10314c454b/b70023a7b26b026c?#b70023a7b26b026c">this thread</a>.</p>
<p>On to the actual topic of the day.</p>
<h3>That Crashing Thing</h3>
<p><em>[Update added at bottom of post.]</em></p>
<p>I&#8217;m happy to report that I have been <del datetime="2010-04-28T21:23:41+00:00">un</del>able to crash Firefox 3.6.<strong>4</strong> beta 1 <em>[only once]</em> using my <a title="Web Worker Test - Blocks" href="http://extremelysatisfactorytotalitarianism.com/projects/experiments/2010/03/boxdemo/">Blocks worker test</a>. I originally noticed the change in one of the 3.7 nightlies, but it&#8217;s nice that it landed earlier. Unfortunately, I&#8217;ve been unable to track down the bug that fixed it, even after spending way too long with Bugzilla yesterday.</p>
<p>Part of the problem is that the stack traces from the crashes were never definitive (to my eyes, at least). All of them were on account of an &#8220;EXCEPTION_ACCESS_VIOLATION,&#8221; but it sometimes happened in TraceMonkey&#8217;s TraceRecorder, indicating my earlier guesses were correct, and sometimes in the JS string code, indicating not so much.</p>
<p>One factor that I actually forgot to mention in my last post is that the worker object running the physics simulation is actually discarded and reloaded from file every time the test level is changed or reset. In a real application, you&#8217;d want to avoid this if at all possible (depending on the browser, the script file might have to be re-parsed, re-compiled, or—serious horrors—re-downloaded). In this case, however, it was a great way to put the worker emulation code through its paces: the old, &#8220;frustrated-user-quadruple-button-click&#8221; stability test. It actually helped me find a nice little NPE that only occurred in the unlikely event that a terminate() call came after an emulated worker was created but before it actually started running.</p>
<p>I&#8217;m going to wildly speculate—with the very real chance that I&#8217;ve missed something on Bugzilla—that something similar was happening with Firefox. The facts:</p>
<ol>
<li>an &#8220;EXCEPTION_ACCESS_VIOLATION&#8221;</li>
<li>the page would only crash after the worker was reloaded at least once (though often, when restoring, it would crash again immediately)</li>
<li>the crash frequently occurred with a call to JS_MakeStringImmutable(), which, MDC <a title="JS_MakeStringImmutable - MDC" href="https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_MakeStringImmutable">tells us</a>, &#8220;applications must call&#8230;before sharing a JSString among threads&#8221;</li>
</ol>
<p>Thinking what I&#8217;m thinking?</p>
<p>The weird thing is that nothing in the <a title="Bug List" href="https://bugzilla.mozilla.org/buglist.cgi?quicksearch=ALL%20status1.9.2:.4-fixed">complete list of changes</a> really matches the situation. The closest I can find is <a title="Bug 547399 &amp;ndash; Workers: Don't let worker messages run if the worker is suspended" href="https://bugzilla.mozilla.org/show_bug.cgi?id=547399">Bug 547399</a>, &#8220;Don&#8217;t let worker messages run if the worker is suspended,&#8221; but the patch doesn&#8217;t touch any of the files I was combing through, nor do the developers involved think that the bug could trigger something as serious as a crash. It does, however, prevent a possible race condition dealing with passing strings between threads, so, who knows? Maybe my crash didn&#8217;t get enough hits and the fix is just a side effect of something else.</p>
<p>Still, it&#8217;s a welcome development. Thanks, Mozilla.</p>
<h3>In Their Slowness</h3>
<p>When I wrote the Blocks test, Firefox 3.6.0 really was as fast as the second test level would indicate, though there were hints that it was losing a lot of speed due to the way it got along with TraceMonkey. What I didn&#8217;t realize was that TraceMonkey wasn&#8217;t involed <em>at all</em>; JIT compilation was disabled in web workers until 3.6.2 and <a title="Bug 538440 – We never jit DOM workers" href="https://bugzilla.mozilla.org/show_bug.cgi?id=538440">this bug</a>. Imagine my surprise a month later: I finally have the time to post the test and Firefox can&#8217;t even manage the IE8 level. There was some frustration.</p>
<p>Our clues:</p>
<ol>
<li>It&#8217;s happened before. I think. Some code just doesn&#8217;t take to the way TraceMonkey traces, so the engine needs a set of heuristics to determine when to just give up and interpret. Scripts will sometimes be misclassified, and this seems to be just such a case. There was a really interesting example of this <a title="an overview of TraceMonkey - Mozilla Hacks - the Web developer blog" href="http://hacks.mozilla.org/2009/07/tracemonkey-overview/comment-page-1/#comment-2093">discovered and diagnosed</a> in front of a live audience (I love you, open development) and <a title="Bug 504829 - declining TM performance with repeated runs of test case" href="https://bugzilla.mozilla.org/show_bug.cgi?id=504829">the bug</a> is still open. The code involved is rather different than this case, but the connection is too nice to think too much about confirmation biases.</li>
<li>I mentioned this before, but just disable JIT compilation and try the test. This <del datetime="2010-04-28T21:23:41+00:00">can be done in about:config</del>, but it&#8217;s a lot easier to just turn on the console or script panels in Firebug. While it&#8217;s not as fast as it once was (Firebug is running, after all), you&#8217;ll usually see the blocks speed up rather comically.</li>
</ol>
<p>The really humorous part of this whole situation is that I got <a title="&quot;We never jit DOM workers&quot; - Extremely Satisfactory Totalitarianism" href="http://extremelysatisfactorytotalitarianism.com/blog/?p=912">exactly what I wanted</a>: a performance update rolled out in a point release. I still agree with the sentiment, and this is undoubtedly an on-average win for performance. But, seriously, can I just have my interpreter back?</p>
<p><em>[Update: Almost immediately after publishing this post, I was able to crash 3.6.4; let's just say it will crash only rarely. Notably, the crash had nothing to do with JSString and occurred, once again, in TraceRecorder.</p>
<p>In addition, turning off JIT compilation in about:config—originally mentioned above—<a title="Bug 530641 - Workers: Should respect JS JIT pref" href="https://bugzilla.mozilla.org/show_bug.cgi?id=530641">will not work</a> to get the speedier Firefox back in action. Using Firebug to accomplish the same thing only works at first (and generally stops if you reset the test), so you'll have to extrapolate from that first few seconds of speediness to imagine what once gloriously was.</p>
<p>There is a bug: <a title="Bug 562455 - TM: Web Worker test case performance regression with JIT" href="https://bugzilla.mozilla.org/show_bug.cgi?id=562455">Bug 562455</a>, but I am a total Bugzilla noob, so expect it to be duped or something in 3...2... =]</em></p>
]]></content:encoded>
			<wfw:commentRss>http://extremelysatisfactorytotalitarianism.com/blog/?feed=rss2&amp;p=1719</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On Web Workers, GWT, and a New Physics Demo</title>
		<link>http://extremelysatisfactorytotalitarianism.com/blog/?p=932</link>
		<comments>http://extremelysatisfactorytotalitarianism.com/blog/?p=932#comments</comments>
		<pubDate>Thu, 08 Apr 2010 03:10:07 +0000</pubDate>
		<dc:creator>Brendan Kenny</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[gwtbox2d]]></category>
		<category><![CDATA[ie]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[ns]]></category>
		<category><![CDATA[physics]]></category>
		<category><![CDATA[tracemonkey]]></category>
		<category><![CDATA[v8]]></category>
		<category><![CDATA[Web Workers]]></category>

		<guid isPermaLink="false">http://extremelysatisfactorytotalitarianism.com/blog/?p=932</guid>
		<description><![CDATA[That original proof of concept gwtBox2d demo has slowly evolved along with the rest of the GWTns library. Though only a small portion of the original code remains, it has ended up being a pretty great stress test for new &#8230; <a href="http://extremelysatisfactorytotalitarianism.com/blog/?p=932">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;">
<p><img class="aligncenter size-full wp-image-1421" title="boxes" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/03/boxes_blue_and_white.png" alt="" width="560" height="126" /></p>
<p>That original <a title="This page best viewed with a quad-core CPU" href="http://extremelysatisfactorytotalitarianism.com/blog/?p=572">proof of concept gwtBox2d demo</a> has slowly evolved along with the rest of the <a title="gwtns" href="https://code.google.com/p/gwt-ns/">GWTns</a> library. Though only a small portion of the original code remains, it has ended up being a pretty great stress test for new and tweaked library functionality; no matter how much performance improves, there can always be more blocks.</p>
<p>While the program itself doesn&#8217;t really do anything useful in a meaningful sense, or even help move Web Workers beyond a <a title="Simulated Annealing" href="http://www.mozbox.org/pub/simulatedAnnealing/index.xhtml">useful-for-simulated-annealing-while-animating-a-png</a> demo reputation, I think it does have its own demonstrative value. And really, I have enough fun poking at it that I figured I might as well just gussy up the styling a bit and let other people have a turn.</p>
<h3>Apologies First</h3>
<ul>
<li>If you&#8217;ve run the worker version of the demo without reading this, and were running <em>(pre-3.6.4)</em> Firefox, I probably crashed your browser. And on reopening, promptly did it again. Sorry about that (hi SUMO!). This isn&#8217;t a problem inherent to workers or this library (see TraceMonkey tear it up in <a title="The Rationals" href="http://extremelysatisfactorytotalitarianism.com/projects/ns/rationals/">The Rationals</a>) but (probably) due to branch heavy/poorly traceable physics code. I&#8217;ll write more about Firefox below.</li>
<li>Stacking boxes turns out to be a good stressor, but Box2d can do much cooler things than this, often requiring more forgiving levels of computing power. For more examples, see the <a title="JBox2D demos" href="http://www.jbox2d.org/v2demos/">JBox2d demos</a> or some of the many Flash/Alchemy <a title="Box2d Flash World Construction Kit + Alchemy Port" href="http://www.sideroller.com/wck/">demos</a> out there.</li>
</ul>
<h3>The Demo</h3>
<p>Now that you&#8217;ve been warned, here are the links. Return (or keep reading) for more on the application, your favorite browser, and some thoughts on using web workers in GWT.</p>
<ul>
<li><a title="Web Worker Test - Blocks" href="http://extremelysatisfactorytotalitarianism.com/projects/experiments/2010/03/boxdemo/"><strong>Blocks</strong>, native web workers where available</a> (may crash Firefox < 3.6.4)</li>
<li><a title="Web Worker Test - Blocks - Forced Emulation" href="http://extremelysatisfactorytotalitarianism.com/projects/experiments/2010/03/boxdemo/noworker.html"><strong>Blocks</strong>, worker emulation in all browsers</a> (safe)</li>
</ul>
<p><span id="more-932"></span></p>
<h3>Please Press That</h3>
<p>First, the basics. Browsers that can run the physics engine in a web worker will do so, those that can&#8217;t, won&#8217;t, and which is happening should be obvious. If you&#8217;d like to force worker-emulation mode no matter what support is available, there&#8217;s a link for that at the bottom right.</p>
<p><img class="size-full wp-image-1624 alignleft" title="Change Test Level" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/04/test_level.png" alt="" width="260" height="252" /> Also on the right, you can select four different stress levels; the first three are named for the level at which that particular browser can regularly keep the blocks stacked, a mark of a stable simulation. Note that &#8220;Firefox 3.6&#8243; is really 3.6, not the here-slower 3.6.3 (the security updates are a net positive, though). Unfortunately, my Windows-browser-centrism is on full display, but feel free to mentally insert &#8220;Safari&#8221; in the list above or below &#8220;Chrome,&#8221; whichever tickles your personal fanatical tendencies. I&#8217;m also hoping that UI purists can forgive my use of radio buttons and that redundant &#8220;reset&#8221; button. In some impromptu testing, users tended to be reluctant to click on things (maybe from all that &#8220;crash your browser&#8221; talk), so those elements function as a bit of a hack to ease users into a first click.</p>
<p>Finally, while we&#8217;re discussing sins: yes, those are all divs. I was originally going to use this opportunity to check out <a title="raphaelgwt" href="http://code.google.com/p/raphaelgwt/">Hydro4GE&#8217;s Raphael wrapper</a>, but testing and optimizing the transform module in something approaching a real application (i.e. transforming elements when you want to be spending execution time doing anything but transforming elements) was too great an opportunity to pass up.</p>
<h3>Test Background</h3>
<p>A physics engine is, at least in this case, an ideal match for a web worker. Once the simulator and display models are initialized, only a very small delta needs to be passed to keep them synchronized ([position + orientation] * number of bodies). Since you want to update the display as often as possible, but total message-passing cost must be kept to a minimum for performance, frequent small payloads work well.</p>
<p>Using Box2d in this particular, &#8220;one-code-fits-all&#8221; approach also works nicely because there is a natural &#8220;chunking&#8221; point between simulation steps. Though it may be possible to wring out a little more responsiveness in the non-worker case by further dividing these steps, the natural split is convenient and even the slowest browser released in the last 1.05 years can handle this code without throwing a slow script warning.</p>
<p>Much like many of the worker demos that came out about a year ago, this one aims to clearly demonstrate the benefits of taking a computation-heavy script out of the main execution thread. I think this one is a little more fair, though, because I actually try to make it run well in browsers without web worker support.</p>
<p>Let&#8217;s look at the emulated-worker mode first.</p>
<h3>The Emulation Test</h3>
<p><a title="Web Worker Test - Blocks - Forced Emulation" href="http://extremelysatisfactorytotalitarianism.com/projects/experiments/2010/03/boxdemo/noworker.html">This is an &#8220;Emulation Test&#8221;</a> and not, say, a &#8220;Regular Test,&#8221; because every component interacts with the simulator as if it were really running within a web worker. While this does introduce some overhead into the normal timer/callback setup, the worker specification is so simple that it ends up being pretty minimal, especially in the face of the benefits of a unified code base.</p>
<p>As a result of the aforementioned &#8220;not trying to be a jerk to older browsers&#8221; approach, most UAs acquit themselves fairly well in worker emulation mode. At the lower stress levels, there will likely be little difference between the worker and non-worker versions.</p>
<p><img class="alignright size-full wp-image-1704" title="Emulated Worker Rates" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/04/rates_emulated2.png" alt="" width="205" height="168" />As the stress level is increased, though, it should be clear that the &#8220;Physics Rate&#8221; (the number of simulation steps per second) and the &#8220;Animation Rate&#8221; (the number of display updates per second) become tightly coupled. Even though the physics engine is updating as often as it can and the interface is only requesting 30 refreshes per second, when the rate of both fall below 30Hz, there is no effective difference betwen what they want (John Resig explains this really well in his <a title="How JavaScript Timers Work" href="http://ejohn.org/blog/how-javascript-timers-work/">timer tutorial</a>).</p>
<p>The end result is obvious to anyone who has used a sluggish website (i.e. everyone). Since the two are tightly coupled, if the physics step takes longer, the interface will be proportionally less responsive. Moreover, since most current browsers refresh styling on the main thread, nothing is safe.</p>
<p>That&#8217;s what the fourth and highest stress level is for. <a title="Web Worker Test - Blocks - Forced Emulation" href="http://extremelysatisfactorytotalitarianism.com/projects/experiments/2010/03/boxdemo/noworker.html">Try it again</a>, in even the fastest browser (unless you&#8217;re from the future). Move your mouse over anything blue, which will trigger a color change via a <code>:hover</code> pseudo-class (typically much faster than doing the switch in Javascript). Try clicking and dragging to use the slingshot block. If your site&#8217;s interface responds in any way <em>approaching</em> that sluggishness, you are alienating your users and are most likely losing a number of them.</p>
<h3>The Native Test</h3>
<p>The native-worker mode will use web workers for the physics engine if available; if not, the emulated-worker mode will automatically be used as a fallback. The benefit is simple, as long as more processing power is available. With the physics simulator off the main thread, no matter how long its time steps take, it won&#8217;t be able to dominate interface refreshes.</p>
<p><img class="alignright size-full wp-image-1672" title="Native Worker Rates" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/04/rates.png" alt="" width="205" height="168" />Once again, at lower stress levels the improvement might be slight, but <a title="Web Worker Test - Blocks" href="http://extremelysatisfactorytotalitarianism.com/projects/experiments/2010/03/boxdemo/">try the test again</a> <strong>(may crash Firefox)</strong> and set it to the highest stress level. Then test the UI. Though all the current browsers are still unable to keep up with the physics step, this fact has significantly less impact on the interaction responsiveness. The slingshot seems connected to your mouse drag. The blocks immediately change color when you hover over them. The standard form elements respond to your cursor. It&#8217;s nice when your website isn&#8217;t acting like Sonic 2 when you just lost all your rings.</p>
<p>The point isn&#8217;t a new one, but it also doesn&#8217;t have much to do with a physics engine, either. If you move your heavy scripts to a worker, you&#8217;ll have a lot less worrying to do about keeping an interface that is snappy and responsive, which is in many ways our first responsibility. Let the newer browsers do the heavy lifting for you, and let libraries pick up the older ones&#8217; slack. Workers really are easier than you think.</p>
<h3>Browser quirks</h3>
<p><strong>Chrome.</strong> So very fast. The only minor complaints I have are that <code>:hover</code> does not update without a mouse move (even if the hovered element itself moves), and that, in terms of apparent sane behavior, <code>-moz-user-select</code> beats the pants off of <code>-webkit-user-select</code>.</p>
<p><strong>Firefox.</strong> Again, the worker version will likely crash the browser. This particular type of code is just not conducive to tracing and turns out to be a bit of a pathological case for TraceMonkey’s current tracing heuristics. Note that this might not actually be the cause of the crashes, but it is similar enough to TraceMonkey bugs fixed in 3.5 that I’m going to assume it to be the case. However, TM’s issues with my code are made more clear since worker scripts are now JITed; Firefox 3.6.x (with x&gt;1) can no longer meet the performance level I set for it. Disable JIT compilation (or just turn on the Firebug Script or Console panels) and performance will double or triple. The entire situation is amusing enough that I think I’m going to write a post dedicated to it. <em>Update: I can’t get recent 3.7 nightlies to crash. Hooray! Still slow.</em></p>
<p><strong>Internet Explorer 8.</strong> Obviously IE is going to be at the shallow end of the performance pool, but I&#8217;ve been surprised at how well it performs, actually. Matrix filter transforms are still somewhat slow even after my <a title="On the Behavior of 2d Transformations in Internet Explorer" href="http://extremelysatisfactorytotalitarianism.com/blog/?p=1002">earlier work</a>, but they seem more fill-bound than geometry-bound. Small rectangles and no overdraw help, too. Finally, Page Speed warns about possible problems with <code>:hover</code> on non-anchors with a strict doctype, but I haven&#8217;t detected this in practice.</p>
<p><strong>IE9 Platform Preview.</strong> Unfortunately there appears to be some bug that is preventing the JSON payload of worker messages from initializing properly in the Preview, which then causes an error when they are deserialized. However, setting breakpoints where the messages are created causes the Preview to crash, so I&#8217;m not pursuing the problem at this time.</p>
<p><strong>Mobile.</strong> I have limited mobile browser testing means, but I&#8217;m proud to say that the newest mobile Safari on an old iPod touch runs the app at a rock-solid 1fps. Since most (all?) current mobile devices have only one core for Javascript execution, the UI and simulation threads will compete for processor time and there will be no real win for using workers in this way. For now, workers might only allow you something like a blocking http request in the mobile space, but the future will undoutedly bring multiple logical cores. In the meantime, if you want physics, far better to look at something brought to you by Objective-C or the NDK.</p>
<p><strong>Opera.</strong> 10.5 came out after I finished this project, but since I was already adding transform support for the browser, a simple recompile enabled an Opera permutation. Opera seems to be actively developing their web worker implementation (and making some very helpful clarifications on the WHATWG mailing list), but no functionality appears available in the current release. In this example, 10.5&#8242;s Carakan Javascript engine is very fast and acquits itself well, but unfortunately odd bugs are manifesting, usually in the form of disappearing or non-interacting blocks. While I&#8217;m willing to concede that the problem probably lies in GWT or my own code, it is annoying, to say the least, that when I activate the Dragonfly debugger—and Javascript is interpreted—the program starts behaving correctly. I haven&#8217;t been able to dedicate the time needed to debug without the debugger yet, so full Opera support will have to wait. I would appreciate any insight anyone has on this problem.</p>
<p><strong>Safari.</strong> On Windows, Safari is pretty much like Chrome with a few more ways to crash it thrown in (mostly via the inspector). On the Mac, Safari really is a class act. A shiny new 3.06GHz MacBook Pro runs the highest test level in something approaching interactive (though not fast enough for a stable timestep, yet). Perhaps more impressive: an old 800MHz dual G4 is able to handle the IE8 level easily, and is able to update the interface faster than 28fps even while the simulation is at the highest setting. I don&#8217;t advocate always using all available processing power for rendering a web page, but if the alternative is an unresponsive interface and an impatient user, use what you have.</p>
<h3>On Workers and GWT</h3>
<p>These thoughts apply to using workers in general, but I&#8217;ll focus on GWT in particular. Once again, I&#8217;m not sure that this example fully supports my call for wider worker use, but in using them, I&#8217;m increasingly convinced that they will soon be considered an essential part of building a faster web.</p>
<p>The GWT compilation process is not currently a perfect fit for generating web workers, but web workers are in many ways a perfect fit for the current trends in GWT development. As the cult of Ray Ryan has spread, the MVP pattern and event buses have become the poster children for structuring large GWT applications. This is the world that workers were made for.</p>
<p>Worker requirements, again:</p>
<ol>
<li>No shared state except where created and maintained by message passing.</li>
<li>No DOM access.</li>
</ol>
<p>I don&#8217;t think the connection could be much clearer. Hook up a worker object to your event bus, finish pulling the view out of model and presenter code, done.</p>
<p>Pragmatically, there is of course more to consider. Code with truly separated logic and presentation will need little change; code otherwise structured will likely need non-trivial work. The point isn&#8217;t that the addition of workers will come free, but that—if you&#8217;re already using these patterns—the barrier to entry is lowered enough that even modest potential performance gains can justify a day or two spent benchmarking.</p>
<h3>Opportunities</h3>
<p>The purpose often given for web workers is that they allow certain kinds of scripts to be written more naturally, without worrying about program flow disrupting the user experience. Blocking I/O and long-running calculations are usually then given as examples. While these are now possible in platform-specific applications—like a (modern) browser extension—the reality is that IE6, 7, and 8 are going to be with us for a long time. Moreover, as good GWT developers, we are already disciples of asynchrony (in addition to that whole Ray Ryan thing); let&#8217;s not regress.</p>
<p>The most obvious worker candidates are anywhere an IncrementalCommand is found, as long it&#8217;s needed for more than updating the DOM (and even then, there is always innerHTML string creation). But in fact, any long-running background process that reduces interface responsiveness should be strongly considered for extraction to a worker. Try the <a title="Web Worker Test - Blocks - Forced Emulation" href="http://extremelysatisfactorytotalitarianism.com/projects/experiments/2010/03/boxdemo/noworker.html">emulated worker test</a> again. If the physics rate is 5fps, that means a step takes only 200ms, nowhere near long enough to trigger a slow script warning. But notice again the effect that has on the interface. Just because something can be done without triggering an error doesn&#8217;t mean that your application doesn&#8217;t suffer for it, especially if you have to do it more than once.</p>
<p>Finally, I don&#8217;t know what the guerilla-GWT-developer demographic is like, but workers are also good for tasks that might normally be performed with a server roundtrip but become limited by bandwidth, throughput, or latency. Local image editing has become a prominent example of this, but really any transformation of a large data set (geometric or otherwise) would qualify, as long as security issues were carefully addressed.</p>
<h3>Potential Results</h3>
<p>Like any multi-threaded approach, there will be trade-offs. There will always be overhead. Gains will be sublinear. With no way to discover the number of processes/threads that can be executed in parallel (as limited by the particular hardware and browser), blind guesses will have to be made. This is mitigated by the fact that extra workers just devolve to same-core native context switching, but before you start writing that worker-based MapReduce implementation, stop being ridiculous and remember that single- and dual-core processors are going to be the (client) norm for a few years yet.</p>
<p>I don&#8217;t want to sound too dour, though. Once again, <em>you should be using web workers</em>. The point of the module I wrote for <a title="gwtns" href="https://code.google.com/p/gwt-ns/">GWTns</a> was to make this as easy as possible (though it certainly isn&#8217;t the only approach available). While it enables, by design, only a proper subset of worker functionality, this allows developers to use the exact same code for all browsers. I covered this pretty well in the post about <a title="Web Worker Example: The Rationals" href="http://extremelysatisfactorytotalitarianism.com/blog/?p=645">The Rationals worker example</a>, but I wanted to go over the end result again.</p>
<p>Older browsers will get an application where the worker object is constructed normally, the only strange behavior being that all messages passed to it are done so asynchronously. Overhead is designed to be as minimal as possible, though there is still more work to be done there. Newer browsers will be able to load the code as a true worker and <em>all</em> execution will be done asynchronously. Script execution that was causing the interface to lag is now off the UI thread. Perhaps most importantly, though, this scheme allows for full dev mode debugging; no need to change your workflow. This last part was pretty much essential for working out the kinks in the blocks demo, but from a larger perspective, development mode is itself the key to not going crazy doing GWT development (<em>Step 1: use dev mode. Step 2: use workers</em>).</p>
<p>I would be remiss if I didn&#8217;t mention that, while I&#8217;ve found my own code to be very stable, it is very much in an alpha-state and feature-incomplete. There aren&#8217;t many other options right now, but you could certainly write a worker script by hand or compile one from a module and then load it manually. SpeedTracer&#8217;s <a title="speedtracer: webworker" href="http://code.google.com/p/speedtracer/source/browse/#svn/trunk/src/client/ui/src/com/google/gwt/webworker">web worker code</a> might help you get started with this approach.</p>
<p>However you go about it, try workers out. I think you&#8217;ll be pleasantly surprised with the results.</p>
]]></content:encoded>
			<wfw:commentRss>http://extremelysatisfactorytotalitarianism.com/blog/?feed=rss2&amp;p=932</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>On the Behavior of 2d Transformations in Internet Explorer, Part 2</title>
		<link>http://extremelysatisfactorytotalitarianism.com/blog/?p=922</link>
		<comments>http://extremelysatisfactorytotalitarianism.com/blog/?p=922#comments</comments>
		<pubDate>Wed, 10 Mar 2010 02:17:58 +0000</pubDate>
		<dc:creator>Brendan Kenny</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[ie]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mathematics]]></category>
		<category><![CDATA[ns]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[transforms]]></category>

		<guid isPermaLink="false">http://extremelysatisfactorytotalitarianism.com/blog/?p=922</guid>
		<description><![CDATA[Unsurprisingly, the last post ran overlong. I&#8217;ll endeavor to stick to code and equations wherever possible, as they are generally faster for me to write and you to parse. Amateur-hour Illustrator work takes a little longer. All previous provisos still &#8230; <a href="http://extremelysatisfactorytotalitarianism.com/blog/?p=922">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><img class="aligncenter size-full wp-image-1359" title="Transformed rect" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/03/trans_rect1.png" alt="" width="446" height="336" /></p>
<p>Unsurprisingly, the <a title="Part 1" href="http://extremelysatisfactorytotalitarianism.com/blog/?p=1002">last post</a> ran overlong. I&#8217;ll endeavor to stick to code and equations wherever possible, as they are generally faster for me to write and you to parse. Amateur-hour Illustrator work takes a little longer.</p>
<p>All <a title="Caveats" href="http://extremelysatisfactorytotalitarianism.com/blog/?p=1002#caveats">previous provisos</a> still apply.</p>
<h3>Implementation</h3>
<p>If you&#8217;ve waded through that enormity of a post, you now know everything you need to get transformations working in Internet Explorer. To review:</p>
<ol>
<li><a href="http://extremelysatisfactorytotalitarianism.com/blog/?p=1002#whyMatrix">Keep an internal augmented matrix</a> to represent the current transformation. Manipulate it through some combination of programmatic access and the parsing of CSS-like transform functions.</li>
<li><a href="http://extremelysatisfactorytotalitarianism.com/blog/?p=1002#linearSupport">Apply the linear portion</a> of the affine transformation (the top 2&#215;2 entries of the matrix) to the element through IE&#8217;s Matrix Filter</li>
<li>Use &#8220;<a href="http://extremelysatisfactorytotalitarianism.com/blog/?p=1002#autoExpand">auto expand</a>&#8221; as the SizingMethod so the element can venture beyond its original confines.</li>
<li><a href="http://extremelysatisfactorytotalitarianism.com/blog/?p=1002#determineShift">Determine the shift</a> that IE has automatically applied through its &#8220;bounding box behavior.&#8221;</li>
<li><a href="http://extremelysatisfactorytotalitarianism.com/blog/?p=1002#translateTime">Translate the element</a> by increasing its <code>left</code> and <code>top</code> attributes by the translation from the internal matrix, less the shift found in step (4).</li>
<li><a href="http://extremelysatisfactorytotalitarianism.com/blog/?p=1002#minorProblems">Work around minor problems</a> like the limits of integer translations and problems due to altering layout via repositioning.</li>
</ol>
<p>I&#8217;ll run through each of these items in turn, sharing implementation details and some of the interesting behavior I ran across in testing. If you&#8217;re the impatient type (or the &#8220;I don&#8217;t care&#8221; type), source is <a href="http://extremelysatisfactorytotalitarianism.com/blog/?p=922#theCode">here</a>.<span id="more-922"></span></p>
<h3>1: Internal Representation</h3>
<p>The biggest win from this approach comes from the standard model/view split of the representation of the transformation and the actual DOM style of the element. For one, this means that all transformation DOM access is one way: nothing needs to be read. This also allows transformation-changing methods to alter only the matrix representation, which can happen in superfast JavaScript-land, leaving a single style-setting DOM access (or as few as possible) until just before the execution context is yielded.</p>
<p>My module uses GWT&#8217;s <code><a title="scheduleFinally JavaDoc" href="http://google-web-toolkit.googlecode.com/svn/javadoc/2.0/com/google/gwt/core/client/Scheduler.html#scheduleFinally(com.google.gwt.core.client.Scheduler.ScheduledCommand)">scheduleFinally()</a></code> mechanism to automate this process, accumulating transformation changes as they occur; each change only flags the need for a style update and doesn&#8217;t actually make one. Usually this means that the actual layout of an element is only updated once per animation frame—in a method named <code>commitTransform()</code>—and only if its transformation was actually changed. Combined with the fact that authors don&#8217;t have to intervene in this process (though it&#8217;s possible to do so), this is about as good as it gets.</p>
<p>For the update, I&#8217;ve given up using internal 4&#215;4 matrices on platforms (IE, Firefox) with no 3d transform support. I originally chose to use them out of hope for the future and to maybe do some tricksy things with projections, but the tradeoff—for now—isn&#8217;t worth it. Obviously the 4&#215;4 implementation will remain, lying in wait, but for the present IE and Firefox will default to 3&#215;3 matrices and the &gt; 50% savings in matrix multiplications. It&#8217;s no DOM access optimization, but in complicated transformations, the ops add up quickly.</p>
<p>(It&#8217;s worth noting that Chrome and Safari use a totally different 4&#215;4 matrix implementation, which is built around their native WebKitCSSMatrix. Due to <a title="WebKitCSSMatrix.idl" href="http://svn.webkit.org/repository/webkit/trunk/WebCore/css/WebKitCSSMatrix.idl">its design</a> (instances are immutable) memory use is quite a bit higher, but the tradeoff is that all matrix ops take place in native code. I&#8217;m planning on moving Firefox to its version of MozCSSMatrix (or even MozSVGMatrix) when it&#8217;s available.)</p>
<p>A note for anyone doing this in straight JavaScript: <em>please</em> use a matrix library optimized for 2d or 3d transforms. I&#8217;ve noticed that the <a title="Sylvester" href="http://sylvester.jcoglan.com/">Sylvester</a> library is widely used. While it is a great library, my understanding is that it was written for general matrix support, so you&#8217;ll get things like loop-based matrix multiplication, generalized inversion methods, and a lot of utilities that you&#8217;ll never use. When you only have 9 (or 16) matrix entries, a lot of these things can be massively sped up through special-case algorithms. Check out Vladimir Vukićević&#8217;s <a title="mjs: Simple Vector and Matrix Math for JS" href="http://blog.vlad1.com/2010/02/05/mjs-simple-vector-and-matrix-math-for-js/">mjs library</a> for something specifically intended for this purpose.</p>
<p>Finally, I currently only support procedural access to manipulating an element&#8217;s transformation, but this means that any transform set in a stylesheet will be clobbered. See <a title="Bringing CSS Transforms to Internet Explorer" href="http://paulbakaus.com/2008/08/16/bringing-css-transform-to-internet-explorer/">Transformie</a> for a good example of the parsing of an existing (and changing) list of transformation functions.</p>
<h3>2: Applying the Linear Transformation</h3>
<p>Interestingly, I&#8217;ve found that setting the Matrix Filter&#8217;s properties individually (and numerically) ends up causing significantly longer layout delays than setting the whole thing as a string. That is, this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> matFilter <span style="color: #339933;">=</span> target.<span style="color: #660066;">filters</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'DXImageTransform.Microsoft.Matrix'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
matFilter.<span style="color: #660066;">M11</span> <span style="color: #339933;">=</span> a<span style="color: #339933;">;</span>
matFilter.<span style="color: #660066;">M21</span> <span style="color: #339933;">=</span> b<span style="color: #339933;">;</span>
matFilter.<span style="color: #660066;">M12</span> <span style="color: #339933;">=</span> c<span style="color: #339933;">;</span>
matFilter.<span style="color: #660066;">M22</span> <span style="color: #339933;">=</span> d<span style="color: #339933;">;</span></pre></div></div>

<p>tends to somehow be much slower than the more naive</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> filt <span style="color: #339933;">=</span> <span style="color: #3366CC;">'progid:DXImageTransform.Microsoft.Matrix(M11='</span> <span style="color: #339933;">+</span> a<span style="color: #339933;">;</span>
filt <span style="color: #339933;">+=</span> <span style="color: #3366CC;">', M21='</span> <span style="color: #339933;">+</span> b<span style="color: #339933;">;</span>
filt <span style="color: #339933;">+=</span> <span style="color: #3366CC;">', M12='</span> <span style="color: #339933;">+</span> c<span style="color: #339933;">;</span>
filt <span style="color: #339933;">+=</span> <span style="color: #3366CC;">', M22='</span> <span style="color: #339933;">+</span> d <span style="color: #339933;">+</span> <span style="color: #3366CC;">')'</span><span style="color: #339933;">;</span>
target.<span style="color: #660066;">style</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'filter'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> filt<span style="color: #339933;">;</span></pre></div></div>

<p>Obviously the access method is different, so perhaps the matrix-filter object has been deprecated internally and it all goes through string parsing anyway. Or perhaps every set variable triggers an internal DOM change rather than using one lazy write. I&#8217;m not sure of the reason, but I&#8217;ve found that the first approach takes almost twice as long as the second, so I no longer use it. I&#8217;d be interested if anyone has other data points on the subject.</p>
<p>Unlike the current CSS3 implementations, IE will happily accept scientific notation in either case; don&#8217;t worry about number formatting through <code>toFixed()</code> or the like.</p>
<h3>3: &#8220;auto expand&#8221;</h3>
<p>I&#8217;m still convinced that whoever wrote SizingMethod didn&#8217;t like other humans and/or didn&#8217;t use their own browser.</p>
<h3>4: The Bounding-Box Shift, Take 1</h3>
<p>As a reminder, here again is the shifting behavior of an element under a pure rotation in Internet Explorer:</p>
<p><a href="http://extremelysatisfactorytotalitarianism.com/projects/misc/2010/02/ie8_live/rotate.html"><img class="aligncenter size-full wp-image-1352" title="IE naive rotation" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/03/ie_naive_rot.png" alt="" width="248" height="231" /></a></p>
<ul>
<li><a title="IE8: naive rotation" href="http://extremelysatisfactorytotalitarianism.com/projects/misc/2010/02/ie8_live/rotate.html">View example: uncorrected rotation</a> (previously posted)</li>
</ul>
<p>In the previous post, I assumed that we knew the dimensions of the transformed element&#8217;s axis-aligned bounding box when calculating IE&#8217;s bonus translation. By far the easiest way to find this information is to first set the linear portion of the transformation to the element&#8217;s matrix filter, then ask the element for its current <code>offsetWidth</code> and <code>offsetHeight</code>. IE faithfully updates these values to give the distance between the extremities of the transformed element in each dimension.</p>
<p><a href="http://extremelysatisfactorytotalitarianism.com/blog/?p=1002#determineShift">As determined last time</a>, the x-shift we need to remove is just half the original width, subtracted from half the bounding width. The same pattern applies vertically.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// original layout</span>
<span style="color: #003366; font-weight: bold;">var</span> x <span style="color: #339933;">=</span> target.<span style="color: #660066;">offsetLeft</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> y <span style="color: #339933;">=</span> target.<span style="color: #660066;">offsetTop</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> w <span style="color: #339933;">=</span> target.<span style="color: #660066;">offsetWidth</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> h <span style="color: #339933;">=</span> target.<span style="color: #660066;">offsetHeight</span><span style="color: #339933;">;</span>
&nbsp;
...
&nbsp;
<span style="color: #660066;">setInterval</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
<span style="color: #006600; font-style: italic;">// matrix filter applied</span>
...
&nbsp;
<span style="color: #006600; font-style: italic;">// find bounding box dimensions</span>
<span style="color: #006600; font-style: italic;">// IE has updated these values based on transform set above</span>
<span style="color: #003366; font-weight: bold;">var</span> wb <span style="color: #339933;">=</span> target.<span style="color: #660066;">offsetWidth</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> hb <span style="color: #339933;">=</span> target.<span style="color: #660066;">offsetHeight</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// determine how far origin has shifted</span>
<span style="color: #003366; font-weight: bold;">var</span> sx <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>wb <span style="color: #339933;">-</span> w<span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> sy <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>hb <span style="color: #339933;">-</span> h<span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// translation, corrected for origin shift</span>
<span style="color: #006600; font-style: italic;">// rounding helps, but doesn't eliminate, integer jittering</span>
target.<span style="color: #660066;">style</span>.<span style="color: #660066;">left</span> <span style="color: #339933;">=</span> Math.<span style="color: #660066;">round</span><span style="color: #009900;">&#40;</span>x <span style="color: #339933;">+</span> e <span style="color: #339933;">-</span> sx<span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'px'</span><span style="color: #339933;">;</span>
target.<span style="color: #660066;">style</span>.<span style="color: #660066;">top</span> <span style="color: #339933;">=</span> Math.<span style="color: #660066;">round</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">+</span> f <span style="color: #339933;">-</span> sy<span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'px'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">30</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><a href="http://extremelysatisfactorytotalitarianism.com/projects/misc/2010/02/ie8_live/rotate_offset_correction.html"><img class="aligncenter size-full wp-image-1353" title="IE offset rotation" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/03/ie_offset_rot.png" alt="" width="248" height="231" /></a></p>
<ul>
<li><a title="IE8: rotation with offset* correction" href="http://extremelysatisfactorytotalitarianism.com/projects/misc/2010/02/ie8_live/rotate_offset_correction.html">View example: slow corrected rotation</a> (via offsetWidth/Height)</li>
</ul>
<p>Well done, theory. This works, and since it works, this is essentially how I left my original implementation. I knew this approach was inherently slow, but (as I wrote before) I didn&#8217;t need to animate transformations so I didn&#8217;t worry about it.</p>
<p>The reason this method is slow is hopefully obvious. To describe its actions in a different way, it writes to an element&#8217;s style, reads computed values from its updated style—forcing at least a limited reflow—then writes to it again, all within the same execution context. Certain DOM disaster.</p>
<p>I ran head-on into this problem when I started to fling little boxes across the screen. Even with a full 2d physics library simulating the boxes, geometric transformations being calculated per box, and each box&#8217;s element being positioned absolutely to keep it out of the document flow, these four lines of code took up a full 40% of execution time.</p>
<p>A different approach is needed.</p>
<h3>4a. Better Box Bounds</h3>
<p>The straightforward way to <em>calculate</em> the size of the minimum axis-aligned bounding box of a transformed rectangle is to apply the linear transformation to each corner of the rectangle in turn. From the resulting points, find the minimum and maximum x- and y-coordinates, subtract, et voilà.</p>
<p><img class="aligncenter size-full wp-image-1218" title="IE bounding box dimensions" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/03/IESimpleBB.png" alt="" width="344" height="315" /></p>
<p>But that&#8217;s boring, redundant, and the nuns used to tell me that extra conditionals are the path to wickedness. Let&#8217;s see if we can do better.</p>
<p>First, we don&#8217;t care about the bounding box&#8217;s actual coordinates, we just need its width and height.</p>
<p>Second, because we only care about the width and height, we can <em>translate</em> the element and its bounding box in any way we wish. A translation affects all points in the same way, so the distance between two points is invariant under a translation. If we translate the element in such a way that its top left corner is moved to the origin, we will only have to transform 3 points, since linear transformations leave the origin in place.</p>
<p>The specific translation needed is irrelevant; conceptually, the element is now just a conveniently positioned rectangle with width <em>w</em> and height <em>h</em>.</p>
<p><img class="aligncenter size-full wp-image-1358" title="Untransformed rect" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/03/untrans_rect1.png" alt="" width="446" height="336" /></p>
<p>The non-origin corners of the rectangle have also been simplified. Their positions:</p>
<img src='http://s.wordpress.com/latex.php?latex=%5Cmathbf%7Bp%7D%20%3D%20%5Cbegin%7Bbmatrix%7D0%20%5C%5C%20h%20%5Cend%7Bbmatrix%7D&#038;bg=T&#038;fg=000000&#038;s=0' alt='\mathbf{p} = \begin{bmatrix}0 \\ h \end{bmatrix}' title='\mathbf{p} = \begin{bmatrix}0 \\ h \end{bmatrix}' class='latex' />
<img src='http://s.wordpress.com/latex.php?latex=%5Cmathbf%7Bq%7D%20%3D%20%5Cbegin%7Bbmatrix%7Dw%20%5C%5C%20h%20%5Cend%7Bbmatrix%7D&#038;bg=T&#038;fg=000000&#038;s=0' alt='\mathbf{q} = \begin{bmatrix}w \\ h \end{bmatrix}' title='\mathbf{q} = \begin{bmatrix}w \\ h \end{bmatrix}' class='latex' />
<img src='http://s.wordpress.com/latex.php?latex=%5Cmathbf%7Br%7D%20%3D%20%5Cbegin%7Bbmatrix%7Dw%20%5C%5C%200%20%5Cend%7Bbmatrix%7D&#038;bg=T&#038;fg=000000&#038;s=0' alt='\mathbf{r} = \begin{bmatrix}w \\ 0 \end{bmatrix}' title='\mathbf{r} = \begin{bmatrix}w \\ 0 \end{bmatrix}' class='latex' />
<p>(We&#8217;re still in screen coordinates, so positive y points down).</p>
<p>Now let&#8217;s look at the same rectangle, under some transformation <strong>T</strong>. Since we&#8217;re still in step (4), <strong>T</strong> is just a linear transformation (and so is represented by a 2&#215;2 matrix). Here is an image of the rectangle under one possible <strong>T</strong></p>
<p><img class="aligncenter size-full wp-image-1359" title="Transformed rect" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/03/trans_rect1.png" alt="" width="446" height="336" /></p>
<p>In general, if</p>
<img src='http://s.wordpress.com/latex.php?latex=%5Cmathbf%7BT%7D%3D%5Cbegin%7Bbmatrix%7Da%20%26%20c%20%5C%5C%20b%20%26%20d%20%5Cend%7Bbmatrix%7D&#038;bg=T&#038;fg=000000&#038;s=0' alt='\mathbf{T}=\begin{bmatrix}a &amp; c \\ b &amp; d \end{bmatrix}' title='\mathbf{T}=\begin{bmatrix}a &amp; c \\ b &amp; d \end{bmatrix}' class='latex' />
<p>then the coordinates of the transformed corners are</p>
<img src='http://s.wordpress.com/latex.php?latex=%5Cmathbf%7Bp%7D%27%3D%5Cmathbf%7BT%7D%5Cmathbf%7Bp%7D%3D%5Cbegin%7Bbmatrix%7Da%20%26%20c%20%5C%5C%20b%20%26%20d%20%5Cend%7Bbmatrix%7D%5Cbegin%7Bbmatrix%7D0%20%5C%5C%20h%20%5Cend%7Bbmatrix%7D%3D%20%5Cbegin%7Bbmatrix%7Dch%20%5C%5C%20dh%20%5Cend%7Bbmatrix%7D&#038;bg=T&#038;fg=000000&#038;s=0' alt='\mathbf{p}&#039;=\mathbf{T}\mathbf{p}=\begin{bmatrix}a &amp; c \\ b &amp; d \end{bmatrix}\begin{bmatrix}0 \\ h \end{bmatrix}= \begin{bmatrix}ch \\ dh \end{bmatrix}' title='\mathbf{p}&#039;=\mathbf{T}\mathbf{p}=\begin{bmatrix}a &amp; c \\ b &amp; d \end{bmatrix}\begin{bmatrix}0 \\ h \end{bmatrix}= \begin{bmatrix}ch \\ dh \end{bmatrix}' class='latex' />
<img src='http://s.wordpress.com/latex.php?latex=%5Cmathbf%7Bq%7D%27%3D%5Cmathbf%7BT%7D%5Cmathbf%7Bq%7D%3D%5Cbegin%7Bbmatrix%7Da%20%26%20c%20%5C%5C%20b%20%26%20d%20%5Cend%7Bbmatrix%7D%20%5Cbegin%7Bbmatrix%7Dw%20%5C%5C%20h%20%5Cend%7Bbmatrix%7D%3D%5Cbegin%7Bbmatrix%7D%20aw%20%2B%20ch%20%5C%5C%20bw%20%2B%20dh%20%5Cend%7Bbmatrix%7D&#038;bg=T&#038;fg=000000&#038;s=0' alt='\mathbf{q}&#039;=\mathbf{T}\mathbf{q}=\begin{bmatrix}a &amp; c \\ b &amp; d \end{bmatrix} \begin{bmatrix}w \\ h \end{bmatrix}=\begin{bmatrix} aw + ch \\ bw + dh \end{bmatrix}' title='\mathbf{q}&#039;=\mathbf{T}\mathbf{q}=\begin{bmatrix}a &amp; c \\ b &amp; d \end{bmatrix} \begin{bmatrix}w \\ h \end{bmatrix}=\begin{bmatrix} aw + ch \\ bw + dh \end{bmatrix}' class='latex' />
<img src='http://s.wordpress.com/latex.php?latex=%5Cmathbf%7Br%7D%27%3D%5Cmathbf%7BT%7D%5Cmathbf%7Br%7D%3D%5Cbegin%7Bbmatrix%7Da%20%26%20c%20%5C%5C%20b%20%26%20d%20%5Cend%7Bbmatrix%7D%20%5Cbegin%7Bbmatrix%7Dw%20%5C%5C%200%20%5Cend%7Bbmatrix%7D%3D%20%5Cbegin%7Bbmatrix%7Daw%20%5C%5C%20bw%20%5Cend%7Bbmatrix%7D&#038;bg=T&#038;fg=000000&#038;s=0' alt='\mathbf{r}&#039;=\mathbf{T}\mathbf{r}=\begin{bmatrix}a &amp; c \\ b &amp; d \end{bmatrix} \begin{bmatrix}w \\ 0 \end{bmatrix}= \begin{bmatrix}aw \\ bw \end{bmatrix}' title='\mathbf{r}&#039;=\mathbf{T}\mathbf{r}=\begin{bmatrix}a &amp; c \\ b &amp; d \end{bmatrix} \begin{bmatrix}w \\ 0 \end{bmatrix}= \begin{bmatrix}aw \\ bw \end{bmatrix}' class='latex' />
<p>For the example transformed rectangle, now with a projected bounding box:</p>
<p><img class="aligncenter size-full wp-image-1360" title="Transformed rect with bounding box" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/03/trans_bb21.png" alt="" width="446" height="336" /></p>
<p style="text-align: center;">
<p>it should be clear that in this case the width of the bounding box is</p>
<img src='http://s.wordpress.com/latex.php?latex=w_b%3Dr_x%27-p_x%27&#038;bg=T&#038;fg=000000&#038;s=0' alt='w_b=r_x&#039;-p_x&#039;' title='w_b=r_x&#039;-p_x&#039;' class='latex' />
<p>By substitution,</p>
<img src='http://s.wordpress.com/latex.php?latex=w_b%3Daw-ch&#038;bg=T&#038;fg=000000&#038;s=0' alt='w_b=aw-ch' title='w_b=aw-ch' class='latex' />
<p>Incidentally, because <em>ch</em> is negative (see image), this is equivalent to</p>
<img src='http://s.wordpress.com/latex.php?latex=w_b%3Daw%2B%7Cch%7C&#038;bg=T&#038;fg=000000&#038;s=0' alt='w_b=aw+|ch|' title='w_b=aw+|ch|' class='latex' />
<p>(hint, wink, nudge, etc).</p>
<p>The height of this bounding box is</p>
<img src='http://s.wordpress.com/latex.php?latex=h_b%3Dq_y%27-0%3Dbw%2Bdh&#038;bg=T&#038;fg=000000&#038;s=0' alt='h_b=q_y&#039;-0=bw+dh' title='h_b=q_y&#039;-0=bw+dh' class='latex' />
<p>We need to determine the difference between the greatest and the least of the x-coordinates and the y-coordinates, for <em>all</em> transformations. Rather than trying to enumerate all the possible geometric situations, it&#8217;s easier to consider sign combinations. Beginning with the x-coordinates, we have four values: 0, <em>ch</em>, <em>aw</em>, and (<em>aw</em> + <em>ch</em>). <em>a</em> and <em>c</em> can be any real number, while <em>w</em> and <em>h</em> will always be non-negative.</p>
<ul>
<li>Case 1: <em>aw</em> and <em>ch</em> are positive. 0 is clearly the minimum x-value and (<em>aw</em> + <em>ch</em>) is both the maximum and the width of the bounding box.</li>
<li>Case 2: <em>aw</em> and <em>ch</em> are negative. 0 is now the maximum and (<em>aw</em> + <em>ch</em>) the minimum, but the bounding box&#8217;s width—the distance from the maximum to the minimum x-value—is still |(<em>aw</em> + <em>ch</em>)|.</li>
<li>Case 3: <em>aw</em> and <em>ch</em> have opposite signs. 0 cannot be a max or a min, as it is bounded by these values. Likewise, (<em>aw</em> + <em>ch</em>) will also be bounded by the two. It does not matter which value is positive and which negative, since the subtraction of the negative value will yield the addition of its magnitude; the width is (|<em>aw</em>| + |<em>ch</em>|) either way.</li>
<li>Finally, careful consideration of the cases where <em>aw</em> or <em>ch</em> is equal to 0 (<em>always</em> be careful with your 0s) will find that their outcomes fall under the results listed above.</li>
</ul>
<p>Since <em>w</em> and <em>h</em> are always non-negative, we only have to worry about the signs of the entries in <strong>T</strong>. While half the time it is a waste of an <code>abs()</code> call, it is <em>always</em> safe to say that</p>
<img src='http://s.wordpress.com/latex.php?latex=w_b%3D%7Ca%7Cw%2B%7Cc%7Ch&#038;bg=T&#038;fg=000000&#038;s=0' alt='w_b=|a|w+|c|h' title='w_b=|a|w+|c|h' class='latex' />
<p>Therefore, if <em>s<sub>x</sub></em> is the horizontal distance between the ideal origin and IE&#8217;s shifted origin, then, using our <a href="http://extremelysatisfactorytotalitarianism.com/blog/?p=1002#determineShift">shift equation</a> and substituting the new <em>w<sub>b</sub></em></p>
<img src='http://s.wordpress.com/latex.php?latex=s_x%3D%5Cfrac%7B1%7D%7B2%7D%28w_b-w%29%3D%5Cfrac%7B1%7D%7B2%7D%28%7Ca%7Cw%2B%7Cc%7Ch-w%29&#038;bg=T&#038;fg=000000&#038;s=0' alt='s_x=\frac{1}{2}(w_b-w)=\frac{1}{2}(|a|w+|c|h-w)' title='s_x=\frac{1}{2}(w_b-w)=\frac{1}{2}(|a|w+|c|h-w)' class='latex' />
<img src='http://s.wordpress.com/latex.php?latex=s_x%3D%28%7Ca%7C-1%29%5Cfrac%7Bw%7D%7B2%7D%20%2B%7Cc%7C%5Cfrac%7Bh%7D%7B2%7D&#038;bg=T&#038;fg=000000&#038;s=0' alt='s_x=(|a|-1)\frac{w}{2} +|c|\frac{h}{2}' title='s_x=(|a|-1)\frac{w}{2} +|c|\frac{h}{2}' class='latex' />
<p>Similarly,</p>
<img src='http://s.wordpress.com/latex.php?latex=s_y%3D%7Cb%7C%5Cfrac%7Bw%7D%7B2%7D%20%2B%20%28%7Cd%7C-1%29%5Cfrac%7Bh%7D%7B2%7D&#038;bg=T&#038;fg=000000&#038;s=0' alt='s_y=|b|\frac{w}{2} + (|d|-1)\frac{h}{2}' title='s_y=|b|\frac{w}{2} + (|d|-1)\frac{h}{2}' class='latex' />
<h3 id="theCode">All Together Now</h3>
<p>You have a 2d affine transformation, represented by an augmented matrix of the form</p>
<img src='http://s.wordpress.com/latex.php?latex=%5Cmathbf%7BT%7D%3D%5Cbegin%7Bbmatrix%7Da%20%26%20c%20%26%20e%5C%5C%20b%20%26%20d%20%26%20f%20%5Cend%7Bbmatrix%7D&#038;bg=T&#038;fg=000000&#038;s=0' alt='\mathbf{T}=\begin{bmatrix}a &amp; c &amp; e\\ b &amp; d &amp; f \end{bmatrix}' title='\mathbf{T}=\begin{bmatrix}a &amp; c &amp; e\\ b &amp; d &amp; f \end{bmatrix}' class='latex' />
<p>To transform an element by this matrix in some future, standards-compliant browser, the following is sufficient:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">target.<span style="color: #660066;">style</span>.<span style="color: #660066;">transform</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;matrix(a, b, c, d, e, f)&quot;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Today, just substitute the vendor-extended version for &#8220;transform,&#8221; and add &lt;length&gt; units to e and f for Firefox (which doesn&#8217;t really make any sense, but for now: fine).</p>
<p>To do the same in Internet Explorer, here is our assembled JavaScript routine. In spite of some minor math optimizations, it does end up being fairly straightforward. Feel free to substitute your favorite IE string concatenation method.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// set linear transformation via Matrix Filter</span>
<span style="color: #003366; font-weight: bold;">var</span> filt <span style="color: #339933;">=</span> <span style="color: #3366CC;">'progid:DXImageTransform.Microsoft.Matrix('</span><span style="color: #339933;">;</span>
filt <span style="color: #339933;">+=</span>   <span style="color: #3366CC;">'M11='</span> <span style="color: #339933;">+</span> a<span style="color: #339933;">;</span>
filt <span style="color: #339933;">+=</span> <span style="color: #3366CC;">', M21='</span> <span style="color: #339933;">+</span> b<span style="color: #339933;">;</span>
filt <span style="color: #339933;">+=</span> <span style="color: #3366CC;">', M12='</span> <span style="color: #339933;">+</span> c<span style="color: #339933;">;</span>
filt <span style="color: #339933;">+=</span> <span style="color: #3366CC;">', M22='</span> <span style="color: #339933;">+</span> d<span style="color: #339933;">;</span>
filt <span style="color: #339933;">+=</span> <span style="color: #3366CC;">', SizingMethod=&quot;auto expand&quot;)'</span><span style="color: #339933;">;</span>
target.<span style="color: #660066;">style</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'filter'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> filt<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// assuming a-d are local variables</span>
<span style="color: #006600; font-style: italic;">// and halfW and halfH are initialized properly</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// horizontal shift</span>
a <span style="color: #339933;">=</span> Math.<span style="color: #660066;">abs</span><span style="color: #009900;">&#40;</span>a<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// or go ternary</span>
c <span style="color: #339933;">=</span> Math.<span style="color: #660066;">abs</span><span style="color: #009900;">&#40;</span>c<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> sx <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>a <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">*</span>halfW <span style="color: #339933;">+</span> c<span style="color: #339933;">*</span>halfH<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// vertical shift</span>
b <span style="color: #339933;">=</span> Math.<span style="color: #660066;">abs</span><span style="color: #009900;">&#40;</span>b<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
d <span style="color: #339933;">=</span> Math.<span style="color: #660066;">abs</span><span style="color: #009900;">&#40;</span>d<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> sy <span style="color: #339933;">=</span> b<span style="color: #339933;">*</span>halfW <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>d <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">*</span>halfH<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// translation, corrected for origin shift</span>
<span style="color: #006600; font-style: italic;">// rounding helps--but doesn't eliminate--integer jittering</span>
target.<span style="color: #660066;">style</span>.<span style="color: #660066;">left</span> <span style="color: #339933;">=</span> Math.<span style="color: #660066;">round</span><span style="color: #009900;">&#40;</span>x <span style="color: #339933;">+</span> e <span style="color: #339933;">-</span> sx<span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'px'</span><span style="color: #339933;">;</span>
target.<span style="color: #660066;">style</span>.<span style="color: #660066;">top</span> <span style="color: #339933;">=</span> Math.<span style="color: #660066;">round</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">+</span> f <span style="color: #339933;">-</span> sy<span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'px'</span><span style="color: #339933;">;</span></pre></div></div>

<p><a href="http://extremelysatisfactorytotalitarianism.com/projects/misc/2010/02/ie8_live/rotate_math_correction.html"><img class="aligncenter size-full wp-image-1354" title="IE calculated rotation" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/03/ie_calc_rot.png" alt="" width="248" height="231" /></a></p>
<ul>
<li><a title="IE8: rotation with calculated correction" href="http://extremelysatisfactorytotalitarianism.com/projects/misc/2010/02/ie8_live/rotate_math_correction.html">View example: fast corrected rotation</a> (via calculation)</li>
</ul>
<p>The shift correction is not exactly self-documenting code, but it is kind of pretty. The dimensions of the bounding box are computed—not queried—from the current linear transformation and used to correct the position of the element&#8217;s origin. <code>commitTransform()</code> now treats the DOM as write-only.</p>
<p>From some empirical testing, I&#8217;ve found that for a pure rotation this method will vary from the slow version by no more than a pixel in each dimension, and usually by much less. This error seems to grow at a quarter of the scale factor: for example, an element scaled by a factor of 20 will be at most 5 pixels off from where the slow method would place it. Based on the performance improvement, outlined below, I find this to be an acceptable trade-off (and without further testing, I&#8217;m not sure I would conclusively say that the slow method is more correct, anyway).</p>
<p>And there you have it; a mostly foolproof, efficient transformation method for Internet Explorer. If you can express your desired 2d affine transform in terms of a 2&#215;3 matrix, and it&#8217;s not hard to do so, this code will take care of the rest.</p>
<h3>The GWT Code</h3>
<p>I originally wasn&#8217;t going to include this—everything one needs to implement IE support is found above—but I think it&#8217;s interesting to see what the GWT compiler does with the code. This snippet comes straight from the IE permutation of my test program, but has been complied using the &#8220;PRETTY&#8221; compiler option so it is somewhat comprehensible. I&#8217;ve inserted some extra comments for additional explanation.</p>
<p>Keep in mind that, even though this is the less-minified &#8220;pretty&#8221; output, it is meant to be an end-product and not an intermediate one. As such, syntax <a title="Code Conventions for the JavaScript Programming Language" href="http://javascript.crockford.com/code.html">normally considered to be unfriendly</a> (like the comma operator) is fine in this context.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// this$static is object scope</span>
<span style="color: #003366; font-weight: bold;">function</span> $commitTransform<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>$static<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> finalTransform<span style="color: #339933;">,</span> m11<span style="color: #339933;">,</span> m12<span style="color: #339933;">,</span> m21<span style="color: #339933;">,</span> m22<span style="color: #339933;">,</span> tarStyle<span style="color: #339933;">,</span> xAdj<span style="color: #339933;">,</span> yAdj<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// init dimensions if this is the first time transforming element</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000066; font-weight: bold;">this</span>$static.<span style="color: #660066;">elementInitialized</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>$isOrHasChild<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>$clinit_22<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">,</span> $doc.<span style="color: #660066;">body</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>$static.<span style="color: #660066;">target</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    $initElementLayout<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>$static<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// only hint that compiler removed unused origin-changing code</span>
finalTransform <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>$static.<span style="color: #660066;">transform</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// horizontal shift (using 'a' and 'c')</span>
m11 <span style="color: #339933;">=</span> finalTransform.<span style="color: #660066;">m11</span><span style="color: #339933;">;</span>
m11 <span style="color: #339933;">=</span> m11 <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">?-</span>m11<span style="color: #339933;">:</span>m11<span style="color: #339933;">;</span>
m12 <span style="color: #339933;">=</span> finalTransform.<span style="color: #660066;">m12</span><span style="color: #339933;">;</span>
m12 <span style="color: #339933;">=</span> m12 <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">?-</span>m12<span style="color: #339933;">:</span>m12<span style="color: #339933;">;</span>
xAdj <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span> <span style="color: #339933;">-</span> m11<span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> <span style="color: #000066; font-weight: bold;">this</span>$static.<span style="color: #660066;">halfOrigWidth</span> <span style="color: #339933;">-</span> m12 <span style="color: #339933;">*</span> <span style="color: #000066; font-weight: bold;">this</span>$static.<span style="color: #660066;">halfOrigHeight</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// vertical shift (using 'b' and 'd')</span>
m21 <span style="color: #339933;">=</span> finalTransform.<span style="color: #660066;">m21</span><span style="color: #339933;">;</span>
m21 <span style="color: #339933;">=</span> m21 <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">?-</span>m21<span style="color: #339933;">:</span>m21<span style="color: #339933;">;</span>
m22 <span style="color: #339933;">=</span> finalTransform.<span style="color: #660066;">m22</span><span style="color: #339933;">;</span>
m22 <span style="color: #339933;">=</span> m22 <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">?-</span>m22<span style="color: #339933;">:</span>m22<span style="color: #339933;">;</span>
yAdj <span style="color: #339933;">=</span> <span style="color: #339933;">-</span>m21 <span style="color: #339933;">*</span> <span style="color: #000066; font-weight: bold;">this</span>$static.<span style="color: #660066;">halfOrigWidth</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span> <span style="color: #339933;">-</span> m22<span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> <span style="color: #000066; font-weight: bold;">this</span>$static.<span style="color: #660066;">halfOrigHeight</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// translation from matrix ('e' and 'f')</span>
xAdj <span style="color: #339933;">+=</span> finalTransform.<span style="color: #660066;">m13</span><span style="color: #339933;">;</span>
yAdj <span style="color: #339933;">+=</span> finalTransform.<span style="color: #660066;">m23</span><span style="color: #339933;">;</span>
&nbsp;
tarStyle <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>$static.<span style="color: #660066;">target</span>.<span style="color: #660066;">style</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// I use Array.join, but doesn't make a huge difference</span>
tarStyle<span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'filter'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>filterArray<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> finalTransform.<span style="color: #660066;">m11</span> <span style="color: #339933;">,</span> filterArray<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> finalTransform.<span style="color: #660066;">m12</span> <span style="color: #339933;">,</span> filterArray<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">5</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> finalTransform.<span style="color: #660066;">m21</span> <span style="color: #339933;">,</span> filterArray<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">7</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> finalTransform.<span style="color: #660066;">m22</span> <span style="color: #339933;">,</span> filterArray.<span style="color: #660066;">join</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
tarStyle<span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'left'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>$static.<span style="color: #660066;">originalLeft</span> <span style="color: #339933;">+</span> xAdj <span style="color: #339933;">+</span> <span style="color: #3366CC;">'px'</span><span style="color: #339933;">;</span>
tarStyle<span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'top'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>$static.<span style="color: #660066;">originalTop</span> <span style="color: #339933;">+</span> yAdj <span style="color: #339933;">+</span> <span style="color: #3366CC;">'px'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The GWT compiler doesn&#8217;t really have a chance to work its magic here; the java code was purposefully written to be straightforward, so the output is close to what was input. What&#8217;s interesting is actually what you don&#8217;t see. There&#8217;s barely a hint that the compiler was able to remove the code for handling setOrigin(), which is nicely inlined if it is used. There is also no trace of the completely different code that is used in Firefox, or Chrome, or Opera, etc.</p>
<p>Incidentally, this little gem takes care of everything found above in the Webkit permutation:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> $commitTransform<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>$static<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">this</span>$static.<span style="color: #660066;">target</span>.<span style="color: #660066;">style</span>.<span style="color: #660066;">WebkitTransform</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>$static.<span style="color: #660066;">transform</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>I&#8217;m trying to think of the appropriate cliche to sum up poor old IE&#8217;s situation—something about bailing water or running in place—but I just don&#8217;t have the heart.</p>
<h3>DOM is the animation-killer</h3>
<p>It can be difficult to get exact numbers for code that affects reflow and repainting. Beyond the usual &#8220;measuring JavaScript with JavaScript&#8221; problems, other style-changing code can have a huge impact on execution time, and the non-deterministic order in which they all may interleave can have disproportionate effects. As a result, I&#8217;ve tried to rely on numbers from my stress-test program, which in some ways resembles a real web application. The results come from the built-in IE8 profiler, so specific values shouldn&#8217;t be treated as absolute.</p>
<p>In addition to the changes already mentioned, I&#8217;ve made a few other efficiency improvements. I restructured the initialization of internal &#8220;scratch&#8221; matrices to avoid GWT&#8217;s clinit()s (Firefox shows a 75% reduction in null method calls). Combined with the switch to 3&#215;3 matrices, optimization of the bounding box routine, and other small changes, I managed to cut the execution time of the write-only version of <code>commitTransform()</code> by about 50%.</p>
<p>For all my bluster about numerical and algebraic improvements, though, this amounts to about a tenth of a millisecond, depending on how it&#8217;s measured. This is a big savings and the faster <code>commitTransform()</code> can yield sooner and let other code run more often. But it is nothing compared to the elimination of reading DOM attributes.</p>
<p>In the example files, averaged over 20,000 calls, the <a title="IE8: rotation with offset* correction" href="http://extremelysatisfactorytotalitarianism.com/projects/misc/2010/02/ie8_live/rotate_offset_correction.html">offsetWidth/Height transformation method</a> takes 2.5ms. On the other hand, the <a title="IE8: rotation with calculated correction" href="http://extremelysatisfactorytotalitarianism.com/projects/misc/2010/02/ie8_live/rotate_math_correction.html">final transformation method</a> claims to take 0.0ms, but my division finds an average of .03ms per call (though I could imagine an uncertainty approaching .1ms). But that&#8217;s just a toy example.</p>
<p>As I mentioned above, in an already intensive app, <code>commitTransform()</code> on 40 elements just 10 times per second was using around 40% of total execution time on a maxed-out processor. The new version drops this below 4%. To emphasize the point:</p>
<p><img class="aligncenter size-full wp-image-1368" title="method comparison graph" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/03/graph1.png" alt="" width="496" height="483" /></p>
<p>Keep in mind that &#8220;setting transform&#8221; isn&#8217;t calculating the transform, it isn&#8217;t changing it, it isn&#8217;t making a new one; it is only setting the transform style from an existing matrix. Note also that &#8220;everything else&#8221; is <em>everything</em> else, including the time the app spends responding to user input, which is its only reason for existing in the first place.</p>
<p>Now, transforming and positioning elements correctly is important, but I think the second bar better reflects the time that should be devoted to <em>just</em> setting the transform style on 40 elements.</p>
<p>Two take-aways:</p>
<ol>
<li>USE THE SECOND METHOD. Unless you&#8217;re certain that the original bounds of the elements have changed (and there are event listeners for that sort of thing), cache the bounds and calculate the bounding box.</li>
<li>If you aren&#8217;t paying attention to the way you access the DOM, your application <em>will</em> be slow. This is certainly <a title="Stubbornella - Reflows &amp;amp; Repaints: CSS Performance making your JavaScript slow?" href="http://www.stubbornella.org/content/2009/03/27/reflows-repaints-css-performance-making-your-javascript-slow/">nowhere</a> <a title="Let's make the web faster - Google Code" href="http://code.google.com/speed/articles/reflow.html">near</a> an <a title="Notes on HTML Reflow" href="http://www.mozilla.org/newlayout/doc/reflow.html">original</a> <a title="Steve Souders - High Performance Web Sites" href="http://stevesouders.com/">statement</a>, but it deserves to be repeated yet again. Firebug, SpeedTracer, and IE’s surprisingly handy profiler will help.</li>
</ol>
<p>Internet Explorer&#8217;s <code>commitTransform()</code> is now on par with Firefox&#8217;s (IE actually profiles quite a bit faster, but with way too many variables to control, I&#8217;ll stick with &#8220;on par&#8221;). Limiting agents are now elsewhere.</p>
<h3>Future Work</h3>
<p>Overall, it&#8217;s been interesting to get back into this code. As I wrote at the beginning, this module didn&#8217;t get the full attention it needed, so the code isn&#8217;t exactly a paragon of software design (or good code formatting). Part of the problem was that encapsulating transformations in a way that matches the behavior of CSS3 transforms—the forward-thinking approach—is made difficult by the particulars of the IE implementation.</p>
<p>For instance, I still think a transform shouldn&#8217;t be tied to a particular element; it is, after all, just a style (even if I tend to use transformed elements as logical entities). But to do transformations in IE quickly, the original size of an element can only be read and cached once, so a particular transform <em>is</em> bound to a particular element and the abstraction is lost. This can be worked around (and to an extent already is in the Transforms/TransformedElement split), but currently there is a conceptual gap between the exposed interface and what it gives access to. It&#8217;s fine, but it&#8217;s not elegant.</p>
<p>For now, however, the IE code is working well and speedily (according to the browser&#8217;s ability). In the months since I started this project, I&#8217;ve developed a better sense for the GWT UI idioms (and some thoughts on integrating with UiBinder), so a rewrite is definitely overdue. However, writing this post gave me an idea for yet another way one might abuse the transform system, so I&#8217;ll probably put off any redesign until I have a better idea of all use cases. For the time being, feel free to check out and use the current module and provide any feedback on how it could better suit your needs.</p>
<p>All the source code is here: <a title="gwt-ns - Project Hosting on Google Code" href="https://code.google.com/p/gwt-ns/">gwt-ns project page</a>.</p>
<h3>Examples, Again</h3>
<p style="padding-left: 30px;"><a title="IE8: naive rotation" href="http://extremelysatisfactorytotalitarianism.com/projects/misc/2010/02/ie8_live/rotate.html">First: Pure Rotation</a><br />
<a title="IE8: rotation with offset* correction" href="http://extremelysatisfactorytotalitarianism.com/projects/misc/2010/02/ie8_live/rotate_offset_correction.html">Slow: Fixed Rotation</a><br />
<a title="IE8: rotation with calculated correction" href="http://extremelysatisfactorytotalitarianism.com/projects/misc/2010/02/ie8_live/rotate_math_correction.html">Fast: Final Rotation</a></p>
]]></content:encoded>
			<wfw:commentRss>http://extremelysatisfactorytotalitarianism.com/blog/?feed=rss2&amp;p=922</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>On the Behavior of 2d Transformations in Internet Explorer</title>
		<link>http://extremelysatisfactorytotalitarianism.com/blog/?p=1002</link>
		<comments>http://extremelysatisfactorytotalitarianism.com/blog/?p=1002#comments</comments>
		<pubDate>Sat, 27 Feb 2010 22:24:16 +0000</pubDate>
		<dc:creator>Brendan Kenny</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[ie]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mathematics]]></category>
		<category><![CDATA[ns]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[transforms]]></category>

		<guid isPermaLink="false">http://extremelysatisfactorytotalitarianism.com/blog/?p=1002</guid>
		<description><![CDATA[In my work on the box2d and web worker modules in gwtns, I&#8217;ve needed the ability to put things up on the screen. To really make sure I was doing the word &#8220;overkill&#8221; justice, I decided to use my old &#8230; <a href="http://extremelysatisfactorytotalitarianism.com/blog/?p=1002">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><img class="aligncenter size-full wp-image-1385" title="IE origin shift" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/02/ie_shift_vector.png" alt="" width="396" height="378" /></p>
<p>In my work on the box2d and web worker modules in gwtns, I&#8217;ve needed the ability to put things up on the screen. To really make sure I was doing the word &#8220;overkill&#8221; justice, I decided to use my old TransformedElement module for that purpose. This has given me the opportunity to go back and ruminate over my original implementation.</p>
<p>Though it was only a few months ago, I originally took it on as more of a way to get to know the GWT deferred binding system than to write the perfect transformation library, and I wrote it in definite haste. I would probably not structure it the same way a second time. It&#8217;s not bad, but the differences between the underlying IE and CSS3 implementations are enough to make the unifying API a little less straightforward than it should be.</p>
<p>What was terrible, though, was the speed of the Internet Explorer version. The trial and error process to get IE&#8217;s matrix filter fully operational was annoying enough that I didn&#8217;t spend much longer on it than I had to. It helped that I only needed to position elements, not animate them, but that&#8217;s no longer true. As a result, I took a day last week to profile and revamp the IE implementation. The performance is actually now on par with the Firefox version, since the majority of execution time is taken up by DOM access.</p>
<p>But I&#8217;ll write more about the changes I made in my next post. For now, I really want to address how to get Internet Explorer transforming elements in almost the exact same way as all the &#8220;modern&#8221; browsers that support the <a title="CSS 2D Transforms Module Level 3" href="http://www.w3.org/TR/css3-2d-transforms/">CSS 2D Transforms (draft) specification</a>. I&#8217;ve been surprised at the lack of support for IE as plugins and tools have started popping up to let authors easily transform elements. In fact, <a title="MooTools Forge | Element.Style.Transform" href="http://mootools.net/forge/p/element_style_transform">many</a> <a title="jQuery Patch: Animate CSS Rotation and Scale - zachstronaut" href="http://www.zachstronaut.com/posts/2009/08/07/jquery-animate-css-rotate-scale.html">explicitly</a> <a title="Jon Combe | Code | HTML clocks using JavaScript and CSS rotation" href="http://joncom.be/code/css-clocks/">state</a> that IE support seems possible, but it hasn&#8217;t been implemented yet due to the pain of figuring out the different format.</p>
<p>But there&#8217;s no reason to repeat ourselves as a community. Supporting IE is actually pretty straightforward, you just have to be a little tricky to get around a few problems. With this done—if you&#8217;re willing to forsake Firefox users prior to 3.5 and Opera users prior to 10.5—essentially every browser in use is capable of applying geometric transformations to HTML elements. In writing this, I&#8217;m hoping that I can at least set a baseline of understanding of how transformations work in IE. That way, those that don&#8217;t want to figure it out from scratch won&#8217;t need to, and those that do will be able to concentrate on creating tools more elegant and sophisticated than I have here.<span id="more-1002"></span></p>
<h3 id="caveats">A few caveats</h3>
<ul>
<li>Unless otherwise stated, this post will be strictly about two dimensional transformations. So when I talk about &#8220;affine transformations&#8221; or &#8220;translations,&#8221; just read &#8220;2d affine transformations&#8221; or &#8220;2d translations.&#8221;</li>
<li>I&#8217;m going to assume some familiarity with basic linear algebra and transforms. I&#8217;m hoping, though, that I can provide enough context so that the proper Wikipedia or MathWorld search will be clear even for unfamiliar concepts. Please let me know if and where I confuse or gloss over an important detail.</li>
<li>This will only cover support for the equivalent of the <a title="The Transformation Functions" href="http://www.w3.org/TR/css3-2d-transforms/#transform-functions">matrix transformation function</a>. i.e. <code>transform: matrix(a, b, c, d, e, f);</code> rather than the list of transformation functions: <code>transform: rotate(&lt;angle&gt;) scale(&lt;number&gt;) ...;</code>. I&#8217;m primarily interested in transforms through scripting—so I concatenate transformations into an internal matrix representation—but it&#8217;s trivial to find the matrix form of any list of transformations. This has <a title="Matrix decomposition for animation" href="http://www.w3.org/TR/css3-2d-transforms/#matrix-decomposition">implications</a> for animation, but that will have to fall outside the scope of this post.</li>
<li>All listed code was tested only in Internet Explorer 8. The Matrix Filter was added in IE5.5, but the accessor syntax was <a title="The CSS Corner: Using Filters In IE8" href="http://blogs.msdn.com/ie/archive/2009/02/19/the-css-corner-using-filters-in-ie8.aspx">slightly changed</a> in the latest version to better comply with the standard way of extending CSS. The syntax changes should be trivial, but layout changes are probably not. If you work it out, please let me know so I can put up a link.</li>
<li>Finally, if all of this isn&#8217;t your cup of tea, I&#8217;ll have the final code posted next. Don&#8217;t worry; it&#8217;ll be JavaScript.</li>
</ul>
<h3>UA Background</h3>
<p>The type of transform we&#8217;re interested in is called an affine transform, which describes most of the ways one would want to move or change an object: scaling it, rotating it, shearing it, translating it, etc. There used to be no standard way to transform DOM elements, but a few years ago Apple started pushing for their format (which started life on the iPhone) to be adopted. From there, it spread to the desktop version of Safari and then eventually to Firefox, Chrome, and Opera. It&#8217;s now close to being finalized.</p>
<p>But it turns out that Internet Explorer has been well ahead of the pack for years, supporting the transformation of elements through its <a title="Matrix Filter" href="http://msdn.microsoft.com/en-us/library/ms533014(VS.85).aspx">CSS &#8220;filter&#8221; extension</a> since at least 2000. A quick Google search will actually find mention of it all over the place in old <a title="DHTML Central" href="http://www.dhtmlcentral.com/tutorials/tutorials_p3_4.php">DHTML tutorials</a>, but I can&#8217;t think of any time I&#8217;ve seen it in the wild. Like the existence of Flashblock, the fact that spinning webpages aren&#8217;t more widespread is probably evidence of divine providence and existing barriers shouldn&#8217;t be trifled with. But in the end, I prefer tools that will cheerfully help you shoot yourself in the foot (or your users in the eyes). We&#8217;re just going to have to rely on collective good taste.</p>
<p>A still forthcoming blog post better compares the <em>results </em>of IE&#8217;s matrix transform filter to the results of current CSS3 implementations, but, in theory, they are close to identical in what they support.</p>
<h3>Math Digression: Linear Transformations</h3>
<p>An affine transformation is actually a combination of a linear transformation and a translation. In our case, the linear transformation takes linear combinations of a point&#8217;s x and y coordinates to map them to new coordinates. In other words, for point <strong>x</strong></p>
<img src='http://s.wordpress.com/latex.php?latex=%5Cmathbf%7Bx%7D%20%3D%20%5Cbegin%7Bbmatrix%7Dx%20%5C%5C%20y%20%5Cend%7Bbmatrix%7D&#038;bg=T&#038;fg=000000&#038;s=0' alt='\mathbf{x} = \begin{bmatrix}x \\ y \end{bmatrix}' title='\mathbf{x} = \begin{bmatrix}x \\ y \end{bmatrix}' class='latex' />
<p>linear transformation <strong>T</strong> produces the new point</p>
<img src='http://s.wordpress.com/latex.php?latex=%5Cmathbf%7BT%7D%28%5Cmathbf%7Bx%7D%29%3D%5Cbegin%7Bbmatrix%7Dax%20%2B%20cy%20%5C%5C%20bx%20%2B%20dy%20%5Cend%7Bbmatrix%7D&#038;bg=T&#038;fg=000000&#038;s=0' alt='\mathbf{T}(\mathbf{x})=\begin{bmatrix}ax + cy \\ bx + dy \end{bmatrix}' title='\mathbf{T}(\mathbf{x})=\begin{bmatrix}ax + cy \\ bx + dy \end{bmatrix}' class='latex' />
<p>or, in matrix form:</p>
<img src='http://s.wordpress.com/latex.php?latex=%5Cmathbf%7BT%7D%28%5Cmathbf%7Bx%7D%29%3D%5Cbegin%7Bbmatrix%7Da%20%26%20c%20%5C%5C%20b%20%26%20d%20%5Cend%7Bbmatrix%7D%5Cbegin%7Bbmatrix%7Dx%20%5C%5C%20y%20%5Cend%7Bbmatrix%7D%20%3D%20%5Cbegin%7Bbmatrix%7Dax%20%2B%20cy%20%5C%5C%20bx%20%2B%20dy%20%5Cend%7Bbmatrix%7D&#038;bg=T&#038;fg=000000&#038;s=0' alt='\mathbf{T}(\mathbf{x})=\begin{bmatrix}a &amp; c \\ b &amp; d \end{bmatrix}\begin{bmatrix}x \\ y \end{bmatrix} = \begin{bmatrix}ax + cy \\ bx + dy \end{bmatrix}' title='\mathbf{T}(\mathbf{x})=\begin{bmatrix}a &amp; c \\ b &amp; d \end{bmatrix}\begin{bmatrix}x \\ y \end{bmatrix} = \begin{bmatrix}ax + cy \\ bx + dy \end{bmatrix}' class='latex' />
<p>By using specific values for the entries of the transformation matrix, here represented as <em>a</em> through <em>d</em>, a single linear transform can express a rotation, a scale, a shear, or even an ordered sequence of these operations combined. It can be very illuminating to work out what these specific matrices are for yourself, but as a simple example, an expansion by a factor of two would be represented like this</p>
<img src='http://s.wordpress.com/latex.php?latex=%5Cmathbf%7BS%7D_2%28%5Cmathbf%7Bx%7D%29%3D%5Cbegin%7Bbmatrix%7D2%20%26%200%20%5C%5C%200%20%26%202%20%5Cend%7Bbmatrix%7D%5Cbegin%7Bbmatrix%7Dx%20%5C%5C%20y%20%5Cend%7Bbmatrix%7D%20%3D%20%5Cbegin%7Bbmatrix%7D2x%20%2B%200y%20%5C%5C%200x%20%2B%202y%20%5Cend%7Bbmatrix%7D%20%3D%20%5Cbegin%7Bbmatrix%7D2x%20%5C%5C%202y%20%5Cend%7Bbmatrix%7D&#038;bg=T&#038;fg=000000&#038;s=0' alt='\mathbf{S}_2(\mathbf{x})=\begin{bmatrix}2 &amp; 0 \\ 0 &amp; 2 \end{bmatrix}\begin{bmatrix}x \\ y \end{bmatrix} = \begin{bmatrix}2x + 0y \\ 0x + 2y \end{bmatrix} = \begin{bmatrix}2x \\ 2y \end{bmatrix}' title='\mathbf{S}_2(\mathbf{x})=\begin{bmatrix}2 &amp; 0 \\ 0 &amp; 2 \end{bmatrix}\begin{bmatrix}x \\ y \end{bmatrix} = \begin{bmatrix}2x + 0y \\ 0x + 2y \end{bmatrix} = \begin{bmatrix}2x \\ 2y \end{bmatrix}' class='latex' />
<p>This transformation would map every point to a new point at twice the distance from the origin, except the origin itself.</p>
<p>In fact, <em>no</em> linear transformation can move the origin. Rotations provide another easy example: no matter how many times a wheel is rotated, there is no rotation that will change the center of the wheel; that point is fixed. If we want to be more precise:</p>
<img src='http://s.wordpress.com/latex.php?latex=%5Cmathbf%7BT%7D%28%5Cmathbf%7B0%7D%29%3D%5Cmathbf%7BT%7D%28%5Cbegin%7Bbmatrix%7D0%20%5C%5C%200%20%5Cend%7Bbmatrix%7D%29%3D%5Cbegin%7Bbmatrix%7Da0%20%2B%20c0%20%5C%5C%20b0%20%2B%20d0%20%5Cend%7Bbmatrix%7D%3D%5Cbegin%7Bbmatrix%7D0%20%5C%5C%200%20%5Cend%7Bbmatrix%7D%3D%5Cmathbf%7B0%7D&#038;bg=T&#038;fg=000000&#038;s=0' alt='\mathbf{T}(\mathbf{0})=\mathbf{T}(\begin{bmatrix}0 \\ 0 \end{bmatrix})=\begin{bmatrix}a0 + c0 \\ b0 + d0 \end{bmatrix}=\begin{bmatrix}0 \\ 0 \end{bmatrix}=\mathbf{0}' title='\mathbf{T}(\mathbf{0})=\mathbf{T}(\begin{bmatrix}0 \\ 0 \end{bmatrix})=\begin{bmatrix}a0 + c0 \\ b0 + d0 \end{bmatrix}=\begin{bmatrix}0 \\ 0 \end{bmatrix}=\mathbf{0}' class='latex' />
<p>At the origin, the values of <em>a</em>, <em>b</em>, <em>c</em>, and <em>d</em> are irrelevant; a linear transformation always maps the origin to itself.</p>
<h3 id="translations">Further Math Digression: Translations</h3>
<p>Translations are what allow objects to move around without distortion. There are a few different ways to think of a translation, but the end effect is that <em>all</em> points (including the origin) are shifted in the same direction by the same amount. As noted, there is no way to do this with a simple linear transformation matrix because (among other things) there is no way for it to move the origin.</p>
<p><span id="whyMatrix">We&#8217;d</span> really like to express the full affine transform as a matrix, though. Why would this be desirable? For our purposes, the main benefit is transform concatenation. Since matrix multiplication is associative, a chain of transformations applied consecutively to an object is equivalent to the application of the single product of each transformation&#8217;s matrix. Instead of an unbounded list of transformations, each requiring yet more operations to find an end result, each transformation can be multiplied into an intermediate matrix, requiring no more storage than the entries in that matrix.</p>
<p>If we can represent a linear transformation and a translation in a single matrix, more sophisticated behavior also becomes possible. For example, objects would be able to rotate about any specific point rather than always rotating about the origin. Our job also becomes easier; rather than dealing with a bunch of bookkeeping to keep two separate data structures geometrically synchronized, we keep only one structure (a matrix) and one very simple operation (multiplication). The problem remains, though, that matrices can <em>only</em> represent linear transformations, and a translation is not a linear transformation.</p>
<p>We cheat this by augmenting the matrix used so that we are now applying a linear transformation to a 2d plane in a 3d space. By convention, we add a z-coordinate of 1 to all of our 2d points, which guarantees we always have a non-zero coordinate with which we can play. Since the origin is no longer the actual origin (it&#8217;s now at (0, 0, 1)), we can shift it. We are actually shearing in 3d space, but when we discard the extraneous z-coordinates and look again at just our original 2d points, it appears as if a translation was applied.</p>
<p>If that&#8217;s not your kind of explanation, maybe the arithmetic will be a little clearer. Again, we augment our points so they are now in 3-space, and our matrix needs to likewise be upgraded to a 3&#215;3 version:</p>
<img src='http://s.wordpress.com/latex.php?latex=%5Cbegin%7Bbmatrix%7Da%20%26%20c%20%26%20e%20%5C%5C%20b%20%26%20d%20%26%20f%20%5C%5C%200%20%26%200%20%26%201%20%5Cend%7Bbmatrix%7D%5Cbegin%7Bbmatrix%7Dx%20%5C%5C%20y%20%5C%5C%201%20%5Cend%7Bbmatrix%7D%20%3D%20%5Cbegin%7Bbmatrix%7Dax%20%2B%20cy%20%2B%20e%20%5C%5C%20bx%20%2B%20dy%20%2B%20f%20%5C%5C%201%20%5Cend%7Bbmatrix%7D&#038;bg=T&#038;fg=000000&#038;s=0' alt='\begin{bmatrix}a &amp; c &amp; e \\ b &amp; d &amp; f \\ 0 &amp; 0 &amp; 1 \end{bmatrix}\begin{bmatrix}x \\ y \\ 1 \end{bmatrix} = \begin{bmatrix}ax + cy + e \\ bx + dy + f \\ 1 \end{bmatrix}' title='\begin{bmatrix}a &amp; c &amp; e \\ b &amp; d &amp; f \\ 0 &amp; 0 &amp; 1 \end{bmatrix}\begin{bmatrix}x \\ y \\ 1 \end{bmatrix} = \begin{bmatrix}ax + cy + e \\ bx + dy + f \\ 1 \end{bmatrix}' class='latex' />
<p>Comparing this result to the linear-transformation matrix multiplication in the previous section, it should be easy to see both the linear transform and the added translation at work. The <em>e</em> and the <em>f</em> entries, since they will always be multiplied by 1, move all points <em>e</em>-units horizontally and <em>f</em>-units vertically.</p>
<p>I purposefully left the bottom row of that matrix as [0, 0, 1]. Some really cool and interesting things can be done by altering the entries there, but without being careful with them, some sticky mathematical situations can arise (especially with invertibility). All the current browsers avoid this (in 2d land, at least) by only accepting transformations specified by the top 2&#215;3 entries of the transformation matrix.</p>
<img src='http://s.wordpress.com/latex.php?latex=%5Cbegin%7Bbmatrix%7Da%20%26%20c%20%26%20e%20%5C%5C%20b%20%26%20d%20%26%20f%20%5Cend%7Bbmatrix%7D%5Cbegin%7Bbmatrix%7Dx%20%5C%5C%20y%20%5C%5C%201%20%5Cend%7Bbmatrix%7D%20%3D%20%5Cbegin%7Bbmatrix%7Dax%20%2B%20cy%20%2B%20e%20%5C%5C%20bx%20%2B%20dy%20%2B%20f%20%5Cend%7Bbmatrix%7D&#038;bg=T&#038;fg=000000&#038;s=0' alt='\begin{bmatrix}a &amp; c &amp; e \\ b &amp; d &amp; f \end{bmatrix}\begin{bmatrix}x \\ y \\ 1 \end{bmatrix} = \begin{bmatrix}ax + cy + e \\ bx + dy + f \end{bmatrix}' title='\begin{bmatrix}a &amp; c &amp; e \\ b &amp; d &amp; f \end{bmatrix}\begin{bmatrix}x \\ y \\ 1 \end{bmatrix} = \begin{bmatrix}ax + cy + e \\ bx + dy + f \end{bmatrix}' class='latex' />
<p>The form is more limited, but for our goals it is sufficient.</p>
<p>This briefest of reviews will have to do for now. If you&#8217;d like to learn more, I suggest basically anything by Jim Blinn (in particular, his <em><a title="Jim Blinn's Corner: A Trip Down the Graphics Pipeline" href="http://www.amazon.com/Jim-Blinns-Corner/dp/1558603875">A Trip Down the Graphics Pipeline</a></em> and its treatment of homogeneous coordinates). For more immediate gratification, Wikipedia does a pretty good job <a title="Transformation matrix" href="http://en.wikipedia.org/wiki/Transformation_matrix">here</a>.</p>
<h3>And Back to IE</h3>
<p>As mentioned earlier, Internet Explorer accepts a transformation matrix through its filter extension to CSS; in Javascript you might set the filter from a matrix like this:</p>
<p><code> element.style.filter="progid:DXImageTransform.Microsoft.Matrix(M11=a, M12=c, M21=b, M22=d, Dx=e, Dy=f, SizingMethod = sMethod)";<br />
</code></p>
<p>where <em>a</em>, <em>b</em>, <em>c</em>, and <em>d</em> still represent a linear transformation, and <em>e</em> and <em>f</em> represent a translation. These could be hardcoded values or dynamic ones, varying due to time and user input.</p>
<p>The <a title="SizingMethod Property" href="http://msdn.microsoft.com/en-us/library/ms532921(VS.85).aspx">SizingMethod</a> property tells IE how to deal with elements that exceed their original bounds when transformed. If SizingMethod is left at its default value—the string &#8220;clip to original&#8221;—everything works and the element is transformed correctly. However, the rendering of it usually leaves something to be desired. If it was rotated or translated or scaled in a way that takes part of it outside of its original bounds, that part will be clipped. For example, a simple translation of 35 pixels to the right yields:</p>
<p><a title="IE8: clip to original example" href="http://extremelysatisfactorytotalitarianism.com/projects/misc/2010/02/ie8_live/clip_to_original.html"><img class="aligncenter size-full wp-image-940" title="IE clipping behavior" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/02/ie_clipping2.png" alt="" width="221" height="342" /></a></p>
<ul>
<li><a title="IE8: clip to original" href="http://extremelysatisfactorytotalitarianism.com/projects/misc/2010/02/ie8_live/clip_to_original.html">View example: SizingMethod = &#8220;clip to original&#8221;</a> (in IE only, obviously).</li>
</ul>
<p>So the default SizingMethod ends up being not very useful, but this isn&#8217;t unexpected given &#8220;clip to original;&#8221; everything seems sane.</p>
<p><span id="autoExpand">The</span> other possible value for SizingMethod is &#8220;auto expand,&#8221; which allows the transformed element to take up as much room as it needs (notably, without changing layout, just like the CSS3 rec). This would seem like the key, but it comes with a catch: if SizingMethod is set to &#8220;auto expand,&#8221; then all translation values will simply be ignored:</p>
<p><a href="http://extremelysatisfactorytotalitarianism.com/projects/misc/2010/02/ie8_live/auto_expand.html"><img class="aligncenter size-full wp-image-1372" title="IE auto expand" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/02/ie_noclipping.png" alt="" width="221" height="342" /></a></p>
<ul>
<li><a title="IE8: auto expand" href="http://extremelysatisfactorytotalitarianism.com/projects/misc/2010/02/ie8_live/auto_expand.html">View example: SizingMethod = &#8220;auto expand&#8221;</a>.</li>
</ul>
<p>I have absolutely no idea what the reasoning was here, or how anyone thought that this behavior would be functionally useful. The MSDN documentation <a title="Dx Property" href="http://msdn.microsoft.com/en-us/library/ms532872(VS.85).aspx">states it</a> so matter of factly that I feel like I must be missing something (or taking crazy pills), but I haven&#8217;t run across anything that actually explains the behavior. Fortunately, there are ways to work around this problem. Mostly.</p>
<h3>Workaround 1</h3>
<p><span id="linearSupport">As</span> <a title="The Sea of Ideas &amp;raquo; Bringing CSS Transforms to Internet Explorer" href="http://paulbakaus.com/2008/08/16/bringing-css-transform-to-internet-explorer/">other people</a> have also realized, the solution is to re-split the desired affine transformation. An augmented matrix is still used throughout the transformation process to allow transforms to be combined, but when it comes time to write the transform to an element&#8217;s style, the linear transformation and the translation are separated once again. The matrix filter (and &#8220;auto expand&#8221;) is used for the linear portion of the transformation. Since the translation is useless there, the element is instead translated as any other element would be: by altering its &#8216;left&#8217; and &#8216;top&#8217; attributes.</p>
<p><span id="minorProblems">There</span> are a few minor regressions inherent to this approach. First, translations now alter layout: as an element is translated around the page, any elements positioned relative to it will also have their positions altered. Currently I work around this by either only transforming absolutely positioned elements, or by wrapping an absolutely positioned element with a relatively positioned one, set to the same original dimensions. This has the effect of keeping the rest of the layout stable as the transformed element moves at will. It&#8217;s not pretty, but it works.</p>
<p>The other minor problem is that elements are now limited to integer pixel positioning instead of the nice floating point values they could use before. Smart rounding can mitigate the effect, but some object jittering will always be present, especially in slow movements or with small elements.</p>
<p>But there&#8217;s a more fundamental hurdle. As stated earlier, by its very nature a linear transformation leaves the origin of an element unaffected. A compliant CSS3 transform with no translation does this: origins stay put. IE is different; it transforms an element, calculates a bounding box for it, and then places that box&#8217;s top left corner at the specified &#8216;top&#8217; and &#8216;left&#8217; coordinates, origin be damned. Hasty info-graphic ahoy:</p>
<p><img class="aligncenter size-full wp-image-1376" title="Transform comparison" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/02/transform_comparison.png" alt="" width="296" height="714" /></p>
<p>The default origin for both the CSS3 Transforms spec and IE is found at the center of an element (given here in screen coordinates). When a pure linear transform is applied to it (in this case a rotation of 30 degrees), CSS3 keeps the origin fixed. IE&#8217;s bounding box routine will instead ensure that an element&#8217;s left-most point is at its &#8216;left&#8217; value, and its top-most point is at its &#8216;top&#8217; value. While this may seem straightforward in its description, in practice you just end up with bouncy boxes. <em>No</em> point is fixed. This becomes clear when you see it in action:</p>
<p><a href="http://extremelysatisfactorytotalitarianism.com/projects/misc/2010/02/ie8_live/rotate.html"><img class="aligncenter size-full wp-image-1374" title="IE naive rotation" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/02/ie_naive_rot.png" alt="" width="248" height="231" /></a></p>
<ul>
<li><a title="IE: naive rotation" href="http://extremelysatisfactorytotalitarianism.com/projects/misc/2010/02/ie8_live/rotate.html">View example: pure rotation behavior</a></li>
</ul>
<p>Again, I have no idea how someone implemented this, tested it, and thought it useful, but not all things are revealed to me.</p>
<p>(In a rotation, the origin&#8217;s movement can be described by two catenary curves. That is cool. But not useful.)</p>
<h3>Workaround 2</h3>
<p>Since IE keeps no point fixed under a linear transformation, if a translation is then just naively applied, an element&#8217;s final position will have shifted not by the translation value but by (translation + (some origin shift)). We need to compute that shift and remove it every time.</p>
<p>Take horizontal positioning first: Let <em>x</em> be the &#8216;left&#8217; position of the original (untransformed) element, let <em>w</em> be its original width. The element&#8217;s horizontal midpoint is at</p>
<img src='http://s.wordpress.com/latex.php?latex=m_x%20%3D%20x%20%2B%20%5Cfrac%7Bw%7D%7B2%7D&#038;bg=T&#038;fg=000000&#038;s=0' alt='m_x = x + \frac{w}{2}' title='m_x = x + \frac{w}{2}' class='latex' />
<p>Finding the midpoint of the bounding box can have serious impacts on performance, but we will only concern ourselves with the theory for now and assume we already know its dimensions. What follows wouldn&#8217;t really be a proof, relying on an appeal to intuition with one visual example, but for one simple fact: a rectangle under a 2d linear transform shares its center with its minimum axis-aligned bounding box. The proof of this is straightforward, so I&#8217;ll leave it as an exercise for the reader.</p>
<p><img class="aligncenter size-full wp-image-1378" title="IE bounding box dimensions" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/02/ie_bounding_box.png" alt="" width="384" height="357" /></p>
<p>Let <em>w<sub>b</sub></em> be the width of the bounding box of the transformed element. Note that <em>w<sub>b</sub></em> is <em>not</em> a transformed version of the vector (<em>w</em>, 0). This is obvious under a 90° rotation, as <em>w<sub>b</sub></em> would have length 0, while the bounding box would actually have a width equal to the height of the original element.</p>
<p>Since it shares its center with its bounding box, and we&#8217;ve assumed that we know the width of that box, the transformed element&#8217;s midpoint has moved to</p>
<img src='http://s.wordpress.com/latex.php?latex=m_x%5E%5Cprime%3D%20x%20%2B%20%5Cfrac%7Bw_b%7D%7B2%7D&#038;bg=T&#038;fg=000000&#038;s=0' alt='m_x^\prime= x + \frac{w_b}{2}' title='m_x^\prime= x + \frac{w_b}{2}' class='latex' />
<p><span id="determineShift">Since</span> we want the bounding box (and thus the transformed element) to be horizontally centered at <em>m<sub>x</sub></em>, not <em>m&#8217;<sub>x</sub></em>, we subtract the difference of the two from the translation value before we apply it to the element. If we call the horizontal shift <em>s<sub>x</sub></em></p>
<img src='http://s.wordpress.com/latex.php?latex=s_x%3D%20m_x%5E%5Cprime%20-%20m_x%3D%5Cfrac%7B1%7D%7B2%7D%28w_b-w%29&#038;bg=T&#038;fg=000000&#038;s=0' alt='s_x= m_x^\prime - m_x=\frac{1}{2}(w_b-w)' title='s_x= m_x^\prime - m_x=\frac{1}{2}(w_b-w)' class='latex' />
<p>The vertical shift is found similarly.</p>
<img src='http://s.wordpress.com/latex.php?latex=s_y%3D%20m_y%5E%5Cprime%20-%20m_y%3D%5Cfrac%7B1%7D%7B2%7D%28h_b-h%29&#038;bg=T&#038;fg=000000&#038;s=0' alt='s_y= m_y^\prime - m_y=\frac{1}{2}(h_b-h)' title='s_y= m_y^\prime - m_y=\frac{1}{2}(h_b-h)' class='latex' />
<p><img class="aligncenter size-full wp-image-1385" title="IE origin shift" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/02/ie_shift_vector.png" alt="" width="396" height="378" /></p>
<p><span id="translateTime">In</span> JavaScript, the shift would then be removed when applying the translation to the element:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">element.<span style="color: #660066;">style</span>.<span style="color: #660066;">left</span> <span style="color: #339933;">=</span> x <span style="color: #339933;">+</span> e <span style="color: #339933;">-</span> sx <span style="color: #339933;">+</span> <span style="color: #3366CC;">'px'</span><span style="color: #339933;">;</span>
element.<span style="color: #660066;">style</span>.<span style="color: #660066;">top</span> <span style="color: #339933;">=</span> y <span style="color: #339933;">+</span> f <span style="color: #339933;">-</span> sy <span style="color: #339933;">+</span> <span style="color: #3366CC;">'px'</span><span style="color: #339933;">;</span></pre></div></div>

<p>Finally, while I&#8217;m not going to go in depth on support for <a title="The ‘transform-origin’ Property" href="http://www.w3.org/TR/css3-2d-transforms/#transform-origin-property">changing the origin</a>, it&#8217;s just an additional adjustment, this time by the <em>transformed</em> difference between the center of the original element and the requested new origin. If you&#8217;d like to take a look at my solution, it&#8217;s <a title="TransformedElementImplIE8::commitTransform()" href="http://code.google.com/p/gwt-ns/source/browse/trunk/src/gwt/ns/transformedelement/client/impl/TransformedElementImplIE8.java#166">located here</a>. The code is somewhat obfuscated for performance, but it shouldn&#8217;t take long to figure out (yes, that&#8217;s Java. It&#8217;s still weird for me too).</p>
<h3>Next</h3>
<p>That&#8217;s it for now. If you just want the code, or you&#8217;re dying to know how the replacement of two lines of code with twelve resulted in an order of magnitude speedup, stay tuned for the <a title="Part 2" href="http://extremelysatisfactorytotalitarianism.com/blog/?p=922">next post</a>, entitled, &#8220;The DOM,&#8221; or, &#8220;The API Only a Mother Could Love.&#8221;</p>
<h3>Links Cited</h3>
<p>Example pages. These only work in Internet Explorer, and probably only in IE8.</p>
<p style="padding-left: 30px;"><a title="IE8: clip to original" href="http://extremelysatisfactorytotalitarianism.com/projects/misc/2010/02/ie8_live/clip_to_original.html">SizingMethod: &#8216;clip to original&#8217;</a><br />
<a title="IE8: auto expand" href="http://extremelysatisfactorytotalitarianism.com/projects/misc/2010/02/ie8_live/auto_expand.html">SizingMethod: &#8216;auto expand&#8217;</a><br />
<a title="IE: naive rotation" href="http://extremelysatisfactorytotalitarianism.com/projects/misc/2010/02/ie8_live/rotate.html">Bounding box positioning</a>.</p>
<p>Outside resources.</p>
<p style="padding-left: 30px;"><a title="The gwtns library" href="http://code.google.com/p/gwt-ns/">The gwtns library</a><br />
<a title="CSS 2D Transforms Module Level 3" href="http://www.w3.org/TR/css3-2d-transforms/">CSS 2D Transforms Module Level 3</a><br />
<a title="Matrix Filter" href="http://msdn.microsoft.com/en-us/library/ms533014(VS.85).aspx">MSDN: Matrix Filter</a><br />
<a title="SVG 1.1: Coordinate Systems, Transformations, and Units" href="http://www.w3.org/TR/SVG/coords.html">SVG 1.1: Coordinate Systems, Transformations, and Units</a><br />
<a title="SizingMethod Property" href="http://msdn.microsoft.com/en-us/library/ms532921(VS.85).aspx">MSDN: SizingMethod Property</a><br />
<a title="Jim Blinn's Corner: A Trip Down the Graphics Pipeline" href="http://www.amazon.com/Jim-Blinns-Corner/dp/1558603875">A Trip Down the Graphics Pipeline</a><br />
<a title="The Sea of Ideas &amp;raquo; Bringing CSS Transforms to Internet Explorer" href="http://paulbakaus.com/2008/08/16/bringing-css-transform-to-internet-explorer/">Paul Bakaus&#8217;s Transformie</a><br />
<a title="jQuery Patch: Animate CSS Rotation and Scale - zachstronaut" href="http://www.zachstronaut.com/posts/2009/08/07/jquery-animate-css-rotate-scale.html">Zachary Johnson&#8217;s jQuery Patch</a><br />
<a title="Jon Combe | Code | HTML clocks using JavaScript and CSS rotation" href="http://joncom.be/code/css-clocks/">Jon Combe&#8217;s css clocks</a></p>
]]></content:encoded>
			<wfw:commentRss>http://extremelysatisfactorytotalitarianism.com/blog/?feed=rss2&amp;p=1002</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>&#8220;We never jit DOM workers&#8221;</title>
		<link>http://extremelysatisfactorytotalitarianism.com/blog/?p=912</link>
		<comments>http://extremelysatisfactorytotalitarianism.com/blog/?p=912#comments</comments>
		<pubDate>Thu, 11 Feb 2010 00:33:19 +0000</pubDate>
		<dc:creator>Brendan Kenny</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[amateur hour]]></category>
		<category><![CDATA[bugzilla]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[Web Workers]]></category>

		<guid isPermaLink="false">http://extremelysatisfactorytotalitarianism.com/blog/?p=912</guid>
		<description><![CDATA[This bug is very interesting in light of some assumptions I was making. Need to investigate. It&#8217;s great to see so much work going into workers and the tracing engine, though, and to hear that changes will start rolling out &#8230; <a href="http://extremelysatisfactorytotalitarianism.com/blog/?p=912">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a title="Bug 538440 - We never jit DOM workers" href="https://bugzilla.mozilla.org/show_bug.cgi?id=538440">This bug</a> is very interesting in light of some assumptions I was making. Need to investigate.</p>
<p>It&#8217;s great to see so much work going into workers and the tracing engine, though, and to hear that changes will start rolling out in point releases. I feel for corporate deployments, and I hate when it&#8217;s done through ever-present update services, but in terms of browser security and iterating/testing standards-to-be, this seems to be the release model to follow. It&#8217;s a huge relief to not have to work around Chrome 2&#8242;s Worker problems, and it will be interesting to see if something similar happens with Chrome 3 in the next month or two. But I worry constantly about Firefox 3.0 vs 3.5 vs 3.6.</p>
<p>I don&#8217;t have a clear idea of where the balance should be between AUTO-UPDATE and developers waiting 5 years for implementations to converge (or at least settle). &#8220;Make all things easier for the user&#8221; is a good starting ideal—as long as &#8220;declining our help&#8221; is first on the list—but the effect in aggregate would not be linear.</p>
<p>Rambling finished. Flash 9 it is.</p>
]]></content:encoded>
			<wfw:commentRss>http://extremelysatisfactorytotalitarianism.com/blog/?feed=rss2&amp;p=912</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Web Worker Example: The Rationals</title>
		<link>http://extremelysatisfactorytotalitarianism.com/blog/?p=645</link>
		<comments>http://extremelysatisfactorytotalitarianism.com/blog/?p=645#comments</comments>
		<pubDate>Sat, 06 Feb 2010 22:08:54 +0000</pubDate>
		<dc:creator>Brendan Kenny</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[hyperbinary]]></category>
		<category><![CDATA[ie]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[ns]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[rationals]]></category>
		<category><![CDATA[tracemonkey]]></category>
		<category><![CDATA[v8]]></category>
		<category><![CDATA[Web Workers]]></category>

		<guid isPermaLink="false">http://extremelysatisfactorytotalitarianism.com/blog/?p=645</guid>
		<description><![CDATA[The Web Worker library I&#8217;m writing for GWT is getting to the point that it needs some examples. At least one of them needs to be simple enough that what is being done doesn&#8217;t distract from how it&#8217;s being done. You can see various examples &#8230; <a href="http://extremelysatisfactorytotalitarianism.com/blog/?p=645">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The Web Worker library I&#8217;m writing for GWT is getting to the point that it needs some examples. At least one of them needs to be simple enough that what is being done doesn&#8217;t distract from how it&#8217;s being done. You can see various examples like this in the official (draft) <a title="Web Workers Draft Specification" href="http://www.whatwg.org/specs/web-workers/current-work/">specification</a> and over at the <a title="Using web workers - MDC" href="https://developer.mozilla.org/En/Using_web_workers">MDC</a>. The problem with these examples, I think, is that they don&#8217;t really motivate the use of Workers; the task is usually completely unrealistic, intentionally implemented naively, and the gain so small that maintaining two separate versions of a codebase—one for browsers with Worker support and one for those without—ends up on the wrong end of the cost/benefit analysis.</p>
<p>But it might work for us. So, here&#8217;s a ridiculously unrealistic task, coded in the most straightforward way possible, and that runs perfectly well in Internet Explorer (8) without any Worker support. The reality is that instructive examples are of course necessary, so I&#8217;m going to trust to other demos to inspire excitement. In the meantime, I get another chance to play around with hyperbinary numbers. I&#8217;ve mentioned this sequence and its connection to the rational numbers before, but to recap: I first came across it on <a title="Cardinality of infinite sets - Division by Zero" href="http://divisbyzero.com/2009/09/11/cardinality1-html/">Division by Zero</a> (still waiting for the rest of that series) and the original paper by Calkin and Wilf is <a title="Recounting the Rationals" href="http://www.math.upenn.edu/~wilf/website/recounting.pdf">here</a>.</p>
<p>The example application calculates and displays a succession of rational numbers (fractions), as ordered by the Calkin-Wilf enumeration of the rationals. That sequence has several very interesting properties, but notably it contains every single (positive) rational number, in reduced form, exactly once. The example page doesn&#8217;t quite live up to the &#8220;every&#8221; part, but it does go on for a while. You can see it here: <a title="An Enumeration of the Rational Numbers" href="http://extremelysatisfactorytotalitarianism.com/projects/ns/rationals/">An Enumeration of the Rational Numbers</a>.</p>
<p>By default, it actually starts at the 10-millionth rational number to make the demonstration a little more computationally taxing, but that can be changed if you want to see how it all begins (for the less motivated: &#8220;1&#8243;).</p>
<h3>The GWT-y details</h3>
<p>Right&#8230; Anyway, the &#8220;Rationals&#8221; GWT project is divided into two modules. The Worker module (<a title="RationalsWorker Source" href="https://code.google.com/p/gwt-ns/source/browse/trunk/samples/gwt/ns/sample/rationals/client/RationalsWorker.java">RationalsWorker</a>) extends a special Worker EntryPoint. It repeatedly calculates a new hyperbinary number, combines it with the last, and returns the result to the parent script:</p>
<p><span id="more-645"></span></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> RationalsWorker <span style="color: #000000; font-weight: bold;">extends</span> IterativeWorkerEntryPoint <span style="color: #009900;">&#123;</span>
  @Override
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onWorkerLoad<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// nothing to initialize</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  @Override
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">int</span> execute<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// calculate numerator and denominator...</span>
    postRational<span style="color: #009900;">&#40;</span>numerator, denominator<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">return</span> DELAY_MS<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #008000; font-style: italic; font-weight: bold;">/**
   * Creates a message containing calculated numerator and denominator and
   * send to parent context.
  */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> postRational<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> numerator, <span style="color: #000066; font-weight: bold;">int</span> denominator<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003399;">String</span> data <span style="color: #339933;">=</span> Json.<span style="color: #006633;">strigify</span><span style="color: #009900;">&#40;</span>RationalNumber.<span style="color: #006633;">create</span><span style="color: #009900;">&#40;</span>numerator, denominator<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    postMessage<span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The main module (<a title="Rationals Source" href="https://code.google.com/p/gwt-ns/source/browse/trunk/samples/gwt/ns/sample/rationals/client/Rationals.java">Rationals</a>) creates a Worker object out of the RationalsWorker module and then just waits to receive new numbers, inserting them into the page as they arrive:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Rationals <span style="color: #000000; font-weight: bold;">implements</span> EntryPoint, MessageHandler <span style="color: #009900;">&#123;</span>
  <span style="color: #003399;">Element</span> numerator<span style="color: #339933;">;</span>
  <span style="color: #003399;">Element</span> denominator<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Worker module definition</span>
  @WorkerModuleDef<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;gwt.ns.sample.rationals.RationalsWorker&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">interface</span> RationalWorkerFactory <span style="color: #000000; font-weight: bold;">extends</span> WorkerFactory <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span>
&nbsp;
  @Override
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onModuleLoad<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    numerator <span style="color: #339933;">=</span> RootPanel.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;numerator&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getElement</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    denominator <span style="color: #339933;">=</span> RootPanel.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;denominator&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getElement</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Worker creation</span>
    RationalWorkerFactory factory <span style="color: #339933;">=</span> GWT.<span style="color: #006633;">create</span><span style="color: #009900;">&#40;</span>RationalWorkerFactory.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    Worker worker <span style="color: #339933;">=</span> factory.<span style="color: #006633;">createAndStart</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    worker.<span style="color: #006633;">setMessageHandler</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  @Override
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onMessage<span style="color: #009900;">&#40;</span>MessageEvent event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    RationalNumber newNum <span style="color: #339933;">=</span> Json.<span style="color: #006633;">parse</span><span style="color: #009900;">&#40;</span>event.<span style="color: #006633;">getData</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    numerator.<span style="color: #006633;">setInnerHTML</span><span style="color: #009900;">&#40;</span>newNum.<span style="color: #006633;">getNumerator</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    denominator.<span style="color: #006633;">setInnerHTML</span><span style="color: #009900;">&#40;</span>newNum.<span style="color: #006633;">getDenominator</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The compilation process is better described in the design document (which I&#8217;ll be finishing real soon now), but I&#8217;ll describe it here in brief. When the Rationals module is compiled, the Web Worker library handles the loading of the Worker through the magic of deferred binding. In code destined for browsers with native Worker support, the Worker module is compiled using a special linker, and a URL for the resulting script is inserted into the parent module so the browser can load it at runtime. For browsers without Web Worker support, the Worker module&#8217;s entry point is actually inserted directly into the main module, along with some machinery to simulate the behavior of a Worker. In both cases, a &#8220;Worker&#8221; object is returned and the parent module can proceed in full ignorance of the implementation.</p>
<p>The Rationals example source code is available in the <a title="Rationals Example" href="https://code.google.com/p/gwt-ns/source/browse/#svn/trunk/samples/gwt/ns/sample/rationals">project repository</a>. The host page is down in the war directory.</p>
<h3>Benefits and Runtime Behavior</h3>
<p>As I noted above, this example runs well in Internet Explorer 8. This comes down to how it was written. Even though code executed continuously inside a Worker would not block the main event loop, the same code run in a faux-Worker would. Authors are perfectly free to further differentiate by loading different code based on browser type. However, the first goal of this library was to provide a &#8220;thread-like&#8221; context for executing the same code regardless of browser—using a real Worker if available—in a way that requires only a minimum of boilerplate and provides full support for development-mode debugging.</p>
<p>So, <em>if</em> the same code is going to be run everywhere, it can&#8217;t be written in a way that disrupts responsiveness in older browsers. For this example, the calculation of rational numbers is divided by the usual setTimeout/callback scheme to keep the UI (fairly) responsive in IE, even though it is being done in the main event loop and nearly pegging one core on my old machine:</p>
<p><img class="aligncenter" title="explorer_cpu" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/02/explorer_cpu.png" alt="IE CPU use at 46%" width="441" height="42" /></p>
<p>Chrome is a different story. The same code uses about the same execution resources (generating rationals at a greater rate) but this time it is running in a Web Worker:</p>
<p><img class="aligncenter" title="chrome_cpu" src="http://extremelysatisfactorytotalitarianism.com/blog/wp-content/uploads/2010/02/chrome_cpu.png" alt="Chrome CPU use in Worker" width="441" height="84" /></p>
<p>As can be seen, this leaves the actual page (&#8220;Tab: &#8230;&#8221;) doing almost nothing. If we imagine that this is a script that <em>must</em> be run, regardless of platform, Chrome leaves the page free to do something else, at the author&#8217;s discretion, or to simply demonstrate the silky smoothness of the future while IE updates at 15 frames per second.</p>
<h3>Stray Observations</h3>
<p>In Firefox versions prior to 3.6, TraceMonkey seems to struggle with <em>some</em> scripts in a Worker context while having no problem when they are run normally. This really calls for a test page, with a reliable Worker on/off switch, to determine exactly which browsers (× which kinds of problems) should receive native or emulated implementations.</p>
<p>With that said, Firefox (and especially Minefield) eats this demo for breakfast. The inner loop is mostly simple arithmetic and array accesses, so I wonder if something else is holding v8 back. If there&#8217;s a way to profile a Web Worker using Firebug/Development Tools, I haven&#8217;t found it yet.</p>
<p>Demo: <a title="An Enumeration of the Rational Numbers" href="http://extremelysatisfactorytotalitarianism.com/projects/ns/rationals/">An Enumeration of the Rational Numbers</a></p>
]]></content:encoded>
			<wfw:commentRss>http://extremelysatisfactorytotalitarianism.com/blog/?feed=rss2&amp;p=645</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>I love Firefox 3.6 loves Workers</title>
		<link>http://extremelysatisfactorytotalitarianism.com/blog/?p=594</link>
		<comments>http://extremelysatisfactorytotalitarianism.com/blog/?p=594#comments</comments>
		<pubDate>Mon, 25 Jan 2010 04:49:33 +0000</pubDate>
		<dc:creator>Brendan Kenny</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[gwtbox2d]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[ns]]></category>
		<category><![CDATA[spidermonkey]]></category>
		<category><![CDATA[tracemonkey]]></category>
		<category><![CDATA[Web Workers]]></category>

		<guid isPermaLink="false">http://extremelysatisfactorytotalitarianism.com/blog/?p=594</guid>
		<description><![CDATA[This post is late (of course), but I wanted to put in a plug for Firefox 3.6. Tremendous, tremendous work has been done since 3.5 and it all shows. In many ways the drumbeat doesn&#8217;t even need to be codified &#8230; <a href="http://extremelysatisfactorytotalitarianism.com/blog/?p=594">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This post is late (of course), but I wanted to put in a plug for <a title="Get Firefox" href="http://www.mozilla.com/en-US/firefox/firefox.html">Firefox 3.6</a>. Tremendous, tremendous work has been done since 3.5 and it all shows. In many ways the drumbeat doesn&#8217;t even need to be codified or pushed, as it&#8217;s so easy to get swept up in the passion the Mozilla community has for improving the web. My favorite part of witnessing Firefox development is probably the transparency, both in Bugzilla and in blogs, where developers and engineers can say whatever <em>they </em>think is important in the ongoing elucidation of the open web, <a title="on personas and themes" href="http://steelgryphon.com/blog/2010/01/09/on-personas-and-themes/">consequences be damned</a> (and it&#8217;s reactions to posts like that that demonstrate how much the rest of the world needs to learn on how to engage in an open dialogue). Congratulations to everyone involved in the new release.</p>
<p>But enough about other people. Most importantly, my Twitter campaign for improving TraceMonkey performance in Web Workers has clearly paid off (actual events might not reflect that statement). 3.6rc1 showed nearly identical performance for gwtBox2d running <a title="Main Loop Demo" href="http://extremelysatisfactorytotalitarianism.com/projects/experiments/2010/01/gwtbox2d_demo1/">in a page&#8217;s main loop</a> as <a title="Worker Demo" href="http://extremelysatisfactorytotalitarianism.com/projects/experiments/2010/01/gwtbox2dWorker_demo2/">in a Worker script</a>, and this has carried on through to the final release. I also haven&#8217;t had any crashes running any demos (yet), which were caused (I think) by an OOM from the tracing engine. The performance increase due to parallel execution isn&#8217;t quite what I was hoping for, but I need to build in some more sophisticated profiling hooks to see what exactly is going on. Also, as fun as Canvas is for some things (and I&#8217;m working on some pixel manipulation ideas that are actually suited for the format), the way I&#8217;m using it now is much better matched with something like SVGWeb or Raphael(js). I only wish the bindings already existed.</p>
<p>I&#8217;ve also been racing to put together some ideas I had on making Web Workers easy to use in any GWT project. That code is finally reaching a usable state and I&#8217;ve had the pleasure of learning far more about Generators, Linkers, and the GWT compiler than I thought I would ever have the impetus to. My approach is just about absolutely nuts, but between a js physics library and a fragment-shader mime type, clearly the Scary Door has already been breached. If this project works out at all, there will be a post here in the next day or two.</p>
]]></content:encoded>
			<wfw:commentRss>http://extremelysatisfactorytotalitarianism.com/blog/?feed=rss2&amp;p=594</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
