<?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>Paul Hayes &#187; transformations</title>
	<atom:link href="http://www.paulrhayes.com/tag/transformations/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.paulrhayes.com</link>
	<description>The web musings and experiments of.</description>
	<lastBuildDate>Sun, 06 Nov 2011 11:31:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>CSS Modal follow up</title>
		<link>http://www.paulrhayes.com/2011-04/css-modal-follow-up/</link>
		<comments>http://www.paulrhayes.com/2011-04/css-modal-follow-up/#comments</comments>
		<pubDate>Tue, 26 Apr 2011 21:43:51 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[modal]]></category>
		<category><![CDATA[transformations]]></category>

		<guid isPermaLink="false">http://www.paulrhayes.com/?p=141</guid>
		<description><![CDATA[A cross browser modal box with CSS animations. Supported in IE7+ it's now being used to add comments.]]></description>
			<content:encoded><![CDATA[<p>In <a href="/2011-03/css-modal/">my original post</a> I explained how to create a CSS only modal pop-up using :target, pseudo-elements and pointer events. This had a number of caveats, any browser that didn’t support pointer events would see a non-clickable page and the forward/back controls would navigate through dialogues, which is usually undesirable. Of course it was only an experiment.</p>
<p>My comment form had been much neglected and it felt like the perfect opportunity to try out this modal in a real environment. Click the “<a href="#respond" class="respond">Post a comment</a>” link to see it in action.</p>
<p><iframe class="vimeo" src="http://player.vimeo.com/video/22774103" width="612" height="408" frameborder="0"></iframe></p>
<p>All references to the :target pseudo-selector have been removed, instead an “active” class is toggled using JavaScript. The CSS modal still uses an opacity transition but pointer events are gone. The default is now display:none with an intermediate state that renders the modal as display:block (remember it still begins at opacity: 0).</p>
<p>The flow is:</p>
<ul>
<li>Add an intermediate class to trigger the modal elements above everything, with opacity 0.</li>
<li>Add an active class to trigger animation and transition to full opacity.</li>
<li>On close, remove active class, add minimise class to trigger  minimise animation and transition to opacity 0.</li>
<li>Remove intermediate class.</li>
</ul>
<p>Onclick handlers are added to the “post comment” links to add classes and to the close link to remove them. When opened a handler is added to the body to listen for the ESC key, which closes the modal. The first input in the modal is focused on open.</p>
<p>I took the opportunity to play with some HTML5 features. The comment form now uses placeholder attributes, and if supported, labels are hidden. The feature detection is delightfully simple:</p>
<pre>
supportPlaceholder: function() {
	  var i = document.createElement('input');
	  return 'placeholder' in i;
}()
</pre>
<p>See <a href="http://diveintohtml5.org/detect.html#input-placeholder">Dive into HTML5</a> for more.</p>
<p>The close link text which has an :after pseudo-element (i.e. the X) is no longer hidden, instead it becomes the cancel link and is essential for browsers that can’t comprehend generated content.</p>
<p>In webkit you’ll see the modal bounce in and minimise out (smoothly in Safari and iOS). In Firefox you’ll get an opacity transition and in IE the modal will just appear or disappear. In IE8 and below the page is not greyed out due to lack of rgba support. I’m fine with this. This is still a bit of a trial to see how people actually use the modal and what problems it might throw up.</p>
<p>In conclusion, with JavaScript much of the mechanical new CSS can be dropped and with a slightly more complicated class toggle system we achieve cross browser support, without sacrificing that lovely hardware accelerated CSS animation.</p>
<p>Still want that animation cross browser? I recommend looking into <a href="http://farukat.es/journal/2011/02/514-new-creation-jquery-runloop-plugin">Faruk Ateş’s Runloop jQuery plugin</a> which gives you keyframed animations in any browser.</p>
<p>In other news, I’ve tidied up the comments layout a little and added a short <a href="/category/bookshelf/">books category</a> with a selection of books I highly recommend.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2011-04/css-modal-follow-up/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Creating a sphere with 3D CSS</title>
		<link>http://www.paulrhayes.com/2011-02/creating-a-sphere-with-3d-css/</link>
		<comments>http://www.paulrhayes.com/2011-02/creating-a-sphere-with-3d-css/#comments</comments>
		<pubDate>Thu, 10 Feb 2011 23:33:33 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Experiments]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[sphere]]></category>
		<category><![CDATA[transformations]]></category>
		<category><![CDATA[transitions]]></category>
		<category><![CDATA[webkit]]></category>

		<guid isPermaLink="false">http://www.paulrhayes.com/?p=124</guid>
		<description><![CDATA[Rotate and combine elements in 3D space to create an awesome sphere using CSS 3D transforms.]]></description>
			<content:encoded><![CDATA[<p>With CSS3’s 3D transforms I’ve illustrated how to build a <a href="http://www.paulrhayes.com/2009-07/animated-css3-cube-interface-using-3d-transforms/">cube</a> and a <a href="http://www.paulrhayes.com/2010-10/css-tetrahedron/">tetrahedron</a>. It is also possible to create a sphere-like object, albeit with many elements.</p>
<p><a href="http://www.paulrhayes.com/experiments/sphere/">3D CSS Sphere</a><br />
Works in the latest Safari and iOS (just about runs on an iPhone 4).</p>
<p><img src="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-normal.png" alt="3D sphere using CSS transform" width="549" /></p>
<p>Recently I’ve been looking at creating applicable 3D carousels. These rely on positioning panels in a circle around a central point (ie. rotation about the Y-axis), I put these panels in an unordered list. A natural extension is to duplicate each <code>&lt;ul&gt;</code> and rotate about the X-axis. With ‘A’ rounds (or lists), and ‘B’ panels per round (<code>&lt;li&gt;</code>s), I built a script that would distribute these in a circular manner, panels about Y-axis, lists about the X-axis, creating a sphere.</p>
<p>The more elements per round and the more rounds, the smoother the sphere. But this soon stacks up and kills Safari. The optimum numbers have been about 9 rounds and 30 panels per round for a decent looking sphere, but that’s 279 3D elements and Safari starts to choke. Allowing the panels to overlap eases this somewhat and leads to a tighter sphere but it still appears blocky.</p>
<p>The biggest gains come with border radius. Using a huge radius that made each panel circular the sphere suddenly gained a lovely curvature, and the number of rounds and panels could be reduced. In the experiment I use 8 rounds and 24 panels (200 elements). This doesn’t start choking until I start aggressively animating.</p>
<p>Playing with this I’ve built a few different styles of sphere. In the experiment I’ve included the blocky “square” version, along with the smoothed out border radius one (default). Marking panels white, and a few black can create a nice eye-ball effect.</p>
<p><a href="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-square.png"><img src="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-square-150x150.png" alt="Sphere without border radius" width="150" height="150" /></a> <a href="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-eye.png"><img src="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-eye-150x150.png" alt="Eye" width="150" height="150" /></a></p>
<p>Also included in the experiment are versions showing a single round and another style named “contact”. This takes two lists and animates them like the space transportation device in the Jodie Foster movie of the same name.</p>
<p><a href="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-contact.png"><img src="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-contact-150x150.png" alt="Rotating rounds" width="150" height="150" /></a> <a href="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-half.png"><img src="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-half-150x150.png" alt="Half a sphere" width="150" height="150" /></a> <a href="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-kaleid.png"><img src="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-kaleid-150x150.png" alt="Kaleidoscope effect" width="150" height="150" /></a></p>
<p>Animating the border radius on all 192 panels (if your machine can cope), gives a neat kaleidoscope effect, also included in the experiment.</p>
<h3>Code</h3>
<p>The generated HTML is simply a couple of <code>&lt;div&gt;</code>s containing lists:</p>
<pre>&lt;div id=&quot;sphere&quot;&gt;
	&lt;div class=&quot;container&quot;&gt;
		&lt;ul&gt;
			&lt;li&gt;&lt;/li&gt;
			&lt;li&gt;&lt;/li&gt;
			…
		&lt;/ul&gt;
		…
	&lt;/div&gt;
&lt;/div&gt;</pre>
<p>To transform each set of panels into a circle the total number is divided by 360 to get the angle of rotation. Merely rotating will put all panels on top of each other, translating in the Z axis will move them out from the centre point. The correct translation distance so the panels slightly overlap (i.e. the circle radius) is worked out with some <a href="http://en.wikipedia.org/wiki/Trigonometry#Mnemonics">simple trigonometry</a>. Lists are rotated in the X axis, simply the number of lists divided by 360.</p>
<p>Looping through each panel for each list, the angles of rotation are gradually increased by the calculated increments and applied to the elements:</p>
<pre>
var panels = p || this.panels,
rounds = r || this.rounds,
rotationPerPanel = 360/panels,
rotationPerRound = 360/2/rounds,
yRotation, xRotation,
width = this.panelWidth,
zTranslate = (width/2) / Math.tan(rotationPerPanel * Math.PI/180),
$container = this.el,
$ul, $li, i, j;

this.el.html(&#39;&#39;);
for(i = 0; i &lt; rounds; i++) {
	$ul = $(&#39;&lt;ul&gt;&#39;);
	xRotation = rotationPerRound * i;
	$ul[0].style.webkitTransform = &quot;rotateX(&quot;+ xRotation + &quot;deg)&quot;;
	for(j = 0; j &lt; panels; j++) {
		$li = $(&#39;&lt;li&gt;&#39;);
		yRotation = rotationPerPanel * j;
		$li[0].style.webkitTransform = &quot;rotateY(&quot;+ yRotation +&quot;deg)
                         translateZ(&quot;+ zTranslate +&quot;px)&quot;;
		$ul.append($li);
	}
	$container.append($ul);
}
</pre>
<p>To achieve the 3D effect we give <code>#sphere</code> some perspective, which forms the containing block. A second container transitions between different transforms, letting us rotate the sphere. The complicated transform parts are applied inline via the JavaScript above, but each list element needs <code>preserve-3d</code> so its direct descendants are transformed in the same 3D space (rather than in 2D).</p>
<pre>
#sphere {
width: 100px;
height: 100px;
margin: 200px auto;
-webkit-perspective: 800;
}

.container {
width: 100px;
height: 100px;
-webkit-transition: -webkit-transform 200ms linear;
-webkit-transform-style: preserve-3d;
}

.container > ul {
-webkit-transform-style: preserve-3d;
width: 100%;
height: 100%;
position: absolute;
}

.container li {
width: 98px;
height: 98px;
position: absolute;
display: block;
background: #000;
border: 1px solid #fff;
opacity: 0.1;
border-radius: 50px;
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2011-02/creating-a-sphere-with-3d-css/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>CSS Tetrahedron</title>
		<link>http://www.paulrhayes.com/2010-10/css-tetrahedron/</link>
		<comments>http://www.paulrhayes.com/2010-10/css-tetrahedron/#comments</comments>
		<pubDate>Wed, 06 Oct 2010 19:59:59 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Experiments]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[pyramid]]></category>
		<category><![CDATA[transformations]]></category>

		<guid isPermaLink="false">http://www.paulrhayes.com/?p=112</guid>
		<description><![CDATA[Use CSS to create triangles then arrange with 3D transforms to create a pyramid.]]></description>
			<content:encoded><![CDATA[<p>A triangle can be created in CSS by manipulating the borders of an element. Combining four triangles in a 3D space using <code>-webkit-transform</code>, these can be positioned to form a tetrahedron (or pyramid if you prefer).</p>
<p><a href="http://www.paulrhayes.com/experiments/pyramid/index.html">CSS pyramid — proof of concept</a><br />
For now this only works in Safari 5.0.2+ and iOS, although 3D transforms will surface in Firefox 4 and the next build of Chrome. The demo doesn’t use JavaScript.</p>
<p><a href="http://www.paulrhayes.com/experiments/pyramid/index.html"><img src="http://host.trivialbeing.org/up/small/css-pyramid.png" alt="CSS pyramid"></a></p>
<p>Combining squares and triangles, <a href="http://www.paulrhayes.com/2010-09/3d-css-cube-ii-touch-gestures-click-and-drag/">cubes</a> and pyramids, all sorts of 3D structures are now possible, if you are so inclined. Not necessarily useful, but possible.</p>
<p>The rotation is performed using a <code>-webkit-animation</code>, I’ve given the animation the name “spin”, which rotates the pyramid around Y from 0 to 360 degrees:</p>
<pre>
#pyramid {
-webkit-animation: spin 5s linear infinite;
}

@-webkit-keyframes spin {
  from {
  	-webkit-transform: rotateY(0deg) rotateX(-20deg);
  }
  to {
  	-webkit-transform: rotateY(360deg) rotateX(-20deg);
  }
}
</pre>
<p>If you haven’t seen it before, the code to create an approximate equilateral triangle is as follows:</p>
<pre>
#pyramid > div {
position: absolute;
border-color: transparent transparent transparent rgba(50, 50, 50, 0.5);
border-style: solid;
border-radius: 3px;
border-width: 200px 0 200px 346px;
}
</pre>
<p>Tantek Çelik coined this technique in his <a href="http://tantek.com/CSS/Examples/polygons.html">study of regular polygons</a> which includes pentagons, hexagons and octagons. The methods are explained over at the <a href="http://www.filamentgroup.com/lab/image_free_css_tooltip_pointers_a_use_for_polygonal_css/">Filament Group</a>.</p>
<p>The 3D techniques I’ve used in this experiment are explained in my <a href="http://www.paulrhayes.com/2009-07/animated-css3-cube-interface-using-3d-transforms/">3D cube post</a> (July 2009). This is a proof of concept and I haven’t delved into the mathematics or geometry too much, instead opting for the slightly faster but significantly less clever and less reproducible trial-and-error approach.</p>
<pre>
#pyramid > div:first-child  {
-webkit-transform: rotateY(-19.5deg);
}

#pyramid > div:nth-child(2) {
-webkit-transform: rotateY(90deg) rotateZ(60deg);
}

#pyramid > div:nth-child(3) {
-webkit-transform: rotateX(60deg) rotateY(19.5deg);
}

#pyramid > div:nth-child(4) {
-webkit-transform: rotateX(-60deg) rotateY(19.5deg) translateX(-116px) translateY(-200px);
-webkit-transform-origin: 0 0 -326px;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2010-10/css-tetrahedron/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CSS 3D cube with touch gestures, click and drag</title>
		<link>http://www.paulrhayes.com/2010-09/3d-css-cube-ii-touch-gestures-click-and-drag/</link>
		<comments>http://www.paulrhayes.com/2010-09/3d-css-cube-ii-touch-gestures-click-and-drag/#comments</comments>
		<pubDate>Tue, 28 Sep 2010 22:20:49 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Experiments]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[cube]]></category>
		<category><![CDATA[perspective]]></category>
		<category><![CDATA[transformations]]></category>
		<category><![CDATA[transitions]]></category>
		<category><![CDATA[webkit]]></category>

		<guid isPermaLink="false">http://www.paulrhayes.com/?p=108</guid>
		<description><![CDATA[An updated 3D cube that comes with touch gestures and click ‘n’ drag.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.paulrhayes.com/experiments/cube-3d/touch.html">Experiment: 3D cube with touch gestures and click and drag</a></p>
<p><a href="http://www.paulrhayes.com/experiments/cube-3d/touch.html"><img src="http://host.trivialbeing.org/up/small/3d-cube-ii.png" alt="3D cube"></a></p>
<p>An update on the <a href="http://www.paulrhayes.com/2009-07/animated-css3-cube-interface-using-3d-transforms/">original 3D cube</a> (from July 2009 no less), I’ve added touch gesture support (iOS) and click-and-drag behaviour. Animation is incredibly smooth on the iPhone, even the 3G model. Arrow key presses will still rotate the cube, and ESC will reset it.</p>
<p>One year on and the cube still only works in Safari. Chrome, which says it supports <code>webkit-perspective</code> and <code>webkit-transform</code>, still renders differently. Firefox doesn’t support 3D transforms <i><a href="https://developer.mozilla.org/En/CSS/Using_CSS_transforms">yet</a></i>.</p>
<p>It works relatively simply: on click the start co-ordinates are saved and on drag the difference between current drag position and starting co-ordinates are applied to the cube as a transform, which is completed after the specified transition duration. Many thanks to <a href="http://remysharp.com">Remy Sharp</a> and his rubik’s experiment, which got me started with a lot of the basics.</p>
<h3>Touch tweaks</h3>
<p>Pixel values for touch positions are found in <code>event.originalEvent.touches[0].pageX</code>, instead of <code>event.pageX</code>. Using ‘start minus current’ pixel values led the cube to rotate more than intended on the iPhone. To correct, and for intuitive behaviour, the difference is reduced by a factor of four. </p>
<p>JavaScript prevents single touch default events — e.g. scrolling and text selection, but if it detects more than one touch (<code>event.originalEvent.touches.length</code>) the cube won’t rotate, so pinch and zoom will still work. This is a compromise.</p>
<p>A 200ms transition duration suits the browser, but on touch devices it felt sluggish, so I’ve upped it to 50ms so the cube is always at your finger-tips.</p>
<h3>Better CSS</h3>
<p>The cube is created exactly as before, but I’ve simplified the markup a little — dropping the <em>face</em> and <em>number</em> class names in favour of CSS3 selectors:</p>
<pre>
#cube > div:first-child  {
-webkit-transform: rotateX(90deg) translateZ(200px);
}

#cube > div:nth-child(2) {
-webkit-transform: translateZ(200px);
}

