I am trying to display a cube with one side showing an image that I draw some text upon. I’ve tried several approaches but the side that with the image and text always ends up being rendered as black. If instead I simply load the image directly using something like the ThreeJS text loader, I can see the image just fine (with no text on it of course). What is wrong with my code so that I can’t see the desired image with the text I print on to it during initialization?
var scene, camera, renderer;
var WIDTH = window.innerWidth;
var HEIGHT = window.innerHeight;
var SPEED = 0.01;
var cube = null;
var imgBackSide = null;
function init() {
// Create a document element to house the back side image for cards.
imgBackSide = document.createElement('img');
imgBackSide.src = '/images/cards/card-back-side-400x400.png';
scene = new THREE.Scene();
initCamera();
initRenderer();
initCube();
document.body.appendChild(renderer.domElement);
}
function initCamera() {
camera = new THREE.PerspectiveCamera(70, WIDTH / HEIGHT, 1, 10);
camera.position.set(0, 3.5, 5);
camera.lookAt(scene.position);
}
function initRenderer() {
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(WIDTH, HEIGHT);
}
function canvasDrawText(ctx, canvas, text, x, y) {
// if x isn't provided
if ( x === undefined || x === null ){
let textSize = ctx.measureText(text);
x = (canvas.width - textSize.width) / 2;
}
// if y isn't provided
if ( y === undefined || y === null ){
let textSize = ctx.measureText(text);
y = (canvas.height - textSize.height) / 2;
}
// actually draw the text
// ctx.fillStyle = fillStyle;
ctx.fillText(text, x, y);
}
function newCardBacksideTexture(cardBackSideText) {
// Create an IMG element to hold the card back side image and load it.
let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d');
canvas.width = 400;
canvas.height = 400;
ctx.drawImage(imgBackSide, 0, 0);
// Draw the card label on top of the background.
ctx.font = 'bolder 90px Verdana';
canvasDrawText(ctx, canvas, cardBackSideText);
// dynamicTexture.texture.anisotropy = renderer.capabilities.getMaxAnisotropy();
return new THREE.CanvasTexture(canvas);
}
function initCube() {
let cubeGeometry = new THREE.BoxGeometry(2, 0.1, 2);
let loader = new THREE.TextureLoader();
let dummy = loader.load("/images/cards/white-square-400x400.png");
let materialArray = [
new THREE.MeshBasicMaterial( { map: loader.load('/images/cards/white-square-400x400.png') } ),
new THREE.MeshBasicMaterial( { map: loader.load('/images/cards/white-square-400x400.png') } ),
// Card face.
new THREE.MeshBasicMaterial( { map: loader.load('/images/card-face.jpg') } ),
// Card back side.
new THREE.MeshBasicMaterial( { map: newCardBacksideTexture('BACK SIDE OF CARD') } ),
//
new THREE.MeshBasicMaterial( { map: loader.load('/images/cards/white-square-400x400.png') } ),
new THREE.MeshBasicMaterial( { map: loader.load('/images/cards/white-square-400x400.png') } ),
];
cube = new THREE.Mesh( cubeGeometry, materialArray );
scene.add(cube);
}
function rotateCube() {
cube.rotation.x -= SPEED * 2;
cube.rotation.y -= SPEED;
cube.rotation.z -= SPEED * 3;
}
function render() {
requestAnimationFrame(render);
rotateCube();
renderer.render(scene, camera);
}
init();
render();