Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 752
Andrey Gusakov Avatar asked Dec 19 '14 17:12

Andrey Gusakov


2 Answers

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>
like image 188
Wk_of_Angmar Avatar answered Oct 15 '22 07:10

Wk_of_Angmar


You can get this using masking. It has limited support, but provides exactly what you want

The required CSS

#test {
    top: 0px;
    left: 0px;
    -webkit-mask-position: -20px -20px;
    -webkit-mask-size: 200px 400px;
    -webkit-mask-image: radial-gradient(circle, rgba(0, 0, 0, 0) 32px, rgba(0, 0, 0, 1) 38px);
    background-color: white;
    border: solid 1px red;
    width: 200px;
    height: 200px;
    background-image: url('http://placekitten.com/g/200/300');
}

body {
    background: repeating-linear-gradient(45deg, lightgreen 0px, white 50px);
}

and some scripting to get it moving

document.getElementById("test").addEventListener('mousemove', mouseMove, false);

function mouseMove (event)
{
    var ele = document.getElementById ('test');

    ele.style.webkitMaskPositionX = event.offsetX - 100 + "px";
    ele.style.webkitMaskPositionY = event.offsetY + 200 + "px";
}

demo - only webkit

like image 25
vals Avatar answered Oct 15 '22 05:10

vals