Grayscale Hover Effect with HTML5 canvas and jquery

I saw a tutorial on showing how to make a HTML5 Grayscale Image Hover and thought this is very cool. After some research I’ve found another tutorial on Nettuts+ with another function. This one was better for me to understand(video tutorial), so I combined the snippets together and reduced the jQuery code for my needs. Finally I’ve created some different hover effects.

View Demos & Codes

The Future with CSS Shaders and Filter Effects

In the future there will be CSS Shaders to do something like that. For more information check out this article about CSS Filter Effects on


  1. Love all the effects! I have try your code but it doesnt working for me. Is there a way I can get some example to download? Thanks

    by leo on
  2. Hi Leo,

    thanks for the feedback. Here is a .zip file with the examples

    But remember you need to put the files on a web server or a local testserver. The images should have the same domain as your html document.

    I hope that helps you.


    by solemone on
  3. Thank you very much solemone. It was my fault I deleted the other scripts and fogot to check it in firebug. I was missing a function. Thanks again it’s working like a charm!

    by leo on
  4. What if I add some new images with ajax. How can I make this work? Please HELP! :D

    by Florescu Adrian on
  5. Hi Florescu Adrian,

    you can change $(window).load to $(‘YOUR_IMAGE’).load in the first line of the JavaScript source. This should call the grayscale() function after your image is loaded.

    You can also try out the on() method from jQuery 1.7+

    I hope that helps you. Cheers

    by solemone on
  6. Great effects! Is it possible to transform a background-image of a div in the same way? Thanks

    by Daniel on
  7. Ok, but where do i need to put the URL to make it work? in this line: this.src = grayscale(this.src); ? Maybe you can explain some more details, because i can’t find a image URL in the original examples. Thank you – Daniel

    by Daniel on
  8. You are right “this.src” sets the new image url and “grayscale(this.src)” give you the image in grayscale back. If you want to use a backrground image you have to apply it to the cloned element. Maybe like this:

    $(this).css(‘background-image’, grayscale(put_your_url_of_default_background_image_here));

    Let me know if that helped.

    by solemone on
  9. I can’t do it with a background-image. Please help!

    by carlotta on
  10. Thanks a lot… works just great… only one question pls: any ideas on how to make a whole div or ul (multiply images) change all at once, on hover?

    by Andrei Dumitrache on
  11. Hi Andrei,
    you can change the .hover() function like this:

    $("#imglist1 a").hover(
    	function() {
    		$("#imglist1 a").find('.gotcolors').stop().animate({opacity: 1}, 200);
    	function() {
    		$("#imglist1 a").find('.gotcolors').stop().animate({opacity: 0}, 500);

    Just change “#imglist1 a” to “your_div_or_ul a” and it should work ;)

    by solemone on
  12. Is that work for the cross domain images ?
    Local images is fine.But, I’m now trying to use with 500px website images with API and it didn’t work.

    by winminseo on
  13. Unfortunately it doesn’t work with cross domain images.

    by solemone on
  14. thanks for the quick reply. :)

    i think the canvas couldn’t do that action.When i look the console , it says insecure to perform that action.

    by winminsoe on
  15. Hi Solemone, I’m trying to add this function to to a wordpress theme where img thumbnails for a list of posts or pages are greyscaled.

    How do I go about using this code with a dynamic img source?

    by Marco on
  16. It should work. Just change the “src” of the img tag to your dynamic source.

    by solemone on
  17. Can this be use with jquery lightbox or just with regular images that doesn’t pop out with lightbox.I have jquery lightbox already set up but I am trying to add this hover. I really like the last one number 11 Masking with canvas diagonal from bottom to top diagonal. In addition, I download the demo as well as that software.Also I have an class name image block img for my images, I tried to add .image block img but it just messies my lightbox up. I put .image block img with the script.

    by Glen on
  18. Maybe you can try to load an iframe with your Lightbox script. In this iframe you call the grayscale script.

    by solemone on
  19. I forgot to say I am using prettyphoto lightbox, will this iframe/grayscale still work?. Sorry for so many questions but I am new to web. I am researching this now, thanks for responding back so quickly.

    by Glen on
  20. I think it should. You can also try the “Inline content” method of prettyphoto lightbox. But remember the images should have the same location/domain of the website.

    by solemone on
  21. Hello, I tried this without the lightbox on an img but nothing works, the demo works just fine but it doesn’t work in google chrome. The demo css.
    .imglist li {
    margin: 0 0 0 15px;
    float: left;
    .imglist { display:block }
    .imglist img { opacity:0; }

    .example-wrap {
    padding: 20px 20px 20px 20px;
    margin: 0 auto 20px;

    .group:before, .group:after { content: “”; display: table; }
    .group:after { clear: both; }
    .group { zoom: 1; }

    demo script starts at:

    $(window).load(function() {
    $(‘.imglist img’).each(function() {
    $(this).wrap(”).clone().addClass(‘gotcolors’).css(‘position’, ‘absolute’).insertBefore(this);
    this.src = grayscale(this.src);
    }).animate({opacity: 1}, 500);

    $(document).ready(function() {

    $(“#imglist1 a”).hover(
    function() {
    $(this).find(‘.gotcolors’).stop().animate({opacity: 1}, 200);
    function() {
    $(this).find(‘.gotcolors’).stop().animate({opacity: 0}, 500);
    and the other script continues. I don’t see what I am doing wrong. I installed that program, but you don’t need it for the effects to work. I tried it again in the browser without the program with the demo an it still works except for chrome. Finally, also I tried one image with the demo code and nothing happens.

    by Glen on
  22. Okay, I got it to work with the demo code, I am just going see about plugging it into my site. Thanks hopefully this works. I used one image without the lightbox, I will tried and see if it works with lightbox with the advice you give me. Thanks

    by Glen on
  23. How do I do this with prettyphoto “Inline content” method of prettyphoto lightbox as you suggest. I tried researching this but I am at lost right now.

    by Glen on
  24. I got it to work with prettyphoto without doing the inline content and iframe. I put the js file in its own file and just put the script src=””> in the head area but I need to fix my images with the padding and spacing. That’s the css. I didn’t realized that I could do this Thanks for all your help. It works I just have to make the padding and spacing imglist the same as the portfolio area li . I will post and link after I reupload my new site design.Thanks for all your help and this awesome hover effect.

    by Glen on
  25. Sorry this is what I was referring to when I said I didn’t realized that I could do this ul class=”portfolio-area group imglist” id=”imglist”> Such as grouping classes within the same area. Thanks I just wanted to clear that up. Sorry for all the emails.Thanks

    by Glen on
  26. Thanks I am going to tried something else, its a beautiful effect though.Thanks for the upload and help.

    by Glen on
  27. Hi I have a minor issue…My images load up in color, I have to hover each image with mouse in order for the effect to start working properly. Kindly appreciated if you can help to figure this out.

    by Sophie on
  28. Hi Sophie,

    I think you have to check the class names in the .load() function.

    by solemone on
  29. i also have to hover on my img first before it starts working

    by annelies on
  30. Sorry it was my fault. I set the opacity of the color image to 0 with css. Now I do that in the jQuery code so you can copy it again and it should work.

    by solemone on
  31. thanks

    Can you do it with a document.ready as well instead of window load caus i can see my images pop from color to bw

    by annelies on
  32. That does not work. You need to load the images before you grayscale them. But you can set the opacity of your images to 0 with css. Like this: .imglist img { opacity: 0; }

    If you don’t want to fade them onload you can change the animate duration in the onload function like this: .animate({opacity: 1}, 0);

    Alternatively you can delete the .animate({opacity: 1}, 500); and write something like: .css('opacity', 1);

    I hope this will help you.

    by solemone on
  33. Thanks! I’ven looking for this and finally I found something that works.

    ¡Muchas gracias desde México!

    by Uriel on
  34. Hi,
    im trying to use this for a long time but the result is every image display twice, and everything is a mess.
    in the code i also see 2 div not 1 in every item.
    i copied the code without changing anything.
    please help…

    by chandler on
  35. Can you give me a link?

    by solemone on
  36. Hi
    I am trying to use pagination for this code using ajax But effects after load new images not work.
    Do you have a solution؟

    by victor on
  37. I think you have to call the $(window).load(function()... after your images are loaded.

    by solemone on
  38. But I can not call $(window).load.after load content using ajax
    I use .live() and ajaxComplete() but i not get good results.
    Please help and give more explanation

    by victor on
  39. Hi Victor,

    maybe you try to set the load function to the image itself. So every time the image is loaded you call the grayscale function. If you now load the image via ajax it is stil loaded and should call the grayscale stuff, right? Here is some code:

    $('.imglist img').load(function() {
    	$(this).wrap('<div style="display:inline-block;width:' + this.width + 'px;height:' + this.height + 'px;">');
    	$(this).clone().attr('src', grayscale($(this).attr('src'))).insertAfter($(this)).animate({opacity: 1}, 500);
    	$(this).addClass('gotcolors').css({'position': 'absolute', 'opacity' : 0 });

    Please let me know if this is working.

    by solemone on
  40. it was very use for me. thanks

    by Moorthy on
  41. Dude, you are awesome. Thank you, worked a charm on my recent project.

    by David on
  42. Actually… It works but when I tried to view the site on my phone (samsung/android) the images don’t show at all… But when I change .css opacity from 0 to 1 (window load) the images show on my phone…. is there a way around this?

    by David on
  43. Hi David,

    maybe your phone doesn’t support the tag. You can remove 'absolute', 'opacity' : 0 in the load function.

    by solemone on
  44. By doing that the grayscale is gone and the full color images are there instead. Thanks anyway.

    by David on
  45. Its really Good but Its not working in IE browser,pls help

    by Mano on
  46. It should work in IE9+ the other IE Versions don’t support the canvas element, that is used for the grayscale conversion.

    by solemone on
  47. Awesome!!!

    Spend ages working on this one and your article finally got it working for me!

    thanks very much

    by james on
  48. The effects are amazing. Thanks for sharing.

    I have a small problem trying to make it work in my site:

    The grey images are created successfully, but the animation didn’t work. Even if I replace the opacity manually to 1 nothing happens.

    It should be a css issue, but I can’t figure out what is the problem.

    by Guillermo on
  49. Hi Guillermo,

    I think you have to give the parent div of the images the “position: relative;” property.

    by solemone on
  50. Yes sir!

    Thank you.

    Solemone rocks!

    by Guillermo on

Leave a Reply