Пользовательский курсор, который инвертирует цвета - PullRequest
2 голосов
/ 11 марта 2019

У меня есть вопрос.Как я могу сделать курсор, который меняет цвет позади него и применяет к себе.

Так же, как «отрицательный» эффект.

Но мне нужно, чтобы это было автоматически без кодирования каждого цвета, поэтомуон может взаимодействовать с любыми элементами

. Вот мой старт для пользовательского курсора и пример моего фона:

(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>

Как я могу это сделать?

1 Ответ

1 голос
/ 11 марта 2019

Вот идея с использованием фона, где задача состоит в том, чтобы симулировать курсор, используя radial-gradient, чтобы вы могли определить цвет для каждого элемента, как вы хотите:

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>

Хитрость заключается в том, что каждый градиент сделан fixed, поэтому он позиционируется относительно области просмотра, тогда я использую одну и ту же переменную CSS для всехградиент, чтобы поместить их в том же положении.Каждый из них будет виден только в его разделе.

Если у вас будет контент и вам нужен курсор над всем, вы можете рассмотреть псевдоэлемент для создания слоя сверху:

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>

Вот еще одна идея, где вы можете закрасить курсор, который вы сделали, с помощью linear-gradient, имеющего тот же размер, что и ваши 3 раздела:

(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>

соответствующая часть вышеуказанного кода:

 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;

ОБНОВЛЕНИЕ

Исходя из ваших новых требований, вы можете рассмотреть mix-blend-mode для достижения того, что вы хотите

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>

Вам просто нужно изменить цвет курсора (один раз) и определить нужный режим наложения.

Вот сЭлемент курсора:

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>
...