简体   繁体   English

创建圆形鼠标悬停饱和效果

[英]Creating a circular mouseover saturation effect

I have two versions of an image: a desaturated version and a full color version. 我有两个版本的图像:去饱和版和全彩版。 What I want to accomplish is a hover effect in which mousing over the desaturated image reveals a circle of the color version of the image. 我想要实现的是悬停效果,其中鼠标在去饱和图像上显示出图像颜色版本的圆圈。 It would be sort of like shining a spotlight on the desaturated image to show its color. 这有点像在不饱和图像上闪耀聚光灯以显示其颜色。 And then when you move the mouse away, it would fade back to its desaturated state. 然后当你移开鼠标时,它会逐渐消失回去饱和状态。

I know I could probably use flash, but I'd like to do this with JavaScript and CSS. 我知道我可能会使用flash,但我想用JavaScript和CSS来做这件事。 Ideally this would degrade to just an image if JavaScript is disabled and could be fluid in width (responsive). 理想情况下,如果JavaScript被禁用并且宽度可以是流动的(响应),这将降低为仅图像。

border-radius 边界半径

CSS3 border-radius can be used to create a round div with a background image which serves as the image spotlight. CSS3 border-radius可用于创建带有背景图像的圆形div,该背景图像用作图像聚光灯。 The spotlight can be overlaid on top of the main image, and positioned based on the mouse coordinates. 聚光灯可以叠加在主图像的顶部,并根据鼠标坐标定位。 JSFiddle Demo JSFiddle演示

Although there's no natural way to soften the edges of the spotlight in CSS3 -- which would require support for adding an opacity gradient to arbitrary content -- it can be simulated using a staggered set of elements with increasing radius and decreasing opacity. 虽然没有自然的方法来软化CSS3中聚光灯的边缘 - 这需要支持向任意内容添加不透明度渐变 - 但可以使用交错的元素集来模拟半径增加和不透明度降低。 Updated demo with softened edges 更新了带有软化边缘的演示

In the updated demo , the size and softness of the the spotlight can be adjusted using the following variables: 更新的演示中 ,可以使用以下变量调整聚光灯的大小和柔和度:

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

Here's a modified demo where the spotlight has noticeable ripples. 这是一个经过修改的演示 ,其中聚光灯有明显的涟漪。 The thickness of the layers was increased to show more clearly how it works. 增加层的厚度以更清楚地显示其工作原理。

Below is a simplified version of the code for the initial version with sharp edges. 下面是具有锐边的初始版本的代码的简化版本。

HTML HTML

<div class="content">
    <div class="spotlight"></div>
</div>

CSS 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 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'});
});

Alternative implementations 替代实施

This could also be implemented using HTML5 Canvas or SVG. 这也可以使用HTML5 Canvas或SVG实现。 Below is a browser-support comparison of the different approaches: 以下是不同方法的浏览器支持比较:

In short, IE8 and earlier is not an option for any of these approaches, and if Android support is needed, that limits the choices to border-radius and HTML5 Canvas. 简而言之,IE8及更早版本不适用于任何这些方法,如果需要Android支持,则会限制对border-radius和HTML5 Canvas的选择。 Of course, since this is mouse-based, Android support may not be a factor anyhow. 当然,由于这是基于鼠标的,因此Android支持可能不是一个因素。

Use two SVG <image> elements overlaid exactly on top of one another. 使用两个SVG <image>元素完全叠加在一起。 The bottom is the greyscale image. 底部是灰度图像。 The top is the color image. 顶部是彩色图像。 Apply a clipPath to the color image, and then adjust the transform on the clipping path to reveal different areas of the upper image. clipPath应用于彩色图像,然后调整剪切路径上的变换以显示上部图像的不同区域。

Simple Demo: http://jsfiddle.net/hZgkz/ 简单演示: http//jsfiddle.net/hZgkz/

SVG: 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>

and the JavaScript that moves the circle around: 以及移动圆圈的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); 

All you have to do is track the mouse movement and set the translation to the right spot. 您所要做的就是跟踪鼠标移动并将转换设置到正确的位置。

You can use some CSS to achieve the result, if I have understood correctly your request. 如果我已正确理解您的请求,您可以使用一些CSS来实现结果。 I've prepared a small fiddle as a demo here: http://jsfiddle.net/sandro_paganotti/k3AmZ/ 我在这里准备了一个小小提琴作为演示: http//jsfiddle.net/sandro_paganotti/k3AmZ/

Here's the code involved: 这是涉及的代码:

HTML HTML

<figure data-desaturated></figure>
<figure data-original></figure>

CSS CSS

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

I've also added a transition to enhance the experience. 我还添加了一个transition来增强体验。

Update 更新

Version that follows mouse movements: http://jsfiddle.net/sandro_paganotti/k3AmZ/3/ 跟随鼠标移动的版本: http//jsfiddle.net/sandro_paganotti/k3AmZ/3/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM