See beyond grayscale/saturation using CSS or Javascript/jQuery

99 Views Asked by At

Summary of what I'm trying to achieve: I want to make my entire website in grayscale or saturation 0 and a div which follows the cursor to display the colors under that "mask" or div which acts like a mask.

I tried different approaches for this but I can't get it. I tried using CSS, with filter property or backdrop-filter. I tried finding the solution with Google Web Designer

In GWD the mask works just in one way, not like in photoshop.For example, in photoshop you can pun a top layer to remove the saturation than put a mask on it and reverse the mask to for it to apply outside the area created.

mask in pohotoshop

But in GoogleWebDesigner the mask is only applied on the area created, you can reverse it mask in googlewebdesigner

Do you have other suggestions how to approach this ? another method

1

There are 1 best solutions below

2
DBS On

This is possible using a combination of clip-path (documentation) and backdrop-filter (documentation). These are both quite new, so check whether they are suitable for you browser support requirements.

Most of the explanation is in the code comments, but a basic summary:

  • Fix an element over the entire document, and use backdrop-filter to make everything greyscale.
  • Use clip-path to only apply that filter to a rectangle in the center.
  • Use JS to offset the element so that the center remains over the cursor.

// This simply listens for mouse movenet and sets the CSS variables to the current X/Y
const cursor = document.querySelector(".cursor")
addEventListener('mousemove', e => {
  cursor.style.setProperty("--x", `${e.pageX}px`);
  cursor.style.setProperty("--y", `${e.pageY}px`);
});
/* This body style is just an example to make the demo work, it is not relevant to the solution*/
body {
  min-height: 100%;
  background-image: linear-gradient(45deg, #ff002f 10%, #2bcc33 10%, #2bcc33 20%, #0c12cc 20%, #0c12cc 30%, #0ddec6 30%, #0ddec6 40%, #d0db00 40%, #d0db00 50%, #ff002f 50%, #ff002f 60%, #2bcc33 60%, #2bcc33 70%, #0c12cc 70%, #0c12cc 80%, #0ddec6 80%, #0ddec6 90%, #d0db00 90%, #d0db00 100%);
  background-size: 141.42px 141.42px;
}

/* This container covers the page and prevent the mask from blocking clicks or making the page scrollable*/
.cursorContainer {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  overflow: hidden;
  pointer-events: none;
}

.cursor {
  /* These are set by JS and used to keep the box over the cursor */
  --x: 0px;
  --y: 0px;
  /* These are each half of the box's width and height respectively */
  --boxX: 60px;
  --boxY: 40px;
  /* These work out the boundries of the clip path from the sizes above */
  --boxUpperX: calc(50% + var(--boxX));
  --boxLowerX: calc(50% - var(--boxX));
  --boxUpperY: calc(50% + var(--boxY));
  --boxLowerY: calc(50% - var(--boxY));
  
  position: fixed;
  height: 200vh;
  width: 200vw;
  /* Use the variables above to keep this over the cursor */ 
  left: calc(-100% + var(--x));
  top: calc(-100% + var(--y));
  /* Apply the greyscale filter to the webpage behind this element */ 
  backdrop-filter: grayscale(1);
  /* Only apply that filter to this area (Basically a thick rectangle with a gap for the colour to appear through) */
  clip-path: polygon(0% 0%, 0% 100%, var(--boxLowerX) 100%, var(--boxLowerX) var(--boxLowerY), var(--boxUpperX) var(--boxLowerY), var(--boxUpperX) var(--boxUpperY), var(--boxLowerX) var(--boxUpperY), var(--boxLowerX) 100%, 100% 100%, 100% 0%);
}
<div class="cursorContainer">
  <div class="cursor"></div>
</div>