#cube > div:nth-child(3) {
-webkit-transform: rotateY(90deg) translateZ(200px);
text-align: center;
}

#cube > div:nth-child(4) {
-webkit-transform: rotateY(180deg) translateZ(200px);
}

#cube > div:nth-child(5) {
-webkit-transform: rotateY(-90deg) translateZ(200px);
}

#cube > div:nth-child(6) {
-webkit-transform: rotateX(-90deg) rotate(180deg) translateZ(200px) ;
}
</pre>
<h3>Any questions?</h3>
<p>This is quite a speedy write-up, if anything needs explaining I’m happy to go into a bit more detail.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2010-09/3d-css-cube-ii-touch-gestures-click-and-drag/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Animated CSS3 cube using 3D transforms</title>
		<link>http://www.paulrhayes.com/2009-07/animated-css3-cube-interface-using-3d-transforms/</link>
		<comments>http://www.paulrhayes.com/2009-07/animated-css3-cube-interface-using-3d-transforms/#comments</comments>
		<pubDate>Sat, 18 Jul 2009 01:16:54 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Experiments]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[perspective]]></category>
		<category><![CDATA[transformations]]></category>
		<category><![CDATA[transitions]]></category>
		<category><![CDATA[webkit]]></category>

		<guid isPermaLink="false">http://www.fofronline.com/?p=99</guid>
		<description><![CDATA[Position elements with 3D transforms to build a cube and use transitions to rotate on keypress.]]></description>
			<content:encoded><![CDATA[<p class="update"><strong>Update (28th Sept 2010)</strong>: Cube updated to work with touch gestures and click and drag — <a href="http://www.paulrhayes.com/2010-09/3d-css-cube-ii-touch-gestures-click-and-drag/">3D CSS cube II</a></p>
<p>Last week WebKit included the much anticipated (at least on my part) 3D transforms in its latest nightly build, announced practically alongside the awesome <a href="http://www.satine.org/research/webkit/snowleopard/snowstack.html">Snow Stack demo</a> that provides a 3D interface for browsing Flickr images (use left, right and space-bar). Today the <a href="http://webkit.org/blog/386/3d-transforms/">Surfin Safari blog</a> has updated with some more exciting demos, including “<em>Morphin Power Cubes</em>” and “<em>Poster Circle</em>”. It is now possible to create all sorts of crazy three-dimensional and animated user interfaces; the power comes largely in <code>-webkit-perspective</code> and a number of updated transforms–adapted to incorporate the Z axis.</p>
<p><span id="more-99"></span></p>
<p>Since working on the <a href="/2009-04/3d-cube-using-css-transformations/">3D cube using 2D transforms</a> back in April I’ve experimented with perspective to create something more powerful, playing around with 3D transforms on the iPhone a few times (e.g. this <a href="/experiments/perspective/">early rotating demo</a>). Now I’ve got something worth sharing.</p>
<p>A 3D cube can be created solely in CSS, with all six faces. Using JavaScript to detect key presses and update inline styles this cube can be intuitively navigated.</p>
<h3>Result</h3>
<p><a href="/experiments/cube-3d/index.html">A 3D cube that rotates using the Up, Down, Left and Right arrow keys.</a><br />
Supported browsers: WebKit Nightly r46042+</p>
<p class="center"><img src="http://host.trivialbeing.org/up/fofr-online-20090717-3d-cube.jpg" alt="3D cube interface using new WebKit transforms" /></p>
<h3>How To</h3>
<p>I’ll start with the markup, because it’s simple. Each of the six cube faces is given a face class and another relating to it’s number. These six faces sit within a cube container, which sits in another wrapper, each is necessary.</p>
<pre class='prettyprint'>&lt;div id=&quot;experiment&quot;&gt;
	&lt;div id=&quot;cube&quot;&gt;
		&lt;div class=&quot;face one&quot;&gt;
			One face
		&lt;/div&gt;
		&lt;div class=&quot;face two&quot;&gt;
			Up, down, left, right
		&lt;/div&gt;
		&lt;div class=&quot;face three&quot;&gt;
			Lorem ipsum.
		&lt;/div&gt;
		&lt;div class=&quot;face four&quot;&gt;
			New forms of navigation are fun.
		&lt;/div&gt;
		&lt;div class=&quot;face five&quot;&gt;
			Rotating 3D cube
		&lt;/div&gt;
		&lt;div class=&quot;face six&quot;&gt;
			More content
		&lt;/div&gt;
	&lt;/div&gt;
&lt;/div&gt;</pre>
<p>The outer wrapper serves as a camera, on which you apply some perspective — appropriate 3D transformations are then applied to descendants. <code>-webkit-perspective</code> defines the depth of the Z-plane and relative sizes of elements above and below it, <code>-webkit-perspective-origin</code> specifies the perspective’s origin. <a href="http://webkit.org/blog-files/3d-transforms/perspective-by-example.html">View a perspective example (webkit.org)</a></p>
<pre class='prettyprint'>
    #experiment {
      -webkit-perspective: 800;
      -webkit-perspective-origin: 50% 200px;
    }
</pre>
<p>The second container, the actual cube, has a specified height, margin, position, etc. as usual. The height and width are necessary to create some confines for the cube face transformations — alternatively the width defaults to 100% and the cube’s appearance would vary with window width. <code>-webkit-transition</code> (<a href="http://www.w3.org/TR/css3-transitions/">documentation</a>) defines the animated property, duration and timing-function — we’re animating the 3d transformation (via <code>-webkit-transform</code>) linearly for two seconds. <code>-webkit-transform-style</code> determines whether child elements lie flat against their parent (“flat”) or remain in 3D space (“preserve-3d”).</p>
<pre class='prettyprint'>
    #cube {
      position: relative;
      margin: 0 auto;
      height: 400px;
      width: 400px;
      -webkit-transition: -webkit-transform 2s linear;
      -webkit-transform-style: preserve-3d;
    }
