Change the color of the image to black and white and then back to its original state when a specific element is hovered over

Searching for a jQuery plugin to convert an image to black and white? Look no further! I've explored various options, but none quite fit the bill. What I'm really after is an effect that will revert the image back to color when a specific element is hovered over.

Currently, I am using this plugin:

(function ($) {
$.fn.extend({
    BlackAndWhite: function (options) {
        'use strict';
        var container = this,
            self = this,
            defaults = {
                hoverEffect: true,
                webworkerPath: false,
                responsive: true,
                invertHoverEffect: false,
                speed: 500
            };
            options = $.extend(defaults, options);
        //@public vars
        var hoverEffect = options.hoverEffect,
            webworkerPath = options.webworkerPath,
            invertHoverEffect = options.invertHoverEffect,
            responsive = options.responsive,
            fadeSpeedIn = $.isPlainObject(options.speed) ? options.speed.fadeIn : options.speed,
            fadeSpeedOut = $.isPlainObject(options.speed) ? options.speed.fadeOut : options.speed;
        //@private var
        var supportsCanvas = !!document.createElement('canvas').getContext,
            $window = $(window);
        /* Check if Web Workers are supported */
        var supportWebworker = (function () {
                return (typeof (Worker) !== "undefined") ? true : false;
            }());

        var isIE7 = $.browser.msie && +$.browser.version === 7;
        //@private methods
        //convert any image into B&W using HTML5 canvas
        var greyImages = function (img, canvas, width, height) {
            var ctx = canvas.getContext('2d'),
                currImg = img,
                i = 0,
                grey;

            ctx.drawImage(img, 0, 0, width, height);

            var imageData = ctx.getImageData(0, 0, width, height),
                px = imageData.data,
                length = px.length;

            // web worker superfast implementation
            if (supportWebworker && webworkerPath) {

                var BnWWorker = new Worker(webworkerPath + "BnWWorker.js");

                BnWWorker.postMessage(imageData);

                BnWWorker.onmessage = function (event) {
                    ctx.putImageData(event.data, 0, 0);
                };
            } else {

                // no webworker slow implementation
                for (; i < length; i += 4) {
                    grey = px[i] * 0.3 + px[i + 1] * 0.59 + px[i + 2] * 0.11;
                    px[i] = px[i + 1] = px[i + 2] = grey;
                }

                ctx.putImageData(imageData, 0, 0);
            }
        };

        var injectTags = function (pic, currImageWrapper) {

            var src = pic.src;

            if (supportsCanvas && (!($.browser.msie && $.browser.version == '9.0'))) {

                var currWidth = $(currImageWrapper).find('img').width(),
                    currHeight = $(currImageWrapper).find('img').height(),
                    realWidth = pic.width,
                    realHeight = pic.height;

                //adding the canvas
                $('<canvas width="' + realWidth + '" height="' + realHeight + '"></canvas>').prependTo(currImageWrapper);
                //getting the canvas
                var currCanvas = $(currImageWrapper).find('canvas');
                //setting the canvas position on the Pics
                $(currCanvas).css({
                    'position': 'absolute',
                    top: 0,
                    left: 0,
                    width: currWidth,
                    height: currHeight,
                    display: invertHoverEffect ? 'none' : 'block'
                });

                greyImages(pic, currCanvas[0], realWidth, realHeight);

                if (hoverEffect) {
                    $(currImageWrapper).mouseenter(function () {
                        if(!invertHoverEffect) {
                            $(this).find('canvas').stop(true, true).fadeOut(fadeSpeedOut);
                        } else {
                            $(this).find('canvas').stop(true, true).fadeIn(fadeSpeedIn);
                        }
                    });
                    $(currImageWrapper).mouseleave(function () {
                        if(!invertHoverEffect) {
                            $(this).find('canvas').stop(true, true).fadeIn(fadeSpeedIn);
                        } else {
                            $(this).find('canvas').stop(true, true).fadeOut(fadeSpeedOut);
                        }
                    });
                }
            } else {

                var ieWidth = $(currImageWrapper).find('img').prop('width');
                var ieHeight = $(currImageWrapper).find('img').prop('height');

                //adding the canvas
                $('<img src=' + src + ' width="' + ieWidth + '" height="' + ieHeight + '" class="ieFix" /> ').prependTo(currImageWrapper);
                $('.ieFix').css({
                    'position': 'absolute',
                    top: 0,
                    left: 0,
                    'filter': 'progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)',
                    display: invertHoverEffect ? 'none' : 'block'
                });

                if (hoverEffect) {
                    $(currImageWrapper).mouseenter(function () {
                        if(!invertHoverEffect) {
                            $(this).children('.ieFix').stop(true, true).fadeOut(fadeSpeedOut);
                        } else {
                            $(this).children('.ieFix').stop(true, true).fadeIn(fadeSpeedIn);
                        }
                    });
                    $(currImageWrapper).mouseleave(function () {
                        if(!invertHoverEffect) {
                            $(this).children('.ieFix').stop(true, true).fadeIn(fadeSpeedIn);
                        } else {
                            $(this).children('.ieFix').stop(true, true).fadeOut(fadeSpeedOut);
                        }
                    });
                }
            }
        };
        this.init = function (options) {

            $(container).each(function (index, currImageWrapper) {
                var pic = new Image();
                pic.src = $(currImageWrapper).find('img').prop("src");

                if (!pic.width) {
                    $(pic).on("load", function() {injectTags( pic, currImageWrapper);});
                } else {
                    injectTags( pic, currImageWrapper );
                }
            });


            if (responsive) {
                $window.on('resize orientationchange', container.resizeImages);
            }
        };

        this.resizeImages = function () {

            $(container).each(function (index, currImageWrapper) {
                var pic = $(currImageWrapper).find('img:not(.ieFix)');
                var currWidth,currHeight;
                if (isIE7) {
                    currWidth = $(pic).prop('width');
                    currHeight = $(pic).prop('height');
                } else {
                    currWidth = $(pic).width();
                    currHeight = $(pic).height();
                }

                $(this).find('.ieFix, canvas').css({
                    width: currWidth,
                    height: currHeight
                });

            });
        };

        return self.init(options);

    }

});
}(jQuery));

