Search code examples
javascriptcsstransparencyopacitymouse-cursor

Changing image opacity with JS or CSS under mouse pointer?


I would like to have an image on the web page, which will became transparent on mouse hover, but transparent only in some area nearest to mouse pointer, moving that area with the pointer.

Simple opacity transition can be easily achieved with CSS:

    <style type="text/css">
        img.transparent {
            opacity: 1;
            -webkit-transition: opacity 1s;
            -moz-transition: opacity 1s;
            transition: opacity 1s;
        }
        img.transparent:hover {
            opacity: 0;
        }
    </style>
    <img class="transparent" src="1.jpg">

That makes image nicely disappearing on mouse on and appearing back on mouse out.

But what I would like to achieve is the same effect just for some area near the mouse pointer. So that there would be always transparent area under pointer, while it is moving over the image.

Is there a way to achieve that with CSS or JS?

Thank you!


Solution

  • As vals suggested, use an (arbitrary) mask. The following is a demonstration of a rectangular mask, although it can be very easily modified to be any shape that you wish. This version works on the latest versions of both Firefox and Chromium and allows for more complex shapes via SVG elements.

    Note that this is very poor code. It will need to be written if you wish to use it in any project, but the idea is there.

    Demo: http://jsfiddle.net/WK_of_Angmar/f8oe7hcq/

    <!DOCTYPE html>
    <html>
        <head>
            <script type="application/javascript">
                window.addEventListener("load", function() {
                    var img = document.getElementsByTagName("image")[0];
                    var imgPos = img.getBoundingClientRect();
                    var imgX = imgPos.left;
                    var imgY = imgPos.top;
                    var rect = document.getElementsByTagName("rect")[1];
                    var rectHalfWidth = rect.getAttribute("width") / 2;
                    var rectHalfHeight = rect.getAttribute("height") / 2;
                    img.addEventListener("mousemove", function(e) {
                        rect.setAttribute("x", e.clientX - imgX - rectHalfWidth);
                        rect.setAttribute("y", e.clientY - imgY - rectHalfHeight);
                        }, false);
                }, false);
            </script>
            <style>
                svg {
                    width: 320px;
                    height: 166px;
                }
                body {
                    background-color: red;
                    background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/7/76/Mozilla_Firefox_logo_2013.svg/226px-Mozilla_Firefox_logo_2013.svg.png");
                }
                image:hover {
                    mask: url("#cursorMask");
                }
            </style>
        </head>
        <body>
            <svg>
                <defs>
                    <mask id="cursorMask" maskUnits="objectBoundingBox" maskContentUtils="objectBoundingBox">
                        <g>
                        <!-- the SECOND rect element is what determines the transparent area -->
                        <rect x="0" y="0" width="320" height="166" fill="#FFFFFF" />
                        <rect x="0" y="0" width="100" height="100" fill="#000000" />
                        </g>
                    </mask>
                </defs>
            <image width="320" height="166" xlink:href="https://upload.wikimedia.org/wikipedia/commons/d/d4/Firefox-33-xfce.png" />
            </svg>
        </body>
    </html>