In this tutorial we will create and animate smooth 2D lines using a MeshLine Library for Three.JS. We use this library of THREE.Line as it triangulates the line, meaning it draws it using triangles rather the using GL_LINE, WebGL’s built in line drawing mode. GL_LINE is not very feature rich and may produce different results on different graphics cards. The MeshLine library provides a much more extensive feature set for those who need great line drawing at a variety of thicknesses and colors.
Step 1: Install the THREE.MeshLine
You can find the THREE.MeshLine library here. You can follow the instructions on the GitHub page to install. If you are using npm with your project, feel free to install the npm package. Otherwise, just include the script before your JavaScript but after Three.js.
Step 2: Build the Line
var scene, camera, renderer, points, line;
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, 640 / 480, 0.1, 1000);
renderer = new THREE.WebGLRenderer();
renderer.setSize(640, 480);
document.body.appendChild(renderer.domElement);
camera.position.z = 9;
points = [];
for (var i = -10; i < 10.1; i += 0.1) {
points.push([i, Math.sin(i), 0]);
}
line = new MeshLine();
line.setPoints(points.flat());
var material = new MeshLineMaterial({ color: new THREE.Color(0xffff00), lineWidth: 0.1, dashArray: 0.1, dashRatio: 0.2});
material.transparent = true;
mesh = new THREE.Mesh(line, material);
scene.add(mesh);
animate();
}
function animate() {
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
In this code snippet, we render a static dotted line in a yellow color. A couple of things to note are that the points are sent in in a flat array, but I find it easier to add the points each as their own array first and pass it as a flat array later. This makes it easier to loop the points later when I wish to animate the line. It’s also important to note that aside from the points any configuration done to the line is done in the material. If you wish to have a dotted line, ensure you have the material.transparent = true;
call. Otherwise, you can omit that line.
Step 3: Change or animate the line
To change the line while the program is running, you simply need to make a call to setPoints
and re-render. Below is the full source code from the video, with lines highlighted that were changed to introduce an animation.
var scene, camera, renderer, points, line, amountToAdd = 0.01;
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, 640 / 480, 0.1, 1000);
renderer = new THREE.WebGLRenderer();
renderer.setSize(640, 480);
document.body.appendChild(renderer.domElement);
camera.position.z = 9;
points = [];
for (var i = -10; i < 10.1; i += 0.1) {
points.push([i, Math.sin(i), 0]);
}
line = new MeshLine();
line.setPoints(points.flat());
var material = new MeshLineMaterial({ color: new THREE.Color(0xffff00), lineWidth: 0.1, dashArray: 0.1, dashRatio: 0.2});
material.transparent = true;
mesh = new THREE.Mesh(line, material);
scene.add(mesh);
setInterval(() => { amountToAdd *= -1; }, 2000);
animate();
}
function animate() {
points = points.map((point) => [point[0], point[1] * (1 + amountToAdd), point[2]]);
line.setPoints(points.flat());
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
Conclusion
That’s it! An easy way to create beautiful lines in Three.js.