In my THREE.js application, I am creating 2D surfaces using PlaneGeometry
and BasicMaterial
meshes, while also supporting textures with a canvas:
this.canvas = makeCanvas(canvasWidth, canvasHeight);
this.ctx = this.canvas.getContext('2d');
this.texture = new THREE.Texture(this.canvas);
this.texture.minFilter = THREE.LinearFilter;
this.texture.magFilter = THREE.LinearFilter;
this.texture.anisotropy = 16;
this.mesh = new THREE.Mesh(new THREE.PlaneGeometry(width, height), new THREE.MeshBasicMaterial({
map: this.texture,
overdraw: true,
side: THREE.DoubleSide,
transparent: true
}));
Although this method works well, it becomes complicated when transparency is involved. In such cases, I have to create an additional texture for binding as alphaMap
and duplicate all the drawing operations across two canvas contexts which makes the code quite messy:
var circleAlpha = 'rgb(100, 100, 100);',
segmentAlpha = 'rgb(200, 200, 200);';
ctx.fillStyle = 'rgb(0, 255, 255);';
if (this.segment === -1) {
circleAlpha = segmentAlpha;
}
ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.alphaCtx.clearRect(0, 0, this.canvas.width, this.canvas.height);
var drawArc = function (c, w, h, piece) {
var angw = 2 * Math.PI / 6;
c.beginPath();
c.arc(w / 2, h / 2, 512, angw * piece, angw * (piece + 1), false);
c.arc(w / 2, h / 2, 300, angw * (piece + 1), angw * piece, true);
c.closePath();
c.fill();
};
for (var i = 0; i < 6; i++) {
this.alphaCtx.fillStyle = i == this.segment ? segmentAlpha : circleAlpha;
drawArc(ctx, this.canvas.width, this.canvas.height, i);
drawArc(this.alphaCtx, this.canvas.width, this.canvas.height, i);
}
this.updateTexture();
this.alphaTexture.needsUpdate = true;
I've been considering developing a utility library to automate this process, but before proceeding, I wanted to explore if there are simpler alternatives available.