Color to Grayscale on Hover Image via HTML Canvas Cloning

Original source with some code modifications [a) tutorial is grayscale to color on hover, b) IE compatability]

*change slidebox to whatever your container div for the image is
*can be used in conjunction with other animations. Here we grayscale an image in conjunction with hover overlay to create minimal distraction for the overlay color on hover.


<script type="text/javascript">

	// On window load. This waits until images have loaded which is essential
	$(window).load(function(){

		// Fade in images so there isn't a color "pop" document load and then on window load
		$(".slidebox img").fadeIn(500);

		// clone image
		$('.slidebox img').each(function(){
			var el = $(this);
			el.css({"position":"absolute"}).wrap("<div class='img_wrapper' style='display: inline-block'>").clone().addClass('img_grayscale').css({"position":"absolute","z-index":"2","opacity":"1"}).insertBefore(el).queue(function(){
				var el = $(this);
				el.parent().css({"width":this.width,"height":this.height});
				el.dequeue();
			});
			// Brother version
			var ua = $.browser;

			// IE < 9 Brother
			if ( ua.msie && ua.version.slice(0,3) < 9 ) {
			el.css('filter',"progid:DXImageTransform.Microsoft.BasicImage(grayScale=1)");

			}

			// Canvas Brother
			else {

			this.src = grayscale(this.src);

			}
		});

		// Fade image
		$('.slidebox img').mouseout(function(){
			$(this).parent().find('img:first').stop().animate({opacity:1}, 200);
		})
		$('.img_grayscale').mouseover(function(){
			$(this).stop().animate({opacity:0}, 200);
		});
	});

	// Grayscale w canvas method
	function grayscale(src){
		var canvas = document.createElement('canvas');
		var ctx = canvas.getContext('2d');
		var imgObj = new Image();
		imgObj.src = src;
		canvas.width = imgObj.width;
		canvas.height = imgObj.height;
		ctx.drawImage(imgObj, 0, 0);
		var imgPixels = ctx.getImageData(0, 0, canvas.width, canvas.height);
		for(var y = 0; y < imgPixels.height; y++){
			for(var x = 0; x < imgPixels.width; x++){
				var i = (y * 4) * imgPixels.width + x * 4;
				var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
				imgPixels.data[i] = avg;
				imgPixels.data[i + 1] = avg;
				imgPixels.data[i + 2] = avg;
			}
		}
		ctx.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
		return canvas.toDataURL();
    }

</script>

About Steven Chu


Hi, I'm Steven! I'm an entrepreneur, photographer and art director in New York. Follow this blog for self expression, fun, and most importantly: looking comfortable, at ease, and amazing in your photos no matter who takes them! I dedicate this to my amazing friends who have let me inadvertently turn all of our hangouts and travel photos into a never ending photoshoot of fun. The proof is in the pudding-- our photos rock. My other projects: I'm the founder of InstaTechie.com, a face-to-face tech concierge service for NYC. Book a techie to walk you through something you want to learn! My work focuses on socially engaged art projects which use technology to create access to resources for communities. Visit Steven Chu Studio (stevenchustudio.com) for branding & design work or Steven Chu (stevenchu.com) for photography projects.

Leave a Reply