Welcome to Google

I work at Google.

Over the last 5 weeks, I’ve transitioned into a whole new world. I’ve always been on the outskirts, used the tools, apps, search and everything else. I still remember how I first heard about Google. He described to me as a “Website where you can type things in and it’ll find it for you.” (Brian, I’m looking at you) over 10 years ago. I still remember writing down “www.google.com” on a little scrap of paper, never knowing that someday I’d actually be working for that then little company.

It’s intimidating. Going from a great little company of around 20 people, to a global tech company whose name has become a verb in the english language because of how engrained into our culture this company has become. I’m looking forward the challenge. A whole new set of language, tools, and platforms. It’s so much to learn and take in. At times it feels like trying to drink from a firehose with the sheer quantity of information that is just thrown your way. It’s the kind of challenge I enjoy, and hopefully, will excel at.

As I sit on the GBus with WiFi writing this post and headed for the set of buildings collectively known as the Googleplex, I feel like I’m back in school. It’s incredible to think back on where I’ve been, the things that have happened to get me too this point, and on all the possibilities that the future holds.

Let the adventures continue.

Farewell InterKnowlogy, thanks for all the fish

As some of you may know, this last Friday (August 3rd) was my last day at InterKnowlogy. It has been a fantastic experience working with and being there for the past 3.33 years (1215 days to be exact). But, like all good things, there comes a time a better opportunity comes along that you just can’t resist. If you don’t know already, you’ll hear about it shortly.

I’ve been extremely fortunate to have started my career at InterKnowlogy. It has been incredible to work with people of that caliber, people who are not just technical, but people who genuinely care about the work they do and the people around them. I’ve been invested in and mentored during my time there and it’s to all of them that I owe the experience and skills that I have today. I know that these experiences will continue to shape me throughout my career. So to all of you who who are reading this that have helped me along the way: Thank you!

My best wishes and continued success to InterKnowlogy and all the people that work there,

You rock,

Paul

CSS 3D Clouds Retake

This post is going to cover my experience following through the tutorial on making CSS 3D clouds posted here: http://www.clicktorelease.com/tutorials/css3dclouds/. I didn’t make the original code, but I did run into several issues while I went through and I wanted to share my experience, work-arounds, and pieces of code that were missing from the original tutorial.

All the questions that came up and fixes changes here were done on the Chrome Beta (v20.0.1132.41 beta-m to be exact)

1. Creating the world and a camera

CSS 3D Clouds Step 1

In this step, you create two div’s in the body of your HTML 5 page, the outer <div> gets an id of viewport and the inner <div> gets an id of world. From there you setup some structural styling (viewport spans entire screen via absolute positioning, world is centered in the middle)

Initial Page Setup

Some initial styling needs to be done to make it look like the demo, here’s what I have:

  1. * {
  2. box-sizing: border-box;
  3. margin: 0;
  4. padding: 0;
  5. }
  6.  
  7. body {
  8. overflow: hidden;
  9. }
  10.  
  11. #viewport {
  12. background-image: linear-gradient(bottom, rgb(69, 132, 180) 28%, rgb( 31, 71, 120 ) 64%);
  13. background-image: -o-linear-gradient(bottom, rgb(69, 132, 180) 28%, rgb( 31, 71, 120 ) 64%);
  14. background-image: -moz-linear-gradient(bottom, rgb(69, 132, 180) 28%, rgb( 31, 71, 120 ) 64%);
  15. background-image: -webkit-linear-gradient(bottom, rgb(69, 132, 180) 28%, rgb( 31, 71, 120 ) 64%);
  16. background-image: -ms-linear-gradient(bottom, rgb(69, 132, 180) 28%, rgb( 31, 71, 120 ) 64%);
  17. }
  18.  
  19. #world {
  20. background-color: rgba(255, 0, 0, .2);
  21. }

Vendor prefixes

I’m so used to Chrome being the “latest and greatest” that I honestly expected to be able to use non-prefixed CSS properties and have the code “just work”. That’s NOT the case. As of this writing you will need to use prefixed properties, so add the following prefixes into the appropriate rules:

  1. #viewport {
  2. perspective: 400;
  3. -webkit-perspective: 400;
  4. -moz-perspective: 400;
  5. -o-perspective: 400;
  6. }
  7.  
  8. #world {
  9. transform-style: preserve-3d;
  10. -webkit-transform-style: preserve-3d;
  11. -moz-transform-style: preserve-3d;
  12. -o-transform-style: preserve-3d;
  13. }

