Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Cursor that invert colors

I have a question. How can I make a cursor that revert the color behind it and apply to itself.

Just like a "negative" effect.

But I need that is be automatically without coding each colors, so it can interact with any elements behind itself.

Here is my start for the custom cursor and an exemple of what my background can be:

(function () {
  var follower, init, mouseX, mouseY, positionElement, printout, timer;

  follower = document.getElementById('follower');

  printout = document.getElementById('printout');

  mouseX = event => {
    return event.clientX;
  };

  mouseY = event => {
    return event.clientY;
  };

  positionElement = event => {
    var mouse;
    mouse = {
      x: mouseX(event),
      y: mouseY(event) };

    follower.style.top = mouse.y + 'px';
    return follower.style.left = mouse.x + 'px';
  };

  timer = false;

  window.onmousemove = init = event => {
    var _event;
    _event = event;
    return timer = setTimeout(() => {
      return positionElement(_event);
    }, 1);
  };

}).call(this);

//# sourceURL=coffeescript
* {
  cursor: none;
  margin:0;
  padding:0;
}

.img{
  width:49vw;
  height:99vh;
  position:absolute;
  background: url('https://images.pexels.com/photos/531880/pexels-photo-531880.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=1000');
}
.img2{
  width:49vw;
  height:99vh;
  left:49vw;
  position:absolute;
  background: url('https://cdn-images-1.medium.com/max/1600/0*I-sI3u34g0ydRqyA');
}

#follower {
  position: absolute;
  top: 50%;
  left: 50%;
}
#follower #circle {
  position: absolute;
  background: #fff;
  border-radius: 50%;
  opacity: 0.5;
  height: 1.5em;
  width: 1.5em;
  margin-top: -0.5em;
  margin-left: -0.5em;
  z-index:2;
}
<div id="follower">
  <div id="circle"></div>
</div>

<div class="img"></div>
<div class="img2"></div>

How can I give the cursor a negative effect?

like image 378
Tut Ozz Avatar asked Mar 10 '19 21:03

Tut Ozz


People also ask

How do you invert your cursor on Windows 10?

Open Settings. Click on Devices. Click on Touchpad. Under the "Scroll and zoom" section, use the drop-down menu to select the Down motion scrolls down option.

How do I invert the colors on my icons?

For a quick color inversion, press the shortcut Ctrl + ⇧ Shift + I .


1 Answers

Here is an idea using background where the trick is to simulate the cursor using a radial-gradient so you can define the color on each element like you want:

document.onmousemove = function(e) {
  document.body.style.setProperty('--x',(e.clientX)+'px');
  document.body.style.setProperty('--y',(e.clientY)+'px');
  
}
* {
  cursor: none;
  margin:0;
  padding:0;
}

.red{
  width:33vw;
  height:100vh;
  position:absolute;
  background:
  radial-gradient(farthest-side ,white 95%,transparent 100%)
    calc(var(--x) - .75em) calc(var(--y) - .75em)/ /*position*/
    1.5em 1.5em   /*size of circle*/
    fixed no-repeat;
  background-color:red;
}
.black{
  width:33vw;
  height:100vh;
  margin-left:33vw;
  position:absolute;
  background:radial-gradient(farthest-side ,cyan 95%,transparent 100%)
    calc(var(--x) - .75em) calc(var(--y) - .75em)/1.5em 1.5em  fixed no-repeat;
  background-color:black;
}
.green{
  width:33vw;
  height:100vh;
  margin-left:66vw;
  position:absolute;
  background:radial-gradient(farthest-side ,blue 95%,transparent 100%)
    calc(var(--x) - .75em) calc(var(--y) - .75em)/1.5em 1.5em  fixed no-repeat;
  background-color:green;
}
<div class="red"></div>
<div class="black"></div>
<div class="green"></div>

The trick is that each gradient is made fixed so it is positionned relatively to the viewport then I use the same CSS variable for all the gradient to place them in the same position. Each one will be visible only in its section.

In case you will have content and you need to the cursor above everything, you can consider pseudo element to create the layer on the top:

document.onmousemove = function(e) {
  document.body.style.setProperty('--x',(e.clientX)+'px');
  document.body.style.setProperty('--y',(e.clientY)+'px');
  
}
* {
  cursor: none;
  margin:0;
  padding:0;
}
.box {
  position:relative;
  z-index:0;
  color:#fff;
}
.box:before {
  content:"";
  position:absolute;
  z-index:999;
  top:0;
  left:0;
  right:0;
  bottom:0; 
  background:
  radial-gradient(farthest-side ,var(--c) 95%,transparent 100%)
    calc(var(--x) - .75em) calc(var(--y) - .75em)/1.5em 1.5em  fixed no-repeat;
}


.red{
  width:33vw;
  height:100vh;
  position:absolute;
  background-color:red;
  --c:white;
}
.black{
  width:33vw;
  height:100vh;
  margin-left:33vw;
  position:absolute;
  background-color:black;
  --c:cyan;
}
.green{
  width:33vw;
  height:100vh;
  margin-left:66vw;
  position:absolute;
  background-color:green;
  --c:blue;
}
<div class="red box">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin molestie sem non dui tempus placerat non ut nulla. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In vel nulla commodo, dignissim sem in, viverra ipsum. Nam non libero neque.</div>
<div class="black box">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin molestie sem non dui tempus placerat non ut nulla. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In vel nulla commodo, dignissim sem in, viverra ipsum. Nam non libero neque.</div>
<div class="green box">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin molestie sem non dui tempus placerat non ut nulla. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In vel nulla commodo, dignissim sem in, viverra ipsum. Nam non libero neque.</div>

