在鼠标悬停时反转文本颜色

时间:2021-07-04 19:44:11

I'd like to invert a black text while hovering it with a custom -black- cursor. This GIF demonstrates the effect:

我想在使用自定义-black-光标悬停时将蓝色文本反转。这个GIF证明了这个效果:

在鼠标悬停时反转文本颜色

Couldn't wrap my head around to make this work with CSS & JS. Some combination with mix-blend-modes, clipping masks, pseudo elements and filters I guess.

无法用我的头脑来完成CSS和JS的工作。我想有些混合混合模式,剪切蒙版,伪元素和滤镜。

The following code makes the cursor white but doesn't alow the black text to be turned white. Sounds abstract? Here's a demo.

以下代码使光标变为白色,但不会将黑色文本变为白色。听起来很抽象?这是一个演示。

mix-blend-mode: difference;
filter: invert(1) grayscale(1) contrast(2);

I've setup a playground on Codepen to mess around with, but didn't found a solution yet.

我已经在Codepen上安装了一个游乐场,但是还没有找到解决方案。

How could this hover effect be recreated with CSS and Javascript?

如何使用CSS和Javascript重新创建这种悬停效果?

1 个解决方案

#1


12  

Here is an idea using clip-path. The trick is to duplicate the text to have two layers above each other with different text color then I reveal the top one using the clip-path that I adjust with the move of the mouse.

这是一个使用clip-path的想法。诀窍是复制文本以使用不同的文本颜色在彼此之上具有两个层然后使用我通过移动鼠标调整的剪辑路径来显示顶部文本。

var h =document.querySelector('h1');
var p= h.getBoundingClientRect();
var c= document.querySelector('.cursor');

document.body.onmousemove = function(e) {
  /*Adjust the cursor position*/
  c.style.left=e.clientX-20+'px';
  c.style.top=e.clientY-20+'px';
  /*Adjust the clip-path*/
  h.style.setProperty('--x',(e.clientX-p.top)+'px');
  h.style.setProperty('--y',(e.clientY-p.left)+'px');
}
body {
  cursor:none;
}
h1 {
  color: #000;
  display:inline-block;
  margin:50px;
  text-align: center;
  position:relative;
}
h1:before {
  position:absolute;
  content:attr(data-text);
  color:#fff;
  background:#000;
  clip-path: circle(20px at var(--x,-40px) var(--y,-40px));
}
.cursor {
  position:absolute;
  width:40px;
  height:40px;
  background:#000;
  border-radius:50%;
  top:-40px;
  left:-40px;
  z-index:-2;
}
<h1 data-text="WORK">WORK</h1>

<span class="cursor"></span>

Here is Another idea using radial-gradient and without duplicating the text:

这是使用径向渐变而不复制文本的另一个想法:

var h =document.querySelector('h1');
var p= h.getBoundingClientRect();
var c= document.querySelector('.cursor');