</pre>
<p>Using the <code>.face</code> class common styles are applied to the six sides; coloring, size, padding, etc. Importantly they are each positioned absolutely, relative to the cube container. The background rgba property is included to make the cube look pretty and transparent.</p>
<pre class='prettyprint'>
    .face {
      position: absolute;
      height: 360px;
      width: 360px;
      padding: 20px;
      background-color: rgba(50, 50, 50, 0.7);
    }
</pre>
<p>Each of the faces, one through six, needs to be rotated in 3D space to its correct starting position. Using <code>translateZ</code> the elements are brought 200px (half their width) off the Z-plane. Each of the faces must be at 90 degrees. Rotating solely in the X plane positions the top and bottom faces (one, six), before rotating the last four faces in the Y plane, much like origami. The extra rotate on the sixth face rotates the content in 2D space to correct its orientation.</p>
<pre class='prettyprint'>
    #cube .one  {
      -webkit-transform: rotateX(90deg) translateZ(200px);
    }

    #cube .two {
      -webkit-transform: translateZ(200px);
    }

    #cube .three {
      -webkit-transform: rotateY(90deg) translateZ(200px);
    }

    #cube .four {
      -webkit-transform: rotateY(180deg) translateZ(200px);
    }

    #cube .five {
      -webkit-transform: rotateY(-90deg) translateZ(200px);
    }

    #cube .six {
      -webkit-transform: rotateX(-90deg) translateZ(200px) rotate(180deg);
    }