Here is another idea where you can color the cursor you made with a linear-gradient having the same dimension as your 3 sections:

(function () {
  var follower, init, mouseX, mouseY, positionElement, printout, timer;

  follower = document.getElementById('follower');

  printout = document.getElementById('printout');

  mouseX = event => {
    return event.clientX;
  };

  mouseY = event => {
    return event.clientY;
  };

  positionElement = event => {
    var mouse;
    mouse = {
      x: mouseX(event),
      y: mouseY(event) };

    follower.style.top = mouse.y + 'px';
    return follower.style.left = mouse.x + 'px';
  };

  timer = false;

  window.onmousemove = init = event => {
    var _event;
    _event = event;
    return timer = setTimeout(() => {
      return positionElement(_event);
    }, 1);
  };

}).call(this);

//# sourceURL=coffeescript
* {
  cursor: none;
  margin:0;
  padding:0;
}

.red{
  width:33vw;
  height:100vh;
  position:absolute;
  background-color:red;
}
.black{
  width:33vw;
  height:100vh;
  margin-left:33vw;
  position:absolute;
  background-color:black;
}
.green{
  width:33vw;
  height:100vh;
  margin-left:66vw;
  position:absolute;
  background-color:green;
}

#follower {
  position: absolute;
  top: 50%;
  left: 50%;
}
#follower #circle {
  position: absolute;
  background:
    linear-gradient(white,white) 0  0,
    linear-gradient(cyan,cyan) 33vw 0,
    linear-gradient(blue,blue) 66vw 0;
  background-size:33vw 100vh;
  background-attachment:fixed;
  background-repeat:no-repeat;
  border-radius: 50%;
  opacity: 0.5;
  height: 1.5em;
  width: 1.5em;
  margin-top: -0.5em;
  margin-left: -0.5em;
  z-index:2;
}
<div id="follower">
  <div id="circle"></div>
</div>

<div class="red"></div>
<div class="black"></div>
<div class="green"></div>

relevant part of the above code:

 background:
    linear-gradient(white,white) 0  0,
    linear-gradient(cyan,cyan) 33vw 0,
    linear-gradient(blue,blue) 66vw 0;
 background-size:33vw 100vh;
 background-attachment:fixed;
 background-repeat:no-repeat;

UPDATE

Based on your new requirements, you can consider mix-blend-mode to achieve what you want

document.onmousemove = function(e) {
  document.body.style.setProperty('--x',(e.clientX)+'px');
  document.body.style.setProperty('--y',(e.clientY)+'px');
  
}
* {
  cursor: none;
  margin:0;
  padding:0;
}
.box {
  position:relative;
  z-index:0;
  color:#fff;
}
.box:before {
  content:"";
  position:absolute;
  z-index:999;
  top:0;
  left:0;
  right:0;
  bottom:0; 
  background:
  radial-gradient(farthest-side ,#fff 95%,transparent 100%)
    calc(var(--x) - .75em) calc(var(--y) - .75em)/1.5em 1.5em  fixed no-repeat;
  mix-blend-mode:difference;
}


.red{
  width:33vw;
  height:100vh;
  position:absolute;
  background-color:red;
}
.black{
  width:33vw;
  height:100vh;
  margin-left:33vw;
  position:absolute;
  background:url(https://picsum.photos/800/600?image=1069) center/cover;
}
.green{
  width:33vw;
  height:100vh;
  margin-left:66vw;
  position:absolute;
  background:url(https://picsum.photos/800/600?image=1039) center/cover;
}
<div class="red box"></div>
<div class="black box"></div>
<div class="green box"></div>

You simply need to change the cursor color (once) and define the blending mode you want.

Here is with the cursor element:

document.onmousemove = function(e) {
  document.body.style.setProperty('--x',(e.clientX)+'px');
  document.body.style.setProperty('--y',(e.clientY)+'px');
  
}
* {
  cursor: none;
  margin:0;
  padding:0;
}
body:before {
  content:"";
  position:absolute;
  z-index:999;
  top:var(--y);
  left:var(--x);
  right:0;
  bottom:0; 
  width:1.5em;
  height:1.5em;
  border-radius:50%;
  transform:translate(-50%,-50%);
  background:#fff;
  mix-blend-mode:difference;
}


.red{
  width:33vw;
  height:100vh;
  position:absolute;
  background-color:red;
}
.black{
  width:33vw;
  height:100vh;
  margin-left:33vw;
  position:absolute;
  background:url(https://picsum.photos/800/600?image=1069) center/cover;
}
.green{
  width:33vw;
  height:100vh;
  margin-left:66vw;
  position:absolute;
  background:url(https://picsum.photos/800/600?image=1039) center/cover;
}
<div class="red box"></div>
<div class="black box"></div>
<div class="green box"></div>
like image 193
Temani Afif Avatar answered Oct 02 '22 05:10

Temani Afif