Skip to content Skip to sidebar Skip to footer

How To Darken A Css Background Image But Keep Area Around Cursor Brighter

How can I use CSS or JS to make a fixed background darker but keep the area around the cursor slightly lighter so it gives a flashlight type effect ? Cant seem to figure it out. Th

Solution 1:

Just create an overlay using a <div> or a pseudoelement (::before or ::after) and style it as your "torch" / "highlight" 🔦 using CSS. I would suggest using shadows, gradients or a combination of both, depending on the desired result.

Then, with JS, you can keep track of the cursor's position and move that overlay around following it or change its CSS properties' values (maybe using CSS variables, depending on your browser support needs), depending on your implementation.

If you go for the former, ideally you should be using window.requestAnimationFrame() in order to get smoother transitions without harming performance. 🚀

Try to implement that yourself and, if you have issues with the implementation, come back and create another question with that specific issue. As some have pointed out in the comments, we are not supposed to write the code for you, especially when you haven't tried before (or at least you have not provided any evidence about it).

EDIT:

As it's been a few days since this question was created, I guess it's fine to post a working solution now, as I was curious myself to know how realistic this effect could be using just CSS.

@LambdaNinja's solution is a good starting point, but that doesn't look like a real torch.

The Pen @JoshAdams posted in a comment gets closer, but there's still room for improvement.

I have used window.requestAnimationFrame, CSS variables, background-blend-mode and CSS animations.

const W = window.innerWidth;
const H = window.innerHeightfunctionupdateAnimationTiming() {
  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');

    constX2 = X - (12 * W / 100) * (X / W - 0.5);
    constY2 = Y - (12 * W / 100) * (Y / H - 0.5);

    document.documentElement.style.setProperty('--cursorX2', X2 + 'px');
    document.documentElement.style.setProperty('--cursorY2', Y2 + 'px');
  });
});
: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);
    }
}

You can also access it here: https://codepen.io/Danziger/pen/VyOZpy

Keep in mind it has some limitations though, as the overlay will cover all the page, so the effect is limited to the background image and different gradients added to it.

Even if you replace the pseudoelement with a <div> and add content in it, that content will not be affected by the blend mode.

However, it might be possible to achieve that using mix-blend-mode. You can check out the cursor on my website, which also uses animations/transitions between its different shapes or states and mix-blend-mode so that the cursor blends with any element on the page, not just with the background of one specific element:

🚀 Check it out here: https://gmzcodes.com/.

👨‍💻 Check the code here: https://github.com/Danziger/gmzcodes

Lastly, here you can see another answer with a simpler custom cursor that might be all you need in most cases and might help you understand how to do it: CSS - Custom cursor that changes depending on hovered element flickers when moving left to right but not right to left

Solution 2:

edit: as @Rob has said below, always try to answer questions on your own first. This is merely an implementation suggestion and should not be copied mindlessly.


I think you can create a CSS element with a radial gradient that you keep under your mouse with JS.

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 --><divid='mask'></div><!-- flashlight effect --><divid='flashlight'></div>

Solution 3:

There aren’t many options using only CSS. You can check out this link where they detail all the types of cursors you can use. But those are not relevant to your use case as it’s just changing the icon.

You might need to look into a JS solution to track the cursor position. Check out this StackOverflow answer.

After you know where the cursor is, you can create a div:

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

You can then try and change the position of this div using:

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

Where X and Y are your desired position on the screen.

To avoid it looking jumpy, add a transition property in the CSS of “cursor-background”:

transition: all 0.1s ease-in-out;

I haven’t tested any of this out, just trying to provide guidance as to which direction you should take.

As for the background, make it whichever color you want it to be. The flashlight effect will come from the light div hovering over your dark background.

Post a Comment for "How To Darken A Css Background Image But Keep Area Around Cursor Brighter"