Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. Ideally this would degrade to just an image if JavaScript is disabled and could be fluid in width (responsive).

like image 538
Confused One Avatar asked Dec 09 '22 16:12

Confused One


1 Answers

border-radius

CSS3 border-radius can be used to create a round div with a background image which serves as the image spotlight. The spotlight can be overlaid on top of the main image, and positioned based on the mouse coordinates. JSFiddle Demo

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. 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

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

Alternative implementations

This could also be implemented using HTML5 Canvas or SVG. Below is a browser-support comparison of the different approaches:

  • border-radius: Not supported by IE8 or earlier.
  • HTML5 Canvas: Not supported by IE8 or earlier.
  • SVG: Not supported by IE8 or earlier, or Android 2.3 or earlier (which is still most of the Android marketshare).

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. Of course, since this is mouse-based, Android support may not be a factor anyhow.

like image 108
Matt Coughlin Avatar answered Dec 11 '22 05:12

Matt Coughlin