// I have compressed this function as its just an utility to just draw a circle in two colors to use as example images and prevent cross-origin issues.
function anImage( color1, color2 ){ var canvas = document.createElement( 'canvas' ), ctx = canvas.getContext( '2d' ); canvas.width = 256; canvas.height = 256; ctx.fillStyle = color1; ctx.fillRect( 0, 0, 400, 400 ); ctx.fillStyle = color2; ctx.arc( 200, 200, 200, 0, Math.PI * 2 ); ctx.fill(); return canvas; }
function drawTexture(){
// Draw the first image full opaque
ctx.globalAlpha = 1;
ctx.drawImage( image1, 0, 0, 512, 512 );
// Draw the second image as transparent as its transition requires
ctx.globalAlpha = state;
ctx.drawImage( image2, 0, 0, 512, 512 );
texture.needsUpdate = true;
}
function render(){
state = targetState >= state ? state + .01 : state - .01;
state = state < 0 ? 0 : state > 1 ? 1 : state;
drawTexture();
cube.rotation.y += .01;
renderer.render( scene, camera );
window.requestAnimationFrame( render );
}
var image1 = anImage( 'red', 'yellow' );
var image2 = anImage( 'blue', 'green' );
var renderer = new THREE.WebGLRenderer;
var camera = new THREE.PerspectiveCamera;
var scene = new THREE.Scene;
var canvas = document.createElement( 'canvas' );
var ctx = canvas.getContext( '2d' );
var state = 0;
var targetState = 0;
// Lets set up our canvas for the texture
canvas.width = 512;
canvas.height = 512;
ctx.drawImage( image1, 0, 0, 512, 512 );
var texture = new THREE.Texture( canvas );
var cube = new THREE.Mesh(
new THREE.BoxGeometry,
new THREE.MeshBasicMaterial({ map: texture })
);
scene.add( cube );
camera.position.set( 0, 0, 5 );
camera.lookAt( scene.position );
renderer.domElement.addEventListener( 'click', event => {
targetState = targetState === 1 ? 0 : 1
});
renderer.setSize( 512, 512 );
render();
document.body.appendChild( renderer.domElement );
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/92/three.min.js"></script>