How to Transition an Image from B&W to Color with Canvas
Jeffrey Way
•
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!



