PROWAREtech

articles » current » javascript » three-js » transition-from-one-color-to-another

ThreeJS: Transition from One Color to Another

How to gradually transition from one color to another using THREE.js with examples changing the scene background during the scroll event and animation event.

This snippet of code uses a linear transition.


// NOTE: Helper function
var INT2RGB = function (int) {
	return [(int & 0xff0000) >>> 16, (int & 0xff00) >>> 8, int & 0xff];
};

// NOTE: Helper function
var RGB2INT = function (rgb) {
	return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];
};

// NOTE: the function that transitions from one color to another based on a percentage of transition or completion
var transitionColor = function (percent, startColor, endColor) {
	if (percent < 0) {
		return startColor;
	}
	else if (percent > 100) {
		return endColor;
	}
	var pos = percent / 100;
	var rgb1 = INT2RGB(startColor);
	var rgb2 = INT2RGB(endColor);
	var r = Math.trunc((1 - pos) * rgb1[0] + pos * rgb2[0] + 0.5);
	var g = Math.trunc((1 - pos) * rgb1[1] + pos * rgb2[1] + 0.5);
	var b = Math.trunc((1 - pos) * rgb1[2] + pos * rgb2[2] + 0.5);
	return RGB2INT([r, g, b]);
};

Here is a working example that transitions during the animate function:


<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Color Transition</title>
	<style>
		body {
			margin: 0;
			padding: 0;
		}
		canvas {
			display: block;
			width: 100%;
			height: 100vh;
		}
	</style>
</head>
<body>
	<canvas></canvas>
	<script src="/js/three.min.js"></script>
	<script type="text/javascript">

(function () {

	var canvas = document.getElementsByTagName("canvas")[0];

	// NOTE: Helper function
	var INT2RGB = function (int) {
		return [(int & 0xff0000) >>> 16, (int & 0xff00) >>> 8, int & 0xff];
	};

	// NOTE: Helper function
	var RGB2INT = function (rgb) {
		return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];
	};

	// NOTE: the function that transitions from one color to another based on a percentage of transition or completion
	var transitionColor = function (percent, startColor, endColor) {
		if (percent < 0) {
			return startColor;
		}
		else if (percent > 100) {
			return endColor;
		}
		var pos = percent / 100;
		var rgb1 = INT2RGB(startColor);
		var rgb2 = INT2RGB(endColor);
		var r = Math.trunc((1 - pos) * rgb1[0] + pos * rgb2[0] + 0.5);
		var g = Math.trunc((1 - pos) * rgb1[1] + pos * rgb2[1] + 0.5);
		var b = Math.trunc((1 - pos) * rgb1[2] + pos * rgb2[2] + 0.5);
		return RGB2INT([r, g, b]);
	};

	// NOTE: create the scene to place objects in
	var scene = new THREE.Scene();
	scene.matrixWorldAutoUpdate = true;



	// NOTE: the width and height of the canvas
	var size = {
		width: canvas.offsetWidth,
		height: canvas.offsetHeight
	};


	var cameraNear = 1, cameraFar = 500;
	// NOTE: create the camera with 53 degree field of view; this is how the scene is viewed by the user
	var camera = new THREE.PerspectiveCamera(75, size.width / size.height, cameraNear, cameraFar);


	var renderer = new THREE.WebGLRenderer({
		canvas: canvas,
		antialias: true
	});
	renderer.setPixelRatio(window.devicePixelRatio);
	renderer.setSize(size.width, size.height);
	renderer.render(scene, camera);

	var percent = -50;

	// NOTE: MUST HAVE AN ANIMATE FUNCTION
	var animate = function () {
		scene.background = new THREE.Color(transitionColor(percent, 0x6699CC, 0xFF6633));
		percent += 0.5;
		renderer.render(scene, camera);
		requestAnimationFrame(animate);
	};
	animate();

})();

	</script>
</body>
</html>

Here is an example of transitioning between two colors during the scroll event:


<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Color Transition</title>
	<style>
		body {
			margin: 0;
			padding: 0;
			height: 300vh;
		}
		canvas {
			display: block;
			position: fixed;
			top: 0;
			left: 0;
			width: 100%;
			height: 100vh;
		}
	</style>
</head>
<body>
	<canvas></canvas>
	<script src="/js/three.min.js"></script>
	<script type="text/javascript">

