我想在用自定义 -black- 光标悬停时反转黑色文本。 这个 GIF 演示了效果:
无法全神贯注地使用 CSS 和 JS 来完成这项工作。我猜是混合混合模式、剪贴蒙版、伪元素和滤镜的一些组合。
以下代码使光标变为白色,但不允许将黑色文本变为白色。听起来很抽象?这是一个 demo .
// All creds go to https://murmure.me 👀
const cursor = $(".cursor"),
body = $("body"),
slider = $(".slider"),
nav = $(".nav"),
fail = $(".fail"),
invert = $(".invert"),
nav_open_menu = $(".navopen"),
wwidth = $(window).width(),
wheight = $(window).height(),
cursorMove = function() {
var e, n;
return (
body.addClass("cursor-on"),
cursor.css({
transform: "matrix(1, 0, 0, 1, " + wwidth / 2 + ", " + wheight / 2 + ")"
}),
(e = wheight / 2),
(n = 0.65 * wwidth / 2),
n > e ? e : n,
$(window).on("mousemove", function(e) {
var n, t;
if (
((window.x = e.clientX),
(window.y = e.clientY),
cursor.css({
transform: "matrix(1, 0, 0, 1, " + x + ", " + y + ")"
}),
!nav.hasClass("overlay-visible"))
)
return (
(n = Math.floor((x - 60) / 5)),
(t = Math.floor((y - 60) / 5)),
n < 20 && t < 20
? nav_open_menu.addClass("magnetize").css({
transform: "scale(1.3) translate3d(" + n + "px, " + t + "px, 0)"
})
: nav_open_menu.removeClass("magnetize").attr("style", "")
);
})
);
};
cursorBind = function() {
var e, n, t;
if (
((n = cursor.find("span")).removeClass("link external new"),
(e = $(".focus")),
(t = $(".slack")),
$(window).on({
mouseenter: function() {
return n.removeClass("off");
},
mouseleave: function() {
return n.addClass("off");
}
}),
$("a, button, .cursor-link, .sort-listing th").on({
mouseenter: function() {
var e;
return (
(e = $(this).hasClass("external") ? "link external" : "link"),
n.addClass(e)
);
},
mouseleave: function() {
return n.removeClass("link external");
}
}),
$("h1").on({
mouseenter: function() {
var e;
return (
(e = $(this).hasClass("external") ? "invert external" : "invert"),
n.addClass(e)
);
},
mouseleave: function() {
return n.removeClass("invert external");
}
}),
e.length &&
e.find("a").on({
mouseenter: function() {
return n.addClass("new");
},
mouseleave: function() {
return n.removeClass("new");
}
}),
slider.length &&
slider.on({
mouseenter: function() {
var e;
return (
(e = $(this).hasClass("full") ? "click" : "drag"), n.addClass(e)
);
},
mouseleave: function() {
return n.removeClass("drag click");
}
}),
t.length &&
t.on({
mouseenter: function() {
return n.addClass("light");
},
mouseleave: function() {
return n.removeClass("light");
}
}),
fail.length)
)
return fail.on({
mouseover: function() {
return n.addClass("relol");
},
mouseleave: function() {
return n.removeClass("relol");
}
});
};
cursorMove();
cursorBind();
body {
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
h1 {
font-weight: 500;
font-size: 9vw;
}
*, *:before, *:after {
box-sizing: border-box;
}
body {
min-height: 100vh;
background-color: #fff;
color: #000;
text-rendering: optimizelegibility;
line-height: 1.5;
/* System stack font-family mentioned by @wooorm */
font-family: Roboto, -apple-system, BlinkMacSystemFont, Helvetica Neue, Segoe UI, Oxygen, Ubuntu, Cantarell, Open Sans, sans-serif;
}
.cursor-on {
cursor: none;
}
.cursor-on * {
cursor: none;
}
.cursor-on .cursor {
position: fixed;
z-index: 10;
pointer-events: none;
top: -1rem;
left: -1rem;
}
.cursor-on .cursor > span {
display: block;
width: 2rem;
height: 2rem;
border-radius: 2rem;
background: #f8e71c;
transition: transform 0.2s cubic-bezier(0.165, 0.84, 0.44, 1);
transform: scale(1);
}
.cursor-on .cursor > span.off {
transform: scale(0);
}
.cursor-on .cursor > span.link {
transform: scale(1.5);
background-color: #0000ed;
}
.cursor-on .cursor > span.link.external:after {
content: "↗";
display: block;
white-space: pre;
color: #fff;
font-weight: 100;
font-size: 1rem;
text-align: center;
width: 100%;
line-height: 1;
padding-top: 0.6em;
}
.cursor-on .cursor > span.light {
background: #fff;
}
.cursor-on .cursor > span.drag, .cursor-on .cursor > span.click, .cursor-on .cursor > span.relol, .cursor-on .cursor > span.new {
transform: scale(2.5);
}
.cursor-on .cursor > span.drag:after, .cursor-on .cursor > span.click:after, .cursor-on .cursor > span.relol:after, .cursor-on .cursor > span.new:after {
display: block;
content: "";
white-space: pre;
color: #fff;
font-size: 5px;
text-align: center;
width: 100%;
line-height: 1;
padding-top: calc((2rem / 2) - 2.5px);
color: #000;
}
.cursor-on .cursor > span.drag:after {
content: "play";
}
.cursor-on .cursor > span.click:after {
content: "click\A click";
}
.cursor-on .cursor > span.relol:after {
content: "click\A me";
padding-top: calc((2rem / 2) - 5px);
}
.cursor-on .cursor > span.new:after {
content: "new\A new";
}
.cursor-on:active .cursor > span {
transform: scale(0.75);
}
.cursor-on:active .cursor > span.link {
transform: scale(1);
}
.cursor-on:active .cursor > span.drag, .cursor-on:active .cursor > span.click, .cursor-on:active .cursor > span.relol, .cursor-on:active .cursor > span.new {
transform: scale(2);
}
.grid {
background-color: #fff;
}
.grid--column--item {
background-color: #000;
}
.grid--column.sticky .grid--column--item {
border-color: #000;
}
.cursor-on .cursor > span {
background: black;
}
.cursor-on .cursor > span.invert {
transform: scale(2.5);
mix-blend-mode: difference;
filter: invert(1) grayscale(1) contrast(2);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1 class="invert">Work</h1>
<div class="cursor" >
<span class="off"></span>
</div>
mix-blend-mode: difference;
filter: invert(1) grayscale(1) contrast(2);
我设置了一个 playground on Codepen乱来,还没找到解决办法。
如何使用 CSS 和 Javascript 重新创建这种悬停效果?
最佳答案
这是一个使用clip-path
的想法。诀窍是复制文本,使其在彼此之上有两层,文本颜色不同,然后我使用移动鼠标调整的 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+'px';
c.style.top=e.clientY+'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,-100%) var(--y,-100%));
}
.cursor {
position:fixed;
width:40px;
height:40px;
background:#000;
border-radius:50%;
top:0;
left:0;
transform:translate(-50%,-50%);
z-index:-2;
}
<h1 data-text="WORK">WORK</h1>
<span class="cursor"></span>
这是另一个使用 radial-gradient
并且不复制可以同时处理多个元素的文本的想法:
document.body.onmousemove = function(e) {
document.documentElement.style.setProperty('--x',(e.clientX)+'px');
document.documentElement.style.setProperty('--y',(e.clientY)+'px');
}
body {
cursor:none;
}
.mask {
background:
radial-gradient(circle 20px
at var(--x,0) var(--y,0),
#fff 99%,black 100%)
fixed;
background-clip: text;
-webkit-background-clip: text;
color:transparent;
-webkit-text-fill-color: transparent;
}
html::before {
content:"";
position:fixed;
width:40px;
height:40px;
background:#000;
border-radius:50%;
top:var(--y,0);
left:var(--x,0);
transform:translate(-50%,-50%);
z-index:-2;
}
<h1 class="mask">WORK</h1>
<p class="mask">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis risus sapien. Maecenas dui orci, blandit et commodo eget, egestas quis odio. Donec eu tortor turpis. Aliquam convallis et nisi ut varius. Proin sapien erat, auctor in efficitur vel, efficitur sit amet justo. In pretium iaculis tempus. Vivamus congue</p>
<p class="mask">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis risus sapien. Maecenas dui orci, blandit et commodo eget, egestas quis odio. Donec eu tortor turpis. Aliquam convallis et nisi ut varius. Proin sapien erat, auctor in efficitur vel, efficitur sit amet justo. In pretium iaculis tempus. Vivamus congue</p>
思路相似的相关问题:Stacking circles produces a black bar on border radius
关于javascript - 在鼠标悬停时反转文本颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49793312/