I Love Moo

I'm a bit of a sucker when it comes to Valentine's Day and so on Feb 14th 2016 I Love Moo was uploaded and shared.

Tool kit

After spending quite some time playing around with three.js and in particular attempting to create 3D models without 3D modelling software, I ended up with a sort of square looking cow which soon became a much more interesting project.

View Project

The principle method for creating simple 3D models from scratch is to build them up from a series of simple boxes, I had a little "new bit" function that looks like this:

App.utils.newBit = function(parent, name, opts) { App.utils.el = new THREE.Mesh(opts.type, opts.style); App.utils.el.position.x = opts.x; App.utils.el.position.y = opts.y; App.utils.el.position.z = opts.z; App.three[parent].threegroup.add(App.utils.el); }

And passed into it something like this:

App.utils.newBit(type, "body", { type: App.utils.baseGeom, style: App.bovine.config[type].baseColour, x: 0, y: 0, z: 0, scaleX: 5, scaleY: 5, scaleZ: 10 });

Which resulted in the ability to make 3D models all from simple boxes.


And so after a bit of tinkering I was confident I could create models, characters and entire scenes... all from simple boxes!

On Valentine's Day 2016 an email was sent out to the Super natural mailing list with a link to my little experiment and with a bit of help from creative John Kelley who came up with the name "I Love Moo", I had a rather cute little Valentine's treat.

The project wasn't without complications, however. A lot of three.js experiments that use "orbit controls" (the ability to navigate the scene using the mouse) run with the canvas set to 100%, meaning when viewing on device there is no need to scroll the web page. This culminates in a full screen experience that when interacted with on desktop or device allows the user the ability to look around and experience the models in their full 3D glory.


Since I Love Moo also housed a number of other standard HTML elements (the poem at the top, the shareables at the bottom) meant I couldn't set the canvas to 100%. Because I needed to maintain the "touch and scroll" functionality for users on device, this meant I needed to come up with another way of allowing the user to experience the scene but without touching the screen.

The answer, of course...orientation controls or, more specifically...compass heading.

There's a lovely method detailed on w3c for determining the compass heading of the device with a snippet of the Javascript translation. It was this that was used to control the three.js scene when users visited on device instead of the mouse enabled "orbit controls".

On page load I called the "checkSupport" function that uses Modernizr detection features to determine if the user was on device or desktop and if webGL is supported,

App.checkSupport = function(){ var touch = Modernizr.touchevents; var webgl = Modernizr.webgl; var devicemotion = Modernizr.devicemotion; var deviceorientation = Modernizr.deviceorientation; if (touch && webgl && devicemotion && deviceorientation){ return "mobile"; } else if (webgl){ return "desktop"; } else { return "backup"; } };

The result can be seen in the form of a message stating "Since you're on (device or desktop)..." This meant no matter how you were visiting the site you were always guaranteed a working experience, or in the case of non webGL enabled browsers, a message explaining you really should update your browser.

I wrote a blog post which explains a bit more about the project.


If you'd like to know more all the source code is available on my GitHub