Denis Potschien May 8th, 2016

3D Within the Browser: Seen.js Creates Complex Graphics and Animations for Canvas and SVG

HTML5 and JavaScript provide all functions needed to create complex graphics and animations within the browser. For that purpose, the JavaScript library "seen.js" offers a broad array of options to build complex 3D worlds in the browser. "seen.js" is independent of jQuery or other libraries and constructs impressive 3D objects and sceneries on the basis of HTML5 Canvas and SVG. 3D within the browser, without any plugins...

Turn Simple Surfaces Into Complex Sceneries With Seen.js

Getting started with "seen.js" is not exactly easy, that's due how versatile the library is. In return, the options are much more impressive. Let's start at the beginning: first, the JavaScript library has to be integrated. Although "seen.js" works without any other dependencies, CoffeeScript should be incorporated as well. That's because the complete "seen.js" documentation and all examples are based on CoffeeScript. In the following, we'll create a canvas, meaning a "<canvas>" or "<svg>" element. After that, we'll bring it to live via CoffeeScript.
<canvas width="640" height"425" id="seenjs"></canvas>

<script type="text/coffeescript">
…
</script>
In the script above, we set up a canvas element which is supposed to be used as the drawing area for "seen.js." The base for 3D objects are the so-called "shapes". These shapes can be defined regarding size, color, and form. Aside from the development of custom shapes, "seen.js" also offers simple, predefined shapes. This way, spheres, and tetrahedrons can be used, among other shapes.
sphere = seen.Shapes.sphere(1).scale(100)
In the example, a simple sphere that consists of multiple triangular shapes is defined via "Shapes.sphere()". The number within the method determines how complex you want the sphere to be. The larger the number, the large the number of displayed shapes. The sphere's size is defined via "scale()". The value "1" is the smallest possible size. seenjs_sphere Two spheres with different amounts of shapes In the next step, the sphere's color is defined.
for flaeche in kugel.flaechen
  flaeche.fill.color = seen.Colors.rgb(0, 145, 190, 255)
  flaeche.fill.metallic = true
  flaeche.fill.specularColor = flaeche.fill.color
Here, a for-loop is used to assign a color to every single area of the sphere. The attribute "color" determines the - you guessed it - color. Here, we have multiple ways of defining a color. "Colors.rgb()" assigns a color via RGB including an alpha value. Alternatively, the color can also be entered via "Colors.hrs()". Adding the parameter "metallic" makes the surface look metallic. In this case, the color determined via "specularColor" is used as the reflexion paint, instead of a simple light reflexion. seenjs_sphere_metallic Two Spheres - One With and One Without a Metallic Effect In the following step, the sphere is added to a model via "Models.default().add()".
objects = seen.Models.default().add(sphere)
Subsequently, the scene into which the model - the sphere in this case - is placed, is defined.
scene = new seen.Scene
  model : objects
  viewport : seen.Viewports.center(640, 425)
Above, the sphere is added to the scene using the variable "objects." "Viewports.center()" defines, where the sphere is centered. In our example, we want to center the sphere within the drawing area, which is why we entered the measurements of the "<canvas>" element. In the final step, the scene including the sphere has to be rendered and assigned to the canvas element.
seen.Context("seenjs", scene).render()
This is done using the "Context()" method. The ID of the canvas element, as well as the scene, is entered. Finally, everything is drawn onto the HTML5 Canvas via "render()".

How to Create Multiple 3D Objects With Seen.js

We can place as many 3D objects in one scene as we want to. For that, we first need to create a new "shape" object.
pyramid = seen.Shapes.tetrahedron()
pyramid.scale(50)
seen.Colors.randomSurfaces2(pyramid)
In our case, we use "Shapes.tetrahedon()" to define a three-sided pyramid and bring it to an appropriate size with "scale()". The color is chosen at random via "Colors.randomSurfaces2()". In the next step, we assign the pyramid to the variable "objects" using "append()" and "add()". The sphere is already in there.
objekte.append().translate(-25, 25, 100).add(pyramid)
Then, we place the pyramid in relation to the sphere with the "translate()" method. Without "translate()", the pyramid would receive the same center as the sphere. seenjs_append Two Objects in One Scene The methods "rotx()", "roty()", and "rotz()" allow you to rotate single, or all objects in the space.
pyramid.rotx(30)
objects.roty(90)
In this example, the pyramid is rotated by 30 degrees on the x axis. At the same time, all objects in the scene are rotated by 90 degrees on the y-axis. seenjs_rot Rotated Objects

3D Animations With Seen.js

The defined objects can now be animated within the scene with little effort. To do so, we simply add the "animate()" method to the "render()" method. Then, an event is used to define the animation's course.
seen.Context("seenjs", scene).render().animate()
  .onBefore((time, deltatime) -> objekte.rotx(deltatime * 1e-4).roty(0.5 * deltatime * 1e-4))
  .start()
Above, we defined an event that is called up before each frame change via "onBefore()." The time as well as the deltatime are transferred. In our demonstration, all objects are moved using "rotx()" and "roty()". They rotate around their own axis, with the rotation around the y-axis being faster.

How to Create Custom Objects With Seen.js

In "seen.js", there are multiple ways of creating custom objects. One being the "extrude()" method. Here, areas that form an object together are defined in a three-dimensional space.
arrow = seen.Shapes.extrude([
  seen.P(0, 0, 0)
  seen.P(1, 1, 0)
  seen.P(1, 0.5, 0)
  seen.P(2, 0.5, 0)
  seen.P(2, -0.5, 0)
  seen.P(1, -0.5, 0)
  seen.P(1, -1, 0)
 ], seen.P(0, 0, 0))
As seen above, we use "Shapes.extrude()" to create a simple arrow. The coordinates are defined with the method "P()". It contains three coordinates each, to specify one point each on the x, y, and the z-axis of the space. For more complex shapes, "seen.js" supports the wavefront format. That's a file format to save geometrical shapes. It is used by many animation programs and is a good choice for that reason.
$.get "something.obj", {}, (content) ->
  something = seen.Shapes.obj(content, false)
In the JavaScript shown above, we use jQuery to load an object file in the wavefront format. The file's content is transferred to the "Shapes.obj()" method. This method interprets the format and displays a 3D object for "seen.js" based on it.

The Many Other Options of Seen.js

"seen.js" provides plenty other ways of creating objects, changing their appearance, and making them move. For instance, there's the option to view a scene from different points of view. On top of that, various light sources can be defined. Due to different events, there's the option to react to events like mouse movement and clicks.

Seen.js: Free and Well-Documented

"seen.js" is available under the Apache license. That means it's available to anyone for free. On the "seen.js" website, there are plenty of examples that give a good impression of the options that "seen.js" comes with. Even though the documentation is extensive, getting started is not easy. Mainly considering the current low-poly trend, looking into the library is worth it as following this trend allows for the creation of some very impressive graphics and animations. Featured image by Harryarts on Freepik

Denis Potschien

Denis works as a freelance web designer since 2005.

One comment

  1. Hi,
    Does seen.js support animated 3D models? I have an animated cartoon character, minion, which has animation of scaling, dancing and popping effect. This is a FBX file which we load in Unity3D.
    Can we load models with multiple materials and textures?

Leave a Reply

Your email address will not be published. Required fields are marked *