</pre>
<p>Our cube is now complete — but it doesn’t move! With a keydown event listener we can increment X and Y angles based on different key presses, before applying them as inline styles on the cube container. In combination with the transition effect on #cube, all six faces rotate in sync from their original position to the newly defined angle, creating a seamless 3D cube interface.</p>
<pre class='prettyprint'>
  	var xAngle = 0, yAngle = 0;
	document.addEventListener('keydown', function(e)
	{
		switch(e.keyCode)
		{

			case 37: // left
				yAngle -= 90;
				break;

			case 38: // up
				xAngle += 90;
				break;

			case 39: // right
				yAngle += 90;
				break;

			case 40: // down
				xAngle -= 90;
				break;
		};

		$('cube').style.webkitTransform = "rotateX("+xAngle+"deg) rotateY("+yAngle+"deg)";
	}, false);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2009-07/animated-css3-cube-interface-using-3d-transforms/feed/</wfw:commentRss>
		<slash:comments>74</slash:comments>
		</item>
		<item>
		<title>3D Cube using 2D CSS transformations</title>
		<link>http://www.paulrhayes.com/2009-04/3d-cube-using-css-transformations/</link>
		<comments>http://www.paulrhayes.com/2009-04/3d-cube-using-css-transformations/#comments</comments>
		<pubDate>Thu, 30 Apr 2009 23:54:28 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Experiments]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[cube]]></category>
		<category><![CDATA[transformations]]></category>
		<category><![CDATA[transitions]]></category>

		<guid isPermaLink="false">http://www.fofronline.com/?p=67</guid>
		<description><![CDATA[Emulate 3D using 2D transforms to create a cube-like illusion.]]></description>
			<content:encoded><![CDATA[<p><strong>Update (July 21st):</strong> Using newly released (currently only in Webkit Nightly releases) 3D transforms, a three dimensional, rotating cube with correct perspective is possible, and as a bonus–the cube can be navigated using arrow keys. Check out the latest demo, “<a href="/2009-07/animated-css3-cube-interface-using-3d-transforms/">Animated CSS3 cube using 3D transforms</a>”.</p>
<p>The impression of a three dimensional cube can be created using modern CSS techniques, without the need for JavaScript, imagery, canvas or SVG. Using the proprietary transform property to skew and rotate shaded rectangles, individual cube faces can combine to form a 3D object. Currently only supported in recent WebKit and Gecko based browsers, most importantly Firefox 3.5+ <code>-moz-transform</code> (<a href="https://developer.mozilla.org/En/CSS/CSS_transform_functions">documentation</a>) and Safari 3.2+ <code>-webkit-transform</code> (<a href="http://webkit.org/specs/CSSVisualEffects/CSSTransforms.html">documentation</a>).<br />
<span id="more-67"></span></p>
<p>To demonstrate the power of this effect a second experiment with multiple cubes and proprietary WebKit transitions is also available.</p>
<h3>Results</h3>
<p><a href="/experiments/cube/index.html">A 3D cube created with CSS</a><br />
<strong>Update (June 7th):</strong> Altered CSS slightly to use skew(x,y) rather than skewY, the latter of which is not supported in Safari 3 / Chrome.<br />
Supported browsers: Safari 3.2+, Google Chrome, Firefox 3.5+</p>
<p><a href="/experiments/cube/multiCubes.html">Experiment with multiple cubes and CSS transitions, still no JavaScript</a><br />
Supported browsers: Safari 4+, Google Chrome</p>
<p class="center"><a href="http://host.trivialbeing.org/up/multiple-cubes-css.png"><img src="http://host.trivialbeing.org/up/small/multiple-cubes-css.png" alt="Multiple cubes created using CSS" /></a></p>
<h3>How To</h3>
<p>Similar to my previous experiments, the HTML markup is very simple. Each of the faces has its own DIV, class and content. The top face requires some extra markup to aid the transformation, more on that shortly.</p>
<pre class="prettyprint">
&lt;div class=&quot;cube&quot;&gt;
	&lt;div class=&quot;topFace&quot;&gt;
		&lt;div&gt;
			Content
		&lt;/div&gt;
	&lt;/div&gt;
	&lt;div class=&quot;leftFace&quot;&gt;
		Content
	&lt;/div&gt;
	&lt;div class=&quot;rightFace&quot;&gt;
		Content
	&lt;/div&gt;
&lt;/div&gt;
</pre>
<p>A short disclaimer, the geometry in this example is ‘fudged’, in that the values have been adjusted to appear roughly correct. I know that the dimensions are slightly out of whack, this is merely to save my head from mathematics and to get the concept out there quickly for people to see. With that said, let’s crack on with the CSS.</p>
<p>Each of the three rectangles is given a slightly different shade of gray to give the impression of depth, in this example the left face is in shadow. The faces are each positioned absolutely, relative to the cube container. Each face is 200 x 200 pixels, including 10 pixels of padding.</p>
<pre class="prettyprint">
.cube {
	position: relative;
	top: 200px;
}

.rightFace,
.leftFace,
.topFace div {
	padding: 10px;
	width: 180px;
	height: 180px;
}

.rightFace,
.leftFace,
.topFace {
	position: absolute;
}
</pre>
<p>Now for the fun bit. The left and right rectangles are skewed by ±30˚ along the vertical axis, with the right face shifted left by 200px, cleanly lining up the two edges to create a corner that is center aligned.</p>
<pre class='prettyprint'>
.leftFace {
	-webkit-transform: skewY(30deg);
	-moz-transform: skewY(30deg);
	background-color: #ccc;
}

.rightFace {
	-webkit-transform: skewY(-30deg);
	-moz-transform: skewY(-30deg);
	background-color: #ddd;
	left: 200px;
}
</pre>
<p>The top face proves more problematic; it needs to be skewed, scaled, rotated and positioned. The skew is the same, –30˚ along the vertical axis, this skewed rectangle must then be rotated clockwise by 60˚. Rotating the rectangle itself leads to a change in orientation of its content, a container must be added and then rotated.</p>
<p>A simple way of creating a top face without resorting to maths is to duplicate the left and right rectangles, skew them in the opposite directions (by inverting the sign, e.g. left face is now skewed by –30˚) and position them against the existing faces to create a diamond shape between the two sets. Now use positioning and scaling to fill this diamond and form the top face, deleting the duplicates when finished. My results led to a scaling factor of 1.16 in the Y direction which I have accounted for by reducing the font-size by the same factor.</p>
<pre class='prettyprint'>
.topFace div {
	-webkit-transform: skewY(-30deg) scaleY(1.16);
	-moz-transform: skewY(-30deg) scaleY(1.16);
	background-color: #eee;
	font-size: 0.862em;
}

.topFace {
	-webkit-transform: rotate(60deg);
	-moz-transform: rotate(60deg);
	top: -158px;
	left: 100px;
}
</pre>
<p>The final CSS looks like this:</p>
<pre class='prettyprint'>
.cube {
	position: relative;
	top: 200px;
}

.rightFace,
.leftFace,
.topFace div {
	padding: 10px;
	width: 180px;
	height: 180px;
}

.rightFace,
.leftFace,
.topFace {
	position: absolute;
}

.leftFace {
	-webkit-transform: skewY(30deg);
	-moz-transform: skewY(30deg);
	background-color: #ccc;
}

.rightFace {
	-webkit-transform: skewY(-30deg);
	-moz-transform: skewY(-30deg);
	background-color: #ddd;
	left: 200px;
}

.topFace div {
	-webkit-transform: skewY(-30deg) scaleY(1.16);
	-moz-transform: skewY(-30deg) scaleY(1.16);
	background-color: #eee;
	font-size: 0.862em;
}

.topFace {
	-webkit-transform: rotate(60deg);
	-moz-transform: rotate(60deg);
	top: -158px;
	left: 100px;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2009-04/3d-cube-using-css-transformations/feed/</wfw:commentRss>
		<slash:comments>58</slash:comments>
		</item>
		<item>
		<title>An analogue clock using only CSS</title>
		<link>http://www.paulrhayes.com/2009-03/an-analogue-clock-using-only-css/</link>
		<comments>http://www.paulrhayes.com/2009-03/an-analogue-clock-using-only-css/#comments</comments>
		<pubDate>Wed, 25 Mar 2009 01:16:44 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Experiments]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[transformations]]></category>
		<category><![CDATA[transitions]]></category>
		<category><![CDATA[webkit]]></category>

		<guid isPermaLink="false">http://www.fofronline.com/?p=23</guid>
		<description><![CDATA[Use CSS transitions and transforms to rotate clock hands.]]></description>
			<content:encoded><![CDATA[<p>Having read the blurb around <a href="http://webkit.org/blog/138/css-animation/">Safari’s CSS transitions</a> I opted to familiarize myself with a quick project — the aim of which was to create a functional, CSS only, analogue clock.<br />
<span id="more-23"></span></p>
<h3>Result</h3>
<p><a href="/experiments/clock/#clock">Experiment: CSS Analogue Clock</a><br />
Experiment works in Safari 4 Beta and Google Chrome. A working clock that optionally resorts to JavaScript to grab the current time (can be achieved by other means).</p>
<h3>How To</h3>
<p>Before getting into the nitty gritty I created four images, a clock face and three transparent PNG hands (seconds, minutes and hours), ensuring that each of these were the same size so that when overlayed their centres would align. The HTML and CSS to get us going is as follows:</p>
<pre class='prettyprint'>
&lt;div id=&quot;clock&quot;&gt;
	&lt;div id=&quot;hour&quot;&gt;&lt;img src=&quot;images/hourHand.png&quot; /&gt;&lt;/div&gt;
	&lt;div id=&quot;minute&quot;&gt;&lt;img src=&quot;images/minuteHand.png&quot; /&gt;&lt;/div&gt;
	&lt;div id=&quot;second&quot;&gt;&lt;img src=&quot;images/secondHand.png&quot; /&gt;&lt;/div&gt;
&lt;/div&gt;
</pre>
<pre class='prettyprint'>
#clock {
position: relative;
width: 378px;
height: 378px;
background-image: url('../images/clockFace.png');
left: 50%;
margin: 5em 0 0 -189px;
}

#clock div {
position: absolute;
}
</pre>
<p>The magic that rotates the clock’s hands comes via two WebKit specific CSS properties, <code class='prettyprint'>-webkit-transition</code> (<a href="http://webkit.org/specs/CSSVisualEffects/CSSTransitions.html">documentation</a>) and <code class='prettyprint'>-webkit-transform</code> (<a href="http://webkit.org/specs/CSSVisualEffects/CSSTransforms.html">documentation</a>). The transform property can alter the appearance of an element via a two dimensional transformation, for instance: scaling, rotating and skewing a DIV element. In this case it is used to rotate the clock hands to the correct angles; the CSS below puts the hour hand at 3 o’clock:</p>
<pre class='prettyprint'>
#clock img[src*='hour'] {
-webkit-transform: rotate(90deg);
}
</pre>
<p>The transition property creates an animation of a specified property between two values when triggered, for instance fading the opacity on a DIV element from 1 to 0 — triggered using the :hover pseudo class. Transition duration and the transition timing function (e.g. linear) should also be set, amongst other optional properties. In this example the transition is from one transformation angle to another with durations that match the appropriate clock hand, so the second hand takes 60 seconds to complete a 360 degree rotation. The transition is triggered using the :target pseudo element — if the URI contains the ‘clock’ fragment then the time piece shall start ticking.</p>
<pre class='prettyprint'>
#clock img[src*='second'] {
/* -webkit-transition: property duration timing-function */
-webkit-transition: -webkit-transform 60s linear;
}