document.body.onmousemove = function(e) {
  /*Adjust the position of the cursor*/
  c.style.left=e.clientX-20+'px';
  c.style.top=e.clientY-20+'px';
  /*Adjust the radial-gradient*/
  h.style.setProperty('--x',(e.clientX-p.top)+'px');
  h.style.setProperty('--y',(e.clientY-p.left)+'px');
}
body {
  cursor:none;
}
h1 {
  display:inline-block;
  margin:50px;
  background: radial-gradient(circle at var(--x,-40px) var(--y,-40px), #fff 20px,black 21px);
  background-clip: text;
  -webkit-background-clip: text;
  color:transparent;
  -webkit-text-fill-color: transparent;

}
.cursor {
  position:absolute;
  width:40px;
  height:40px;
  background:#000;
  border-radius:50%;
  top:-40px;
  left:-40px;
  z-index:-2;
}
<h1>WORK</h1>

<span class="cursor"></span>


Here is a third method that rely on more supported techniques than clip-path and/or background-clip:text:

这是第三种方法,它依赖于比clip-path和/或background-clip更多支持的技术:text:

var h =document.querySelector('h1.title');
var p= h.getBoundingClientRect();
var c= document.querySelector('.cursor');

document.querySelector('.cursor h1').style.left=p.left+'px';
document.querySelector('.cursor h1').style.top=p.top+'px';

document.body.onmousemove = function(e) {
  /*Adjust the position of the cursor*/
  c.style.left=e.clientX-20+'px';
  c.style.top=e.clientY-20+'px';
}
body {
  cursor:none;
  margin:0;
}
h1.title {
  display:inline-block;
  margin:50px;
}
.cursor {
  position:absolute;
  width:40px;
  height:40px;
  background:#000;
  border-radius:50%;
  top:-40px;
  left:-40px;
  z-index:2;
  overflow:hidden;
}
.cursor > * {
  position:fixed;
  color:#fff;
  margin:0;
}
<h1 class="title">WORK</h1>

<div class="cursor">
  <h1>WORK</h1>
</div>

I made the above example simple but we can add more JS in order to duplicate the text and put inside the cursor and have something more flexible.

我使上面的例子变得简单,但是我们可以添加更多的JS来复制文本并放入光标并使其更灵活。

#1


12  

Here is an idea using clip-path. The trick is to duplicate the text to have two layers above each other with different text color then I reveal the top one using the clip-path that I adjust with the move of the mouse.

这是一个使用clip-path的想法。诀窍是复制文本以使用不同的文本颜色在彼此之上具有两个层然后使用我通过移动鼠标调整的剪辑路径来显示顶部文本。

var h =document.querySelector('h1');
var p= h.getBoundingClientRect();
var c= document.querySelector('.cursor');

document.body.onmousemove = function(e) {
  /*Adjust the cursor position*/
  c.style.left=e.clientX-20+'px';
  c.style.top=e.clientY-20+'px';
  /*Adjust the clip-path*/
  h.style.setProperty('--x',(e.clientX-p.top)+'px');
  h.style.setProperty('--y',(e.clientY-p.left)+'px');
}
body {
  cursor:none;
}
h1 {
  color: #000;
  display:inline-block;
  margin:50px;
  text-align: center;
  position:relative;
}
h1:before {
  position:absolute;
  content:attr(data-text);
  color:#fff;
  background:#000;
  clip-path: circle(20px at var(--x,-40px) var(--y,-40px));
}
.cursor {
  position:absolute;
  width:40px;
  height:40px;
  background:#000;
  border-radius:50%;
  top:-40px;
  left:-40px;
  z-index:-2;
}
<h1 data-text="WORK">WORK</h1>

<span class="cursor"></span>

Here is Another idea using radial-gradient and without duplicating the text:

这是使用径向渐变而不复制文本的另一个想法:

var h =document.querySelector('h1');
var p= h.getBoundingClientRect();
var c= document.querySelector('.cursor');

document.body.onmousemove = function(e) {
  /*Adjust the position of the cursor*/
  c.style.left=e.clientX-20+'px';
  c.style.top=e.clientY-20+'px';
  /*Adjust the radial-gradient*/
  h.style.setProperty('--x',(e.clientX-p.top)+'px');
  h.style.setProperty('--y',(e.clientY-p.left)+'px');
}
body {
  cursor:none;
}
h1 {
  display:inline-block;
  margin:50px;
  background: radial-gradient(circle at var(--x,-40px) var(--y,-40px), #fff 20px,black 21px);
  background-clip: text;
  -webkit-background-clip: text;
  color:transparent;
  -webkit-text-fill-color: transparent;

}
.cursor {
  position:absolute;
  width:40px;
  height:40px;
  background:#000;
  border-radius:50%;
  top:-40px;
  left:-40px;
  z-index:-2;
}
<h1>WORK</h1>

<span class="cursor"></span>


Here is a third method that rely on more supported techniques than clip-path and/or background-clip:text:

这是第三种方法,它依赖于比clip-path和/或background-clip更多支持的技术:text:

var h =document.querySelector('h1.title');
var p= h.getBoundingClientRect();
var c= document.querySelector('.cursor');

document.querySelector('.cursor h1').style.left=p.left+'px';
document.querySelector('.cursor h1').style.top=p.top+'px';

document.body.onmousemove = function(e) {
  /*Adjust the position of the cursor*/
  c.style.left=e.clientX-20+'px';
  c.style.top=e.clientY-20+'px';
}
body {
  cursor:none;
  margin:0;
}
h1.title {
  display:inline-block;
  margin:50px;
}
.cursor {
  position:absolute;
  width:40px;
  height:40px;
  background:#000;
  border-radius:50%;
  top:-40px;
  left:-40px;
  z-index:2;
  overflow:hidden;
}
.cursor > * {
  position:fixed;
  color:#fff;
  margin:0;
}
<h1 class="title">WORK</h1>

<div class="cursor">
  <h1>WORK</h1>
</div>

I made the above example simple but we can add more JS in order to duplicate the text and put inside the cursor and have something more flexible.

我使上面的例子变得简单,但是我们可以添加更多的JS来复制文本并放入光标并使其更灵活。