Answer №1

To achieve the effect of turning an image black and white using CSS3, you can follow these steps. Let's assume the image has a class called "Picture":

img.Picture{
-webkit-filter: grayscale(100%);
-moz-filter: grayscale(100%);
filter: grayscale(100%);
}

To revert the image back to color when hovering over it, you can use the following code:

img.Picture:hover{
-webkit-filter: grayscale(0%);
-moz-filter: grayscale(0%);
filter: grayscale(0%);
}

Answer №2

To achieve the same effect using Jquery, follow these steps:

If you want to turn an image black and white on document ready, use this code:

$('document').ready(function(){
 $("img.Image").css({'-webkit-filter':'grayscale(100%)','-moz- filter':'grayscale(100%)','filter': 'grayscale(100%)'});    
});

Next, if you want to change the image on hover, use the following code:

$("img.Image").on('hover',function(){
$(this).css({'-webkit-filter':'grayscale(0%)','-moz-filter':'grayscale(0%)','filter':'grayscale(0%)'});
},function(){
$(this).css({'-webkit-filter':'grayscale(100%)','-moz-filter':'grayscale(100%)','filter': 'grayscale(100%)'});
}
);

Answer №3

How to convert an image to grayscale using HTML/CSS provides a method for greyscaling images in Firefox by averaging the red, green, and blue components. However, this may not result in the desired luminance effect. A better approach is to utilize the desaturating filter as shown below:

<svg xmlns="http://www.w3.org/2000/svg">
  <filter id="gray">
    <feColorMatrix type="saturate" values="0"/>
  </filter>
</svg>

To apply the filter, use

