Ответ 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>