#clock:target img[src*='second'] {
-webkit-transform: rotate(360deg);
}
</pre>
<p>The above transition lasts only one rotation but by altering the duration length and degree of rotation in accordance the second hand can keep on going (e.g. 600 seconds and 3600 degrees rotation gives a battery life of 10 minutes), a fairly safe assumption that users will not stay on the page for too long.</p>
<pre class='prettyprint'>
#clock img[src*='second'] {
-webkit-transition: -webkit-transform 600000s linear;
}

#clock:target img[src*='second'] {
-webkit-transform: rotate(3600000deg);
}

#clock img[src*='minute'] {
-webkit-transition: -webkit-transform 360000s linear;
}

#clock:target img[src*='minute'] {
-webkit-transform: rotate(36000deg);
}
</pre>
<h3>Grab the current time</h3>
<p>Although the animation works beautifully, CSS alone is not capable of obtaining the current time. To start the clock at the correct time a dynamic transformation needs to be applied to the clock hand containers, this is  easiest done with inline styles and can be set in any number of ways by the backend when the page loads, thereby eradicating any need for JavaScript.</p>
<p>Alternatively, if you’ve no objections to using JavaScript, I’ve created a small <code class='prettyprint'>startClock()</code> function to do the job (<em>albeit using Prototype 1.6.0.3 for my own convenience</em>):</p>
<pre class='prettyprint'>
function startClock() {
	var angle = 360/60;
	var date = new Date();
	var hour = date.getHours();
	if(hour > 12) {
		hour = hour - 12;
	}
	var minute = date.getMinutes();
	var second = date.getSeconds();
	var hourAngle = (360/12)*hour + (360/(12*60))*minute;
	$('minute').setStyle('-webkit-transform: rotate('+angle*minute+'deg)');
	$('second').setStyle('-webkit-transform: rotate('+angle*second+'deg)');
	$('hour').setStyle('-webkit-transform: rotate('+hourAngle+'deg)');
}
</pre>
<p>A word of warning — applying the inline style directly to the image will override the transition effects defined in the CSS file.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2009-03/an-analogue-clock-using-only-css/feed/</wfw:commentRss>
		<slash:comments>51</slash:comments>
		</item>
	</channel>
</rss>