(function () {

	var canvas = document.getElementsByTagName("canvas")[0];

	// NOTE: Helper function
	var INT2RGB = function (int) {
		return [(int & 0xff0000) >>> 16, (int & 0xff00) >>> 8, int & 0xff];
	};

	// NOTE: Helper function
	var RGB2INT = function (rgb) {
		return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];
	};

	// NOTE: the function that transitions from one color to another based on a percentage of transition or completion
	var transitionColor = function (percent, startColor, endColor) {
		if (percent < 0) {
			return startColor;
		}
		else if(percent > 100) {
			return endColor;
		}
		var pos = percent / 100;
		var rgb1 = INT2RGB(startColor);
		var rgb2 = INT2RGB(endColor);
		var r = Math.trunc((1 - pos) * rgb1[0] + pos * rgb2[0] + 0.5);
		var g = Math.trunc((1 - pos) * rgb1[1] + pos * rgb2[1] + 0.5);
		var b = Math.trunc((1 - pos) * rgb1[2] + pos * rgb2[2] + 0.5);
		return RGB2INT([r, g, b]);
	};

	// NOTE: create the scene to place objects in
	var scene = new THREE.Scene();
	scene.matrixWorldAutoUpdate = true;



	// NOTE: the width and height of the canvas
	var size = {
		width: canvas.offsetWidth,
		height: canvas.offsetHeight
	};


	var cameraNear = 1, cameraFar = 500;
	// NOTE: create the camera with 53 degree field of view; this is how the scene is viewed by the user
	var camera = new THREE.PerspectiveCamera(75, size.width / size.height, cameraNear, cameraFar);
	camera.position.z = 3;

	var renderer = new THREE.WebGLRenderer({
		canvas: canvas,
		antialias: true
	});
	renderer.setPixelRatio(window.devicePixelRatio);
	renderer.setSize(size.width, size.height);
	renderer.render(scene, camera);

	var planeImage = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAACYBJREFUeNrs3Y914kYCwOHh3jXAlUBKYEtgS7BLwCXgErwlQAl2CaYEu4R1CXYJBL0bJcThjzQaCUl833t6ySWXNRbSj9EghslutwsAQ/AfuwAQLADBAgQLQLAABAsQLADBAhAsQLAABAtAsADBAhAsAMECBAtAsAAECxAsAMECECxAsAAEC0CwAMECECwAwQIEC0CwAMECECwAwQIEC0CwAAQLECwAwQIQLECwAAQLQLAAwQIQLADBAgQLQLAABAsQLADBAhAsQLAABAtAsADBAhAsAMECBAtAsADBAhAsAMECBAtAsAAECxAsAMECECxAsAAEC0CwAMECECwAwQIEC0CwAAQLECwAwQIQLECwAAQLQLAAwQIQLADBAgQLQLAAwQIQLADBAgQLQLAABAsQLADBAhAsQLAABAtAsADBAhAsAMECBAtAsAAECxAsAMECECxAsAAEC0CwAMECECwAwQIEC0CwAMECECwAwQIEC0CwAAQLECwAwQIQLECwAAQLQLAAwQK4tv8O/ReYTCaH/3MV/zrfb3cX/tPNfvuIf1/89aXlh7rcb9O4rS78f7dxK/264WO03G+z+PfHfB3so2K/vTu1q9ntdsN7wEPe4kH8WvwqGbbfMSbTTLt3lfGxFdvizM/6nfHnlNtb/B1WZ2LRhuLF5rnhY1/FyOVQd9++Zt4frf38wZ3vAw7VXUsn6S7Dgb5q6XEtOw7WuYi1Farcv8c6w/MpWD3ZBjmHtb8MfI6vwLOePbRlPGCeRnwVMY+/36WA1jGLJ1kbz+kynvDLwOANKlj7UE3321uF+amuTeMJt76x42cdf+8ml9DlqGrR0WNFsDrzGl/h+2QWL5MWN3oMLRqEYBVHVV0+1reMc5QI1snR1VMPYzWPJ8Dsxo+jecJl8OpKl85zIy3BajtWs9DeRG+TkdWzV+t/BKhquO/Cdef55h2P7LixEdaqh4+pj5P+11ZlYrvYZ32Y67sL/ZsLZejBKibaGxxYxc2gP4s/5tv2Y789hv/fPJoa0LnD51+qzOM99WhUujZCFqw2ToKUg6oI0n345x3jpeJO6OLO6IcYsPtQ/U73WRjHbQvbEyFvclf9/MJztejZqGYa3O4gWJmlXnbVGT29xGj9qBCuHJen7zGox0Z/hyPAYvvqcF8fPq4mEWhj333Ex/a/b/vqMfz9EavU0bJR1lAM4I728ibFultb8Wx6l/gi8ec+hbx3ul96p2wd8n5KYNFgv1WZIF+HZh/jCR3u27rc6T6gO91TX/3aGOo3+TNf4shp22B0selwv297su/K0e8lDyH9A+wm310SXt26hQOx7ZOuT74y/nfTxJHlRwxRVQ+Jj/vS3BuCVeugTfUch8c57kJPnfyve9L1Rcq7oO8ngpG6737VDNDhMjMpzy+CdbVX+sMD8TXOHy0b/jmhg5OuL1L21TZj/L4SL/FSL2XdpiJYWeSaS5nHy8TPkPZu1SzxpNsM8LhIXZJlkzH228TQv4e0BfwES7Ca2+12HyHvCpLFpclTDFedUUTqSTckqwYj0c2Zy/eU+DV5zlOmEXxqQbCyaWOUMo0jibcKr67l0sZdnnRtO3abQeoHzMt3MXPuuyaX0Sn7XbAEK9soa9PiyV+uuLC6EKyuXumHpgjL/ZnAXGPfpcbOO4WClc19aHfy+imc/lDurOMTZyiKF5EfF15MhjRyESzByjbK+gjt38u0DONe3jjnqOoxxurD7kCwjkdrG0+SNkcuxaWhO5+PK24zKO4pKz7PN8avHhNfwcoereLy44/Q7vcI5lp2ZExvlZe3C2w6ikCTS0mXdoLVq2h97bf7eInYxmT892VHPpw4fy2D/FlzBHqNCfCU2BldCVbr4So/UHxq3asm7jIczGNca6kIyXOofvPtV0j/fF+XI1vfFi1YnSlXFi0uFR8zjiimDaM15gXinmpEKyUGqZ8/nIX0e8kQrE4VB10xGTzJFK5Zhlfgvi4QV644mrrkTRmtKnFI2XepS2OnvmFihCVYV/UrNH/bfZrhgO7Lly6cO1GL0Wnqpwmq3AaSGsS6sU/9dqXUD1ojWP82mUzWDU7GXEu7NJkjK171+/61Ug8NLt0WFfZdyjxW3fXzU792TawEK6tl8RX1+y1lbiL1ZDkWvyaXDUW0UpdIvoujtLbnw1LjXmVUkzqCW1YYoRaRavKt4II1FENYxzl8+4Dut39XxWfIsz75MjRb0/1wbfdzXxV2F//993XKu1jT/TnkXcv9cLTUZJ/9PhLGafxnnw3+3Crrn1vTvS8tGGCwDr84oMrw/y7xQP488Ur+mSlaKVsXwUrdX1VGWesr7rtT26KFYOR+PJ3+fF9C0Y7yJsbXE6OVcv4jde5oe2Jy9jGM20viJXSVy9Wuv7asyu+6DZjD6tAihumtwiVEHZsz/3zsb4GnzOnMKoxW+hT8W3jxEawb8X7hlbftpW6uLXXUUWWUtQn9mOQu3mBws6hgjcKld8u6WOpmiJeFxfxXlXnFNj5KVff59c6gYI3CY8VLvuKE+zni/ZB6Qle99eJa0XoIw/xiEATraKzqrPNURmuMl4dtf4vyV9x3XY10yqWcxUqwRuE+pC1KV0TrjzC+S4zUG27nod4NnOUyQV8t/y4/XAYK1lhGEk2DU756/wzjegexyd3pdZ+DNlYx/Th4XkywC1Y3drvdpMEI6FRgHmOo7jMezOUr+c/MJ982Pt6uRwipc0xVJ9+PXZKXK200eU5e4vM6xpHvTZvU+HhLfx70ZHK4ztSswiv6y8HIZxO6nXMqLo8WByOPSx9hOfxq+2247WVPDp/nc/uu/BLXoX7T9jUHA4IFcLOXhACCBQgWgGABggUgWACCBQgWgGABCBYgWACCBSBYgGABCBaAYAGCBSBYAIIFCBaAYAEIFiBYAIIFIFiAYAEIFoBgAYIFIFgAggUIFoBgAYIFIFgAggUIFoBgAQgWIFgAggUgWIBgAQgWgGABggUgWACCBQgWgGABCBYgWACCBSBYgGABCBaAYAGCBSBYAIIFCBaAYAGCBSBYAIIFCBaAYAEIFiBYAIIFIFiAYAEIFoBgAYIFIFgAggUIFoBgAQgWIFgAggUgWIBgAQgWgGABggUgWACCBQgWgGABggUgWACCBQgWgGABCBYgWACCBSBYgGABCBaAYAGCBSBYAIIFCBaAYAEIFiBYAIIFIFiAYAEIFoBgAYIFIFgAggUIFoBgAYIFIFgAggUIFoBgATTzpwADAGtM5LEaxvPvAAAAAElFTkSuQmCC";
	var planeGeometry = new THREE.PlaneGeometry(1, 1);
	var planeMaterial = new THREE.MeshBasicMaterial({ map: new THREE.TextureLoader().load(planeImage), transparent: true, side: THREE.DoubleSide });
	scene.add(new THREE.Mesh(planeGeometry, planeMaterial));

	scene.background = new THREE.Color(0xFF0000);

	// NOTE: the parent element is the document body!!!
	window.onscroll = function() {
		var scrollPosition = document.body.offsetHeight / canvas.offsetHeight / 2 * window.scrollY;
		var percent = scrollPosition / document.body.offsetHeight * 100;
		scene.background = new THREE.Color(transitionColor(percent, 0xFF0000, 0xFFFF00));
	};

	// NOTE: MUST HAVE AN ANIMATE FUNCTION
	var animate = function () {
		renderer.render(scene, camera);
		requestAnimationFrame(animate);
	};
	animate();

})();

	</script>
</body>
</html>

This site uses cookies. Cookies are simple text files stored on the user's computer. They are used for adding features and security to this site. Read the privacy policy.
CLOSE