1. Code
  2. JavaScript

How to Transition an Image from B&W to Color with Canvas

Scroll to top
1 min read

Recently, in the CodeCanyon forums, a question was brought up: "How do I transition an image from black and white, to color -- using only one image?" Unfortunately, at this point in time, it's not possible with CSS. However, if we're creative with JavaScript and canvas, we can create a solution relatively easily. I'll show you how in today's video tutorial!


Final Source

1
2
<!DOCTYPE html> 
3
 
4
<html lang="en"> 
5
<head> 
6
   <meta charset="utf-8"> 
7
   <title>untitled</title> 
8
	<style> 
9
		/* Setup...not important. */
10
		.img-wrap {
11
			width: 500px;
12
			margin: 100px auto;
13
			position: relative;
14
			cursor: pointer;
15
		}
16
		
17
		/* Handles animation of b*w to color */
18
		canvas {
19
			position: absolute;
20
			left: 0;
21
			top: 0;
22
			opacity: 1;
23
			-webkit-transition: all 1s;
24
			-moz-transition: all 1s;
25
			-o-transition: all 1s;
26
			-ms-transition: all 1s;
27
			transition: all 1s;
28
		}
29
		
30
		canvas:hover {
31
			opacity: 0;
32
		}
33
		
34
		/* If you MUST have IE support */
35
		#cvs-src {
36
		   filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
37
		}
38
		
39
		#cvs-src:hover {
40
			filter: none;
41
		}
42
	</style>  
43
</head> 
44
<body> 
45
 
46
<div class="img-wrap"> 
47
	<img id="cvs-src" src="your-image.jpg" /> 
48
	<canvas width=500 height=500></canvas> 
49
</div> 
50
 
51
<script> 
52
	(function() {
53
		var supportsCanvas = !!document.createElement('canvas').getContext;
54
		supportsCanvas && (window.onload = greyImages);
55
		
56
		function greyImages() {
57
			var ctx = document.getElementsByTagName("canvas")[0].getContext('2d'),
58
				img = document.getElementById("cvs-src"),
59
				imageData, px, length, i = 0,
60
				grey;
61
			
62
			ctx.drawImage(img, 0, 0);
63
			
64
			// Set 500,500 to the width and height of your image.

65
			imageData = ctx.getImageData(0, 0, 500, 500);
66
			px = imageData.data;
67
			length = px.length;
68
					
69
			for ( ; i < length; i+= 4 ) {
70
				grey = px[i] * .3 + px[i+1] * .59 + px[i+2] * .11;
71
				px[i] = px[i+1] = px[i+2] = grey;
72
			}
73
			
74
			ctx.putImageData(imageData, 0, 0);		
75
		}
76
	})();
77
</script> 
78
 
79
</body> 
80
</html>

Conclusion

So what do you think? Would you use this technique in your own projects? Can you think of a better way that doesn't involve using a server-side language or sprites? Let me know in the comments!