Help, my javascript code doesn’t work!

You probably put your javascript in the <head> tag, which means that

  1. document.getElementById( 'world' )

will not work because the elements don’t exist yet. Put the script at the end right before the </body> tag and it should work if everything else is correct.

Besides, it’s just good practice to put your javascript last.

Help, my javascript code doesn’t work! (pt 2)

This just shows my ignorance of javascript, but if something still isn’t working, you might have this problem:

Javascript uses the \ character in your strings to tell the parser to treat the next line as if the string continued:

  1. 'translateZ( ' + d + 'px ) \
  2. rotateX( ' + worldXAngle + 'deg) \
  3. rotateY( ' + worldYAngle + 'deg)';

Is the same as:

  1. 'translateZ( ' + d + 'px ) rotateX( ' + worldXAngle + 'deg) rotateY( ' + worldYAngle + 'deg)';

Zooming javascript

The code samples in the original tutorial omit the code to zoom in and out with the mouse wheel. Here it is in all it’s javascripty wonderfulness:

  1. window.addEventListener( 'mousewheel', onContainerMouseWheel );
  2. window.addEventListener( 'DOMMouseScroll', onContainerMouseWheel );
  3.  
  4. function onContainerMouseWheel( event ) {
  5. event = event ? event : window.event;
  6. d = d - (event.detail ? event.detail * -5 : event.wheelDelta / 8);
  7. updateView();
  8. }

2. Adding objects to our world

CSS 3D Clouds Step 2
E.g. .cloudBase.

Create cloud base code is incorrect

Instead of:

  1. for( var j = 0; j <<; 5; j++ ) {

the correct line is:

  1. for( var j = 0; j < 5; j++ ) {

Actual random numbers and prefixed transforms

The random numbers for createCloud():

  1. var random_x = 256 - ( Math.random() * 512 );
  2. var random_y = 256 - ( Math.random() * 512 );
  3. var random_z = 256 - ( Math.random() * 512 );

The transform styles for createCloud()

  1. div.style.transform = t;
  2. div.style.webkitTransform = t;
  3. div.style.MozTransform = t;
  4. div.style.oTransform = t;

3. Adding layers to our objects

CSS 3D Clouds Step 3
There were a couple of things in this section that cause me to scratch my head and go whyyyyy?

Code for random generation and transforms.

Random variables:

  1. var random_x = 256 - ( Math.random() * 512 );
  2. var random_y = 256 - ( Math.random() * 512 );
  3. var random_z = 100 - ( Math.random() * 200 );
  4. var random_a = Math.random() * 360;
  5. var random_s = .25 + Math.random();
  6. random_x *= .2; random_y *= .2;

Vendor transforms:

  1. cloud.style.transform = t;
  2. cloud.style.webkitTransform = t;
  3. cloud.style.MozTransform = t;
  4. cloud.style.oTransform = t;

Why don’t I see the new squares?

You have to add in the style for .cloudLayer into your CSS:

  1. .cloudLayer {
  2. position: absolute;
  3. left: 50%;
  4. top: 50%;
  5. width: 256px;
  6. height: 256px;
  7. margin-left: -128px;
  8. margin-top: -128px;
  9. background-color: rgba( 0, 255, 255, .1 );
  10. -webkit-transition: opacity .5s ease-out;
  11. -moz-transition: opacity .5s ease-out;
  12. -o-transition: opacity .5s ease-out;
  13. }

I see the cloud layers, but why are they are all flat?

Yeah, this got me too, the parent div’s need to have preserve-3d, so add this into your CSS:

  1. #world div {
  2. transform-style: preserve-3d;
  3. -webkit-transform-style: preserve-3d;
  4. -moz-transform-style: preserve-3d;
  5. -o-transform-style: preserve-3d;
  6. }

4. Making the 3D effect work

CSS 3D Clouds Step 4

This section is essentially “make the layers point at the camera”. You still want them projected into the same locations, but you want them to always face the camera, giving you that sense of “volume” effect.

Vendor Transforms and Update()

First, here’s all the vendor transforms:

  1. layer.style.transform = t;
  2. layer.style.webkitTransform = t;
  3. layer.style.MozTransform = t;
  4. layer.style.oTransform = t;

Now, you also need to call this update manually once right before the end of your script. So right before the closing script tag, make sure you call this:

  1. update();

Render Loop

Finally, even if you do this, you’ll notice that your layers still don’t point at the camera. You need to add in a function that loops and updates the layers in the #viewport at regular intervals. You could add a call to the update function inside your mouse move event, but we’ll need the loop to get the rotation to work in the next step, so it’s better if you just do this now.

  1. (function() {
  2. var lastTime = 0;
  3. var vendors = ['ms', 'moz', 'webkit', 'o'];
  4. for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
  5. window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
  6. window.cancelRequestAnimationFrame = window[vendors[x]+
  7. 'CancelRequestAnimationFrame'];
  8. }
  9.  
  10. if (!window.requestAnimationFrame)
  11. window.requestAnimationFrame = function(callback, element) {
  12. var currTime = new Date().getTime();
  13. var timeToCall = Math.max(0, 16 - (currTime - lastTime));
  14. var id = window.setTimeout(function() { callback(currTime + timeToCall); },
  15. timeToCall);
  16. lastTime = currTime + timeToCall;
  17. return id;
  18. };
  19.  
  20. if (!window.cancelAnimationFrame)
  21. window.cancelAnimationFrame = function(id) {
  22. clearTimeout(id);
  23. };
  24. }())

