Изменение прозрачности изображения с помощью JS или CSS под указателем мыши?

Я хотел бы иметь изображение на веб-странице, которое станет прозрачным при наведении мыши, но прозрачно только в некоторой области, ближайшей к указателю мыши, перемещая эту область с помощью указателя.

Простой переход непрозрачности легко достигается с помощью 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">

Это делает изображение красиво исчезающим на мыши и появляется обратно на мыши.

Но то, что я хотел бы достичь, это тот же эффект только для некоторой области рядом с указателем мыши. Так что всегда будет прозрачная область под указателем, а она перемещается по изображению.

Есть ли способ достичь этого с помощью CSS или JS?

Спасибо!

Ответ 1

Как предложил vals, используйте (произвольную) маску. Ниже приведена демонстрация прямоугольной маски, хотя ее можно легко модифицировать, чтобы быть любой фигурой, которую вы хотите. Эта версия работает с последними версиями Firefox и Chromium и позволяет создавать более сложные формы с помощью элементов SVG.

Обратите внимание, что это очень плохой код. Его нужно будет записать, если вы хотите использовать его в любом проекте, но идея есть.

Демо: 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>

Ответ 2

Вы можете получить это с помощью маскировки. Он имеет ограниченную поддержку, но обеспечивает именно то, что вы хотите

Требуемый 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);
}

и некоторые сценарии, чтобы заставить его двигаться

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";
}

демонстрационный веб-сайт