CSS3 spotlight effect using a rounded rectangle with gradients

匆匆过客 提交于 2019-12-05 15:45:45

Vals gave an excellent answer, and gave me a great hint to figure out a simple way to get exactly what I wanted. This effect can be achieved with an inset box shadow plus a regular one, and has the added benefit that the spotlight box need only be repositioned to highlight a particular area instead of redrawing a CSS gradient.

Here's the code:

.overlay {
  position: absolute;
  left: 50px;
  top: 50px;
  width: 200px;
  height: 200px;
  border-radius: 20px;  
  box-shadow: 0px 0px 4px 10px rgba(0,0,0,0.5) inset, 0px 0px 0px 1000px rgba(0,0,0,0.5)
}

One can tweak the parameters to make the gradient border softer or more dramatic, and how much it pokes into the spotlight.

Check out the following:

You can do that with gradients, but achieving the rounded rectangle will be hard.

One easier way is just using box shadow

.overlay {
  position: absolute;
  left: 50px;
  top: 50px;
  width: 200px;
  height: 200px;
  border-radius: 20px;

  box-shadow: 0px 0px 0px 1000px rgba(255, 255, 255, 0.5);
}

.overlay:after {
  content: '';
  position: absolute;
  left: -25px;
  top: -25px;
  right: -25px;
  bottom: -25px;
  border: solid 1px gray;
  border-radius: 25px;
  box-shadow: 0px 0px 0px 1000px rgba(255, 255, 255, 0.6);
}

This way the rounded corners are easy. I have set a pseudo element to make it more elegant; this way you get 2 levels of transparency. You could elaborate it further using the remaining pseudo element, and also with an inset shadow.

demo

an alternate approach using gradients (no rounded corners, but not a bad effect anyway):

.overlay2 {
  position: absolute;
  left: 40px;
  top: 50px;
  width: 200px;
  height: 200px;
  border-radius: 40px;
  border: solid 1px gray;
  background-image: linear-gradient(90deg,white,transparent 25%, transparent 75%, white), linear-gradient(0deg,white,transparent 25%, transparent 75%, white);
  background-size: 100% 50%, 50% 100%;
  box-shadow: 0px 0px 0px 1000px white;
}

demo2

This is the non CSS3 solution. The solution uses a 10% transparency black background png, the spotlight is added as image down below.

HTML

<div class="spotlightContainer">
    <div class="imageContainer">
        <img src="/images/tuinderlusten.jpg" alt="de tuin der lusten"/>
    </div>
    <div class="darkCover">
        <div class="dark darktop"> </div>
        <div class="darkmiddle">
            <div class="dark darkleft"> </div>
            <div class="spotlight"> </div>
            <div class="dark darkright"> </div>
        </div>
        <div class="dark darkbottom"> </div>
    </div>
</div>

JavaScript

var darkRight, darkLeft, darkBottom, darkTop, darkMiddle, containerHeight, containerWidth;

$(function(){
    containerWidth = $(".spotlightContainer").width();
    containerHeight = $(".spotlightContainer").height();
    darkTop = $(".darktop");
    darkBottom = $(".darkbottom");
    darkLeft = $(".darkleft");
    darkRight = $(".darkright");
    darkMiddle = $(".darkmiddle");
    darkTop.height(100-50);
  darkBottom.height(containerHeight-100-50);
  darkLeft.width(100-50);
  darkRight.width(containerWidth-100-50);
    setSpotlight(100, 100);
    $(".spotlightContainer").on("mousemove", function(e){
        setSpotlight(e.pageX, e.pageY);
    });
});

var setSpotlight = function(pageX, pageY){
    var radius = 100;
        darkMiddle.height(radius*2);
        if(pageX < radius){
            pageX = radius;
        } else if (pageX > containerWidth -radius){
            pageX = containerWidth -radius;
        }
        darkTop.height(pageY-radius);
        darkBottom.height(containerHeight-pageY-radius);
        darkLeft.width(pageX-radius);
        darkRight.width(containerWidth-pageX-radius);
}

CSS

html, body{
    width: 100%;
    height: 100%;
    margin: 0 0 0 0;
    padding: 0 0 0 0;
}

div{
    margin: 0 0 0 0;
    padding: 0 0 0 0;
    border: 0;
}

body{
    overflow: hidden;
}

.dark{
    background: url("/images/darkcover.png");
}

.darktop{
    width: 100%;
    height: 100%;
}

.darkbottom{
    width: 100%;
    height: 0px;
}

.darkmiddle{
    height:0px;
    width: 100%;
}

.darkmiddle div{
    float: left;
    height: 100%;
}

.darkleft{
    width: 200px;
}

.darkright{
    width: 200px;
}

.spotlight{
    width: 200px;
    background: url("/images/spotlight.png");
    background-size: cover;
}

.spotlightContainer{
    width: 100%; height: 100%; z-index: 500; position: fixed;
}

.spotlightContainer .imageContainer, .spotlightContainer .darkCover{
    width: 100%; height: 100%; position: absolute; top: 0; left: 0;
}

.spotlightContainer .imageContainer{
    max-height: 100%;   max-width: 100%; width: 100%;
}

The spotlight image

I tested this and it works on all modern and IE7+ desktop browsers.

I have write a tiny jQuery plugin that create four div and place it arround your zone / element.

Even if it's not the answer you want don't vote down it's a first idea for your futur script.

var element = $("#element1").intro();
$("#element1").click(function() {
    element.intro('moveTo', $("#element2"), 500);
});

http://jsfiddle.net/DoubleYo/DQ6jj/

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!