Lets break this down. I discovered that this function is a polyfill for the browser animation spec here one Paul Irish’s awesome blog http://paulirish.com/2011/requestanimationframe-for-smart-animating/. Previously, when you would animate something, you would set a timer, and every few milliseconds go and update move something from point A to point B on the screen with a small increment. In order to get smoother animations, the browsers are starting to support this requestAnimationFrame function that allows several changes to be made, and update everything with a single reflow / redraw of the screen. This becomes especially handy when you are updating multiple elements on the screen and you want a clean responsive display. It also means that the browser can stop animating when you switch tabs, which means that you don’t eat up battery when someone isn’t looking at your page :)

All you really need to know is that this creates a function on the javascript window object that tells the browser to “please render an animation frame, and call back to this function when you are done and ready to render the next frame”.

5. Final words

CSS 3D Clouds Step 5

Subtle Rotating

Not mentioned, but if you want the clouds to slowly rotate like the demo, you need to add in the rotate z component into the transform update of your layers like so:

  1. 'rotateZ( ' + layer.data.a + 'deg ) /

And, you need to add in a speed property into your cloud layers when you create them:

  1. speed: .2 * Math.random() - .1

Adding Cloud Images

Instead of this:

  1. var cloud = document.createElement( 'div' );

Use this (or find your own cloud .png, it should be transparent to work properly)

  1. var cloud = document.createElement( 'img' );
  2. cloud.style.opacity = 0;
  3. var src = 'http://www.clicktorelease.com/tutorials/css3dclouds/cloud.png';
  4. ( function( img ) {
  5. img.addEventListener( 'load', function() {
  6. img.style.opacity = .8;
  7. } )
  8. } )( cloud );
  9. cloud.setAttribute( 'src', src );

And finally to remove all the debug styles remove the following lines out of your CSS:

From #world remove:

  1. background-color: rgba(255, 0, 0, .2);

From .cloudBase remove:

  1. background-color: rgba( 255, 0, 255, .5 );

From .cloudLayer remove:

  1. background-color: rgba( 0, 255, 255, .1 );

That should cover it! Now go make some happy clouds.

Credits

Everything here was completely taken from the Click To Release CSS 3D Clouds tutorial and expanded to include the missing parts.

Releasing: Comatose WordPress Theme

This has been in the pipe a long time, it started simply as a set of experiments playing with HTML 5, layouts, responsive design, page structure, typeography, displaying images on mobile screens, the mobile web, minimalism, and my own dislike with the previous design(s) of my site. Finally, I decided to turn it into a full fledged WordPress theme. This is the result. It powers my site, and the InterKnowlogy development blogs where I work.

So here is the low down:

  • HTML 5 layout with CSS 3 styling
  • Responsive Layout
  • Clean, minimalist design
  • Print style
  • Clean, readable, and consistent text styling.
  • Clean and readable typography.
  • Clean display of code.
  • Beautiful images
  • Images display at native resolution on Regular and High Density screens
  • Widget enabled sidebar support
  • Nested comment support
  • Gravatar image integration for comments (High resolution images for High Density screens)
  • Custom menu support
  • Nested sub-sub-sub menu support
  • Graceful degradation in older browsers

But don’t take my word for it. Download links, versions and release notes are all on the project page:
http://www.paulrohde.com/development/comatose/

And all of the source code is hosted on GitHub.

Desktop Screenshots

Comatose Windows with Chrome showing Sidebar

iPad Retina Screenshots

Menu

Comatose iPad Retina Menu

See more screenshots