filter: url(grayscale.svg#grayscale);
in your CSS. For simpler documents, you can include the HTML, CSS, and SVG within the same file.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Stepping up your design game by customizing the bootstrap container class for multiple pages

Looking for a solution to customize container-width, @gutter-width, and @column-width for two pages - landing and home? Let's discuss how to achieve this. Currently using less framework and merging all less files for production code deployment. Need ...

Having trouble with the full-screen feature not functioning properly?

I am currently in the process of creating a custom video player and I need to include a full-screen button. However, when I click on it, the video does not expand to fill up the entire screen. I am using javascript, css3, and html5 for this project. Any as ...

Using JavaScript to create customized checkboxes is a useful way to

I am looking to develop a JavaScript code that saves all the checkboxes selected by a user. When the user clicks on the finish button, the code should display what they have chosen (text within the label). Admittedly, I am unsure of how to proceed and wou ...

Reordering Divs in Bootstrap 3 Specifically for Small Screens

Just getting started with my first responsive design project, and I'm wondering if it's possible to achieve something like this using Bootstrap 3. The goal is to switch from the current layout: https://i.stack.imgur.com/lABXp.jpg To https://i. ...

Why is this regular expression failing to match German words?

I am attempting to separate the words in the following sentence and enclose them in individual span elements. <p class="german_p big">Das ist ein schönes Armband</p> I came across this: How to get a word under cursor using JavaScript? $(&ap ...

Using jQuery to control mouseenter and mouseleave events to block child elements and magnify images

My objective is to create a hover effect for images within specific div elements. The images should enlarge when the user hovers their mouse over the respective div element. I plan to achieve this by adding a child element inside each div element. When the ...

Creating a jQuery AJAX form that allows users to upload an image, submit the form, and store the entered values in a MySQL database

I am struggling with an HTML form that I am trying to submit using jQuery's $.ajax(); The form needs to: 1. Upload an image to a directory with error checks 2. Save the image path to a MySQL database 3. Insert two other form values (input and select) ...

Jquery: Transforming Content with Rotator or Slider - Seeking Answers

Hey there, I am currently in the process of revamping a website for a friend over at The current site was quickly put together using Joomla. Quick note: it might be best to mute your sound before visiting the site as there is an obnoxious video that auto ...

Add Content to Textbox by Clicking

In my current setup, I have a variety of buttons that, when clicked, should add the text from the button to a text box. Each time a button is clicked, I want the text to be appended to whatever is already in the input field. Current Approach $('#js- ...

Executing Multiple AJAX Functions with when()

My goal is to use jQuery's when() method to run multiple Ajax functions upon form submission. The plan is to wait for these functions to finish and then finally submit the form. However, it seems like my code is not working as intended: $('form[ ...

The special function fails to execute within an "if" condition

As a newcomer to JavaScript/jQuery and Stack Overflow, I kindly ask for your patience in case there are any major errors in my approach. I am currently developing an HTML page with Bootstrap 3.3.7, featuring a pagination button group that toggles the visib ...

use angularjs directive to position a div absolutely aligned with the right edge of another div

I am attempting to use an angularjs directive to align the right side of an absolute div with another div. The code is working, but I am encountering an issue where the children divs are slightly wider than their parent, causing the offsetWidth value to be ...

Guide on how to vertically and horizontally center a heading text with dash-bootstrap

I have implemented the Bootstrap dash layout for my web application, but I want to place the text in the red area instead of at the top of the page. Can anyone guide me on how to achieve this? https://i.sstatic.net/RcNhy.png I have already tried using "a ...

Traverse each child element sequentially using setTimeout or a delay function

Looking to dynamically apply a CSS filter to a list of divs with a delay between each iteration. Here are my attempted solutions: $(this).children().each(function() { $(this).delay(5000).css("-webkit-filter", "brightness(2)"); }); And this alternativ ...

Ways to dynamically update the content of an HTML table without the need to reload the page

I'm currently working on an HTML table that retrieves data from a database and includes a button for deleting selected records. Here is what the table layout looks like: name phone links john 6562 link1 link2 link3 ___________ ...

Errors from jQuery validation are causing disruptions in my form's functionality

When jQuery validation error messages appear, they take up space and push other fields downwards. I want the error messages to adjust within the available space and not disrupt other fields or elements. Below is the jQuery validation code I'm currentl ...

Adding 7 days to a JavaScript date

Can you spot the bug in this script? I noticed that when I set my clock to 29/04/2011, it displays 36/4/2011 in the week input field! The correct date should actually be 6/5/2011 var d = new Date(); var curr_date = d.getDate(); var tomo_date = d.getDate( ...

Exploring data-toggle elements using jQuery

I am faced with the challenge of dynamically constructing a form using jQuery. The form includes a checkbox list of items that I am creating in the following manner: function initializeForm() { var html = ''; var items = GetItems(); for ( ...

The request response was a JSON object that started with the keyword "POST"

My frustration is growing as I encounter a strange issue with the stack template I purchased from envato market. Every time I attempt a simple ajax request, the json returned from my PHP script seems to be invalid. Interestingly, the exact same code works ...

Introducing unnecessary DOM elements when displaying flash messages

When a user saves in my Rails application, it triggers an Ajax request to save the post and then runs the update.js.erb file. This file contains some jQuery code: $('body').append('<div class="message">Saved</div>'); Due t ...