如何使CSS背景图像变暗但保持光标周围的区域更亮

时间:2018-01-21 02:25:18

标签: javascript jquery css

如何使用CSS或JS使固定的背景更暗但保持光标周围的区域稍微亮一点,这样会产生手电筒类型的效果?似乎无法弄明白。谢谢。

3 个答案:

答案 0 :(得分:1)

编辑:正如@Rob在下面所述,总是先尝试自己回答问题。这只是一个实施建议,不应盲目复制。

我认为你可以用JS创建一个带有径向渐变的CSS元素。



window.onload = function() {
  var flashlight = document.querySelector('#flashlight');
  window.addEventListener('mousemove', function(event) {
    flashlight.style.left = (event.pageX-25) + 'px';
    flashlight.style.top = (event.pageY-25) + 'px';
  });
};

body, html {
  margin: 0;
  padding: 0;
  background-image: url('https://scontent-lga3-1.xx.fbcdn.net/v/t1.0-9/12140762_1159067420823544_4471328164031495581_n.jpg?oh=78a75ea8fe74295d8087eff97dbcef5a&oe=5AF0967D');
  background-size: cover;
  height: 100%;
}
#mask {
  position: absolute;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
}
#flashlight {
  height: 50px;
  width: 50px;
  position: absolute;
  background-image: radial-gradient(white 0%, transparent 50%);
}

<!-- darken background -->
<div id='mask'></div>

<!-- flashlight effect -->
<div id='flashlight'></div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

修改

@ LambdaNinja的解决方案是一个很好的起点,但这看起来并不像真正的火炬。 Pen @JoshAdams posted in a comment越来越接近,但仍有改进的余地。

由于这个问题已经创建了几天,我觉得现在发布一个有效的解决方案很好,因为我很想知道这种效果在使用CSS时有多么现实。

我使用了CSS variablesbackground-blend-modeCSS animations

&#13;
&#13;
const W = window.innerWidth;
const H = window.innerHeight

function updateAnimationTiming() {
  const animationDuration = 5 + Math.random() * 5; // [5 - 10)
  const animationDelay = 5 + Math.random() * 10; // [5 - 15)
  
  window.requestAnimationFrame(() => {
    document.documentElement.style.setProperty('--animationDuration', animationDuration + 's');
    document.documentElement.style.setProperty('--animationDelay', animationDelay + 's');
  });
  
  const timeout = (animationDuration + animationDelay) * 1000 - 100;
  
  setTimeout(updateAnimationTiming, timeout);
}

updateAnimationTiming();

document.addEventListener('mousemove', e => {
  window.requestAnimationFrame(() => {
    const X = e.clientX;
    const Y = e.clientY;

    document.documentElement.style.setProperty('--cursorX', X + 'px');
    document.documentElement.style.setProperty('--cursorY', Y + 'px');

    const X2 = X - (12 * W / 100) * (X / W - 0.5);
    const Y2 = Y - (12 * W / 100) * (Y / H - 0.5);

    document.documentElement.style.setProperty('--cursorX2', X2 + 'px');
    document.documentElement.style.setProperty('--cursorY2', Y2 + 'px');
  });
});
&#13;
:root {
  cursor: crosshair;
  --cursorX: 50vw;
  --cursorY: 50vh;
  --cursorX2: 50vw;
  --cursorY2: 50vh;
  --animationDuration: 10s;
  --animationDelay: 15s;
}

