This is the 1st post in the Use three.js in Jekyll Blog series (»). In this post, I’ll get started with three.js by trying a simple example.
Introduction
My goal is to create some fancy demos on my blog, and three.js, a popular JavaScript 3D library, can be very useful to that end. The Use three.js in Jekyll Blog series will record my journey in learning three.js. Hopefully I can learn the basics of HTML, CSS and JS as well.
Before we start
Create a container
To resize and locate the 3D content in jekyll blog posts, we need to create a container as the canvas.
The simplest example looks like this:
<div id='cube'></div>
This is a common way I found to maintain the aspect ratio. Here the outer div controls the aspect ratio, while the inner div holds the 3D content. A more elegant way is shown here.
.threejs {
position: relative;
width: 100%;
padding-top: 56.25%; /* 16:9 aspect ratio */
}
.threejs > * {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
<div class='threejs'>
<div id='cube'></div>
</div>
Note that the inner div’s id will be used to get container’s width and height while initialzing three.js.
var container = document.getElementById('cube');
var width = container.clientWidth;
var height = container.clientHeight;
Learn how to make this responsive in three.js, i.e., automatically resize the content when the window is resized.
Include the library
This can be done by adding the following line
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r121/three.min.js"></script>
where the src comes from CDN or a local copy of the minified library.
TODO: control this in the front matter like other Markdown enhancements.
Hello, cube!
The spinning cube demo is originally obtained from here and a great explaination can be found here. Essentially, we need to set up three things: scene, camera and renderer to display the 3D content using three.js.
Scene
Here is a unit cube.
// scene
scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
geometry = new THREE.BoxGeometry(1, 1, 1);
material = new THREE.MeshNormalMaterial();
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
Camera
Here is a perspective camera. 70
is the field of view (FOV) in degrees, width / height
is the aspect ratio, 0.01
is the near clipping plane, and 10
is the far clipping plane.
// camera
camera = new THREE.PerspectiveCamera(70, width / height, 0.01, 10);
camera.position.z = 2;
Renderer
Here is a WebGL renderer. Don’t forget to append it as the container’s child.
// renderer
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(width, height);
container.appendChild(renderer.domElement);
The line with setPixelRatio
can improve display quality on mobile devices.
Animation
Here is the so-called render or animate loop.
// animation
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.005;
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
}