WebGL: Christmas Cubes

Cubes in a twisted spiral to make a lovely Christmas tree, with baubles and lights.

The cubes are merged in to a single mesh to speed things along a little, and lit by an ambient light source. If lights are selected then they’re added as basic spheres with red or green point lights in the same positions. Baubles are just shiny red spheres.

This demo also includes dat.gui to control a few things.

Drawing To Chrome's Console

In Chrome (and other browser’s) you can style a console.log message by using a sprintf annotation - %c at the beginning of the log message and a second argument of a CSS style, eg;

1
console.log("%cThis message will appear in blue.", "color:blue");

Using this idea and a canvas tag to read the colours of pixels in an image, we can use Chrome’s console as a target to draw on.

Canvas Interference Circles

HTML5 canvases have a fun global setting called globalCompositeOperation - it’s determines how pixels on the canvas are rendered when they’re overwritten by a new operation. In effect they’re the same sort of thing as Photoshop’s layer modes.

In this script white concentric circles are draw on top of each other when the canvas is set to ‘difference’ so a white + white = black, giving a stripe effect. Two of these circle effects are then rotated around each other giving rise to a cool psychadelic demo.

WebGL: Cube Ocean

An ocean of cubes cycling up and down to a sin wave.

Cube Ocean demonstrates creating and reusing a geometry in THREE.js. With THREE.js you have a few options to create geometries, either building them individually, cloning them from objects, or creating and copying them. What you shoud use depends entirely on the use case for what you’re writing.

In this example a simple BoxGeometry is stored in a variable and used as the geometry for creating an array of 400 cubes that move cyclically up and down following a sinusoidal curve in two dimensions - creating a simple “ocean wave” effect.

WebGL: d12

A dice model created in Blender and exported as a Collada model, imported in to THREE.js.

Creating a model in Blender is relatively straightforward, but exporting it in a model format that THREE.js can use is less so. While there is an ‘official’ THREE.js JSON format it seems to be broken in the Blender export plugin. Consequently it’s easier to use the WaveFront Collada format. What settings you should use is a matter of experimentation as the different features of a model seem to greatly affect how well it loads in THREE.js.

WebGL: Rotating block sphere

An array of cubes arranged in concentric rings and oriented to a central point, then rotated in opposing directions.

There’s more to do here - there are a lot of redundant faces that aren’t really used.

Viewing Console Messages on Mobile

Debugging on mobile devices without access to ADB or Xcode is a pain. This script injects a div in to the page and routes console messages to it.

For more information see the Github repo at https://github.com/onion2k/console.js

Regular Polygons in Rune.js

Rune.js is a useful SVG library, but it lacks functions to draw regular shapes.

1
2
3
4
function polyong() {
return false;
}
`

Detecting WebGL

While WebGL is available in most modern browsers there is still a requirement to check whether it’s available for users on older versions. Unfortunately it’s not simply a case of checking if the API is available as some browsers report is as being there even when it’s not available.

1
2
3
4
5
6
7
8
var detectWebGl = function() {
try {
return (!!window.WebGLRenderingContext &&
!!document.createElement('canvas').getContext('experimental-webgl'));
} catch(e) {
return false;
}
}

Copy CSS Path

One of the most useful aspects of Chrome’s dev tools is the ‘Copy CSS Path’ option available in the context menu. With a selected element it looks up the DOM tree and generators a selector for each level until it has a unique reference to that specific element.

One problem with Chrome though is that this function is only available from the context menu; it’s not available from either the console or in the page context.

This code replicates the function so you can use it in a script.

1
2
3
function copyCssPath(<element>){
return path;
}