:root:before {
  content: '';
  position: fixed;
  display: block;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-blend-mode: normal, overlay;
  background-position: center center;
  background-size: auto, auto, cover;
  background-image:
    radial-gradient(
      circle 16vmax at var(--cursorX2) var(--cursorY2),
      rgba(0,0,0,0) 30%,
      rgba(0,5,5,.1) 40%,
      rgba(5,5,0,.5) 60%,
      rgba(0,0,0,.75) 70%,
      rgba(0,0,0,.95) 100%
    ),
    radial-gradient(
      circle 12vmax at var(--cursorX) var(--cursorY),
      rgba(255,255,255,1) 30%,
      rgba(255,255,255,.3) 50%,
      rgba(255,255,255,.05) 100%
    ),
    url(https://handluggageonly.co.uk/wp-content/uploads/2016/01/Sewers-of-Paris-2.jpg);

  animation: torch var(--animationDuration) linear var(--animationDelay) infinite alternate;
}

@keyframes torch {
    0%, 1%, 2%, 3%, 4%, 5%, 20%, 21%, 60%, 61%, 62%, 100% { background-image:
      radial-gradient(
        circle 16vmax at var(--cursorX2) var(--cursorY2),
        rgba(0,0,0,0) 30%,
        rgba(0,5,5,.1) 40%,
        rgba(5,5,0,.5) 60%,
        rgba(0,0,0,.75) 70%,
        rgba(0,0,0,.95) 100%
      ),
      radial-gradient(
        circle 12vmax at var(--cursorX) var(--cursorY),
        rgba(255,255,255,1) 30%,
        rgba(255,255,255,.3) 50%,
        rgba(255,255,255,.05) 100%
      ),
      url(https://handluggageonly.co.uk/wp-content/uploads/2016/01/Sewers-of-Paris-2.jpg);
    }
  
    0.5%, 1.5%, 60.5% { background-image:
      radial-gradient(
        circle 12vmax at var(--cursorX2) var(--cursorY2),
        rgba(0,0,0,0) 30%,
        rgba(0,5,5,.1) 40%,
        rgba(5,5,0,.5) 60%,
        rgba(0,0,0,.75) 70%,
        rgba(0,0,0,.95) 100%
      ),
      radial-gradient(
        circle 8vmax at var(--cursorX) var(--cursorY),
        rgba(255,255,255,1) 30%,
        rgba(255,255,255,.3) 50%,
        rgba(255,255,255,.05) 100%
      ),
      url(https://handluggageonly.co.uk/wp-content/uploads/2016/01/Sewers-of-Paris-2.jpg);
    }
  
    2.5%, 3.5%, 4.5%, 20.5%, 61.5% { background-image:
      radial-gradient(
        circle 8vmax at var(--cursorX) var(--cursorY),
        rgba(0,0,0,0) 30%,
        rgba(0,5,5,.1) 40%,
        rgba(5,5,0,.5) 60%,
        rgba(0,0,0,.75) 70%,
        rgba(0,0,0,.95) 100%
      ),
      radial-gradient(
        circle 4vmax at var(--cursorX) var(--cursorY),
        rgba(255,255,255,1) 0%,
        rgba(255,255,255,.5) 50%,
        rgba(255,255,255,.05) 100%
      ),
      url(https://handluggageonly.co.uk/wp-content/uploads/2016/01/Sewers-of-Paris-2.jpg);
    }
}
&#13;
&#13;
&#13;

您也可以在此处访问它:https://codepen.io/Danziger/pen/VyOZpy

请注意,它有一些限制,因为叠加层将覆盖所有页面,因此效果仅限于背景图像和添加到其中的不同渐变。即使您使用<div>替换伪元素并在其中添加内容,该内容也不会受混合模式的影响。但是,可以使用mix-blend-mode来实现这一目标。

原始答案:

只需使用<div>或伪元素(::before::after)创建叠加层,并将其设置为&#34;火炬&#34; /&#34;突出显示&# 34;使用CSS。我建议使用阴影,渐变或两者的组合,具体取决于所需的结果。

然后,使用JS,您可以跟踪光标的位置,并在其后面移动该叠加层或更改其CSS属性&#39;值(可能使用CSS variables,具体取决于您的浏览器支持需求),具体取决于您的实现。

如果你选择前者,理想情况下你应该使用window.requestAnimationFrame()以便在不损害性能的情况下获得更平滑的过渡。

尝试自己实现,如果您遇到实施问题,请返回并针对该特定问题创建另一个问题。正如一些人在评论中指出的那样,我们不应该为你编写代码,特别是当你以前没有尝试过(或者至少你没有提供任何证据)。

答案 2 :(得分:0)

使用CSS的选项并不多。您可以查看this link,其中详细说明了您可以使用的所有游标类型。但这些与您的用例无关,因为它只是更改图标。

您可能需要查看JS解决方案以跟踪光标位置。 Check out this StackOverflow answer.

在知道光标所在的位置后,可以创建一个div:

#cursor-background {
    border-radius: 50%;
    height: 20px;
    width: 20px;
    position: absolute;
    background-color: rgba(255, 255, 255, 0.2);
}

然后您可以尝试使用以下方法更改此div的位置:

document.getElementById("cursor-background").style.transform = "translate(“ + X + “,” + Y + “)";

X和Y是您在屏幕上所需的位置。

为避免它看起来有点跳跃,请在“cursor-background”的CSS中添加一个transition属性:

 transition: all 0.1s ease-in-out;

我还没有测试过这些,只是试图提供关于你应该采取哪个方向的指导。

至于背景,请选择您想要的颜色。手电筒效果将来自悬停在黑暗背景上的灯光。