我有两个版本的图像:去饱和版本和全彩版本。我想要完成的是悬停效果,其中将鼠标悬停在去饱和图像上会显示图像彩色版本的圆圈。这有点像将聚光灯照射在去饱和图像上以显示其颜色。然后,当您将鼠标移开时,它会逐渐恢复到去饱和状态。
我知道我可能会使用 flash,但我想用 JavaScript 和 CSS 来做这件事。理想情况下,如果禁用 JavaScript 并且宽度可能是流动的(响应式),这将降级为仅图像。
我有两个版本的图像:去饱和版本和全彩版本。我想要完成的是悬停效果,其中将鼠标悬停在去饱和图像上会显示图像彩色版本的圆圈。这有点像将聚光灯照射在去饱和图像上以显示其颜色。然后,当您将鼠标移开时,它会逐渐恢复到去饱和状态。
我知道我可能会使用 flash,但我想用 JavaScript 和 CSS 来做这件事。理想情况下,如果禁用 JavaScript 并且宽度可能是流动的(响应式),这将降级为仅图像。
CSS3border-radius
可用于创建带有背景图像的圆形 div,用作图像聚光灯。聚光灯可以覆盖在主图像之上,并根据鼠标坐标定位。JSFiddle 演示
尽管在 CSS3 中没有自然的方式来柔化聚光灯的边缘——这需要支持向任意内容添加不透明度渐变——但可以使用一组交错的元素来模拟,这些元素具有增加的半径和降低的不透明度。更新了带有软化边缘的演示
在更新的演示中,聚光灯的大小和柔和度可以使用以下变量进行调整:
var spotlightDiameter = 150; // Base size (not including the soft edge)
var numSpotlightLayers = 6; // More layers = softer edges
var spotlightLayerThickness = 2; // Thinner = the softening is more subtle
这是一个修改后的演示,其中聚光灯有明显的涟漪。增加了层的厚度,以更清楚地显示它是如何工作的。
下面是带有锐边的初始版本的代码的简化版本。
HTML
<div class="content">
<div class="spotlight"></div>
</div>
CSS
.content {
position: relative;
width: 640px;
height: 480px;
background: url(desaturated.jpg) no-repeat 0 0;
overflow: hidden;
}
.spotlight {
display: none;
position: absolute;
background: url(overly_saturated.jpg) no-repeat 0 0;
}
jQuery
var spotlightDiameter = 150;
// Update the spotlight position on mousemove
$('.content').on('mousemove', function(e){
var center = {x: e.pageX - this.offsetLeft,
y: e.pageY - this.offsetTop};
var x = center.x - (spotlightDiameter >> 1);
var y = center.y - (spotlightDiameter >> 1);
$('.spotlight').css({left: x + 'px', top: y + 'px',
backgroundPosition: -x + 'px ' + -y + 'px'}).show();
});
// Hide the spotlight on mouseout
$('.content').on('mouseout', function(e){
$('.spotlight').hide();
});
// Initialize the spotlight
$(document).ready(function(){
$('.spotlight').width(spotlightDiameter + 'px')
.height(spotlightDiameter + 'px')
.css({borderRadius: (spotlightDiameter >> 1) + 'px'});
});
这也可以使用 HTML5 Canvas 或 SVG 来实现。下面是不同方法的浏览器支持比较:
border-radius
: IE8 或更早版本不支持。简而言之,IE8 和更早版本不是这些方法中的任何一个选项,如果需要 Android 支持,则将选择限制为border-radius
HTML5 Canvas。当然,由于这是基于鼠标的,Android 支持可能不是一个因素。
<image>
使用两个完全重叠的SVG元素。底部是灰度图像。顶部是彩色图像。将 aclipPath
应用于彩色图像,然后调整剪切路径上的变换以显示上部图像的不同区域。
SVG:
<svg xmlns="http://www.w3.org/2000/svg" width="200px" height="250px">
<defs>
<image id="im" width="500" height="500"
xlink:href="http://www.nyweamet.org/wp-content/uploads/2011/09/0942a__grandCentralStationExterior.jpg"/>
<clipPath id="clip">
<path id="path" transform="translate(40,60)"
d="M60,0 A30,30 1,0,0 60,120 30,30 1,0,0, 60,0"/>
</clipPath>
</defs>
<use id="clippedImage" xlink:href="#im" clip-path="url(#clip)"/>
</svg>
和移动圆圈的 JavaScript:
var tx = document.querySelector('#path').transform.baseVal.getItem(0);
setInterval(function(){
var ms = (new Date)*1;
tx.matrix.e = Math.sin(ms/812)*150 + 160;
tx.matrix.f = Math.cos(ms/437)*60 + 70;
},50);
您所要做的就是跟踪鼠标移动并将翻译设置到正确的位置。
如果我正确理解了您的要求,您可以使用一些 CSS 来实现结果。我在这里准备了一个小小提琴作为演示:http: //jsfiddle.net/sandro_paganotti/k3AmZ/
这是涉及的代码:
<figure data-desaturated></figure>
<figure data-original></figure>
figure{ width: 550px; height: 360px;
position: absolute; top: 0; left: 0;
margin: 0; padding: 0;
background-position: 50% 50%;
background-repeat: no-repeat;
background-image: url('yourimage.png');
}
figure[data-desaturated]{
/* I've used CSS filters tu simulate desaturation, you can use your already desaturated image */
-webkit-filter: grayscale(0.9);
}
figure[data-original]{
width: 360px;
left: 95px;
border-radius: 180px;
opacity: 0;
transition: opacity 0.4s;
}
figure[data-desaturated]:hover + figure[data-original],
figure[data-original]:hover{
opacity: 1;
}
我还添加了一个transition
来增强体验。
跟随鼠标移动的版本:http: //jsfiddle.net/sandro_paganotti/k3AmZ/3/