CSS - 自定义光标根据悬停元素的变化而变化,当从左向右移动而不是从右向左移动时闪烁
CSS - Custom cursor that changes depending on hovered element flickers when moving left to right but not right to left
我正在尝试创建一个自定义光标,该光标在悬停在 <div>
上时会发生变化,但是从左向右移动时会闪烁,但从右向左移动时不会闪烁。为什么会发生这种情况,我可以做些什么来解决它?
document.addEventListener('mousemove', (ev) => cursorMove(ev));
function cursorMove(ev) {
let circle = document.getElementById('circle');
let posY = ev.clientY;
let posX = ev.clientX;
circle.style.top = posY + 'px';
circle.style.left = posX + 'px';
}
body {
margin: 0;
height: 100vh;
background-color: #acd1d2;
position: relative;
display: flex;
justify-content: center;
align-items: center;
font-family: monospace;
}
#wrapper {
position: relative;
width: 70%;
height: 80%;
}
.box {
height: 25%;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
}
#box-1 {
background-color: #e8edf3;
}
#box-1:hover ~ #circle {
background-color: #e6cf8b;
box-shadow:inset 0em -0.3em 0.4em 0.2em #ca9e03a6;
}
#box-2 {
background-color: #e6cf8b;
}
#box-2:hover ~ #circle {
background-color: transparent;
border: 3px solid #E91E63;
}
#box-3 {
background-color: #b56969;
}
#box-3:hover ~ #circle {
height: 1em;
width: 1em;
background-color: #e6cf8b;
}
#box-4 {
background-color: #22264b;
color: white;
}
#box-4:hover ~ #circle {
background-image: linear-gradient(to top, #fbc2eb 0%, #a6c1ee 100%);
}
#circle {
position: fixed;
border-radius: 50%;
z-index: 5;
height: 32px;
width: 32px;
background-color: white;
}
<div id="wrapper">
<div id="box-1" class="box">Sphere</div>
<div id="box-2" class="box">Circle outline</div>
<div id="box-3" class="box">Circle pin</div>
<div id="box-4" class="box">Circle color gradient</div>
<div id="circle"></div>
</div>
那是因为您的鼠标移动速度比圆圈快,并且您将鼠标悬停在圆圈上,因此适用于它的样式与光标位于页面背景 green/blue-ish 区域时的样式相同。
你可以通过在圆圈中添加 pointer-events: none
来解决这个问题,这样感觉有点像这样:
好的,我们在哪里?哦,是的......所以你应该使用position: fixed
instead of absolute
(as you really want your cursor to be positioned relative to the top-left corner of the viewport) and probably window.requestAnimationFrame
to get a smoother animation and translate3d(0, 0, 0)
to promote the element to its own layer并启用硬件加速渲染,这也有助于让它感觉更流畅。
您还可以使用 cursor: none
隐藏默认光标,并将光标箭头所在的圆圈居中,使其感觉就像一个真正的光标。
const circle = document.getElementById('circle');
const circleStyle = circle.style;
document.addEventListener('mousemove', e => {
window.requestAnimationFrame(() => {
circleStyle.top = `${ e.clientY - circle.offsetHeight/2 }px`;
circleStyle.left = `${ e.clientX - circle.offsetWidth/2 }px`;
});
});
body {
margin: 0;
height: 100vh;
background-color: #acd1d2;
position: relative;
display: flex;
justify-content: center;
align-items: center;
font-family: monospace;
cursor: none;
}
#wrapper {
position: relative;
width: 70%;
height: 80%;
}
#circle {
position: fixed;
border-radius: 50%;
z-index: 5;
height: 32px;
width: 32px;
background-color: white;
pointer-events: none;
transition:
background ease-in 10ms,
box-shadow ease-in 150ms,
transform ease-in 150ms;
/* Promote it to its own layer to enable hardware accelerated rendering: */
transform: translate3d(0, 0, 0);
}
.box {
height: 25%;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
}
#box-1 {
background-color: #e8edf3;
}
#box-1:hover ~ #circle {
background-color: #e6cf8b;
box-shadow: 0 0 0 0 transparent, inset 0em -0.3em 0.4em 0.2em #ca9e03a6;
}
#box-2 {
background-color: #e6cf8b;
}
#box-2:hover ~ #circle {
background-color: transparent;
/* Use box-shadow instead of border to avoid changing the dimensions of the
cursor, which will make it be off-center until the mouse moves again: */
aborder: 3px solid #E91E63;
box-shadow: 0 0 0 3px #E91E63;
}
#box-3 {
background-color: #b56969;
}
#box-3:hover ~ #circle {
background-color: #e6cf8b;
/* Change its size with scale() instead of width and height for better
performance performance: */
transform: scale(0.5) translate3d(0, 0, 0);
}
#box-4 {
background-color: #22264b;
color: white;
}
#box-4:hover ~ #circle {
background-image: linear-gradient(to top, #fbc2eb 0%, #a6c1ee 100%);
}
<div id="wrapper">
<div id="box-1" class="box">Sphere</div>
<div id="box-2" class="box">Circle outline</div>
<div id="box-3" class="box">Circle pin</div>
<div id="box-4" class="box">Circle color gradient</div>
<div id="circle"></div>
</div>
在这里你可以看到另一个很酷的例子,我使用类似于火炬的 CSS 制作了一个自定义光标:How to darken a CSS background image but keep area around cursor brighter.
此外,您可以在我的网站上查看光标,这与您所做的非常相似,因为它的不同形状或状态之间有 animations/transitions。
在这里查看:https://gmzcodes.com/.
检查这里的代码:https://github.com/Danziger/gmzcodes
我正在尝试创建一个自定义光标,该光标在悬停在 <div>
上时会发生变化,但是从左向右移动时会闪烁,但从右向左移动时不会闪烁。为什么会发生这种情况,我可以做些什么来解决它?
document.addEventListener('mousemove', (ev) => cursorMove(ev));
function cursorMove(ev) {
let circle = document.getElementById('circle');
let posY = ev.clientY;
let posX = ev.clientX;
circle.style.top = posY + 'px';
circle.style.left = posX + 'px';
}
body {
margin: 0;
height: 100vh;
background-color: #acd1d2;
position: relative;
display: flex;
justify-content: center;
align-items: center;
font-family: monospace;
}
#wrapper {
position: relative;
width: 70%;
height: 80%;
}
.box {
height: 25%;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
}
#box-1 {
background-color: #e8edf3;
}
#box-1:hover ~ #circle {
background-color: #e6cf8b;
box-shadow:inset 0em -0.3em 0.4em 0.2em #ca9e03a6;
}
#box-2 {
background-color: #e6cf8b;
}
#box-2:hover ~ #circle {
background-color: transparent;
border: 3px solid #E91E63;
}
#box-3 {
background-color: #b56969;
}
#box-3:hover ~ #circle {
height: 1em;
width: 1em;
background-color: #e6cf8b;
}
#box-4 {
background-color: #22264b;
color: white;
}
#box-4:hover ~ #circle {
background-image: linear-gradient(to top, #fbc2eb 0%, #a6c1ee 100%);
}
#circle {
position: fixed;
border-radius: 50%;
z-index: 5;
height: 32px;
width: 32px;
background-color: white;
}
<div id="wrapper">
<div id="box-1" class="box">Sphere</div>
<div id="box-2" class="box">Circle outline</div>
<div id="box-3" class="box">Circle pin</div>
<div id="box-4" class="box">Circle color gradient</div>
<div id="circle"></div>
</div>
那是因为您的鼠标移动速度比圆圈快,并且您将鼠标悬停在圆圈上,因此适用于它的样式与光标位于页面背景 green/blue-ish 区域时的样式相同。
你可以通过在圆圈中添加 pointer-events: none
来解决这个问题,这样感觉有点像这样:
好的,我们在哪里?哦,是的......所以你应该使用position: fixed
instead of absolute
(as you really want your cursor to be positioned relative to the top-left corner of the viewport) and probably window.requestAnimationFrame
to get a smoother animation and translate3d(0, 0, 0)
to promote the element to its own layer并启用硬件加速渲染,这也有助于让它感觉更流畅。
您还可以使用 cursor: none
隐藏默认光标,并将光标箭头所在的圆圈居中,使其感觉就像一个真正的光标。
const circle = document.getElementById('circle');
const circleStyle = circle.style;
document.addEventListener('mousemove', e => {
window.requestAnimationFrame(() => {
circleStyle.top = `${ e.clientY - circle.offsetHeight/2 }px`;
circleStyle.left = `${ e.clientX - circle.offsetWidth/2 }px`;
});
});
body {
margin: 0;
height: 100vh;
background-color: #acd1d2;
position: relative;
display: flex;
justify-content: center;
align-items: center;
font-family: monospace;
cursor: none;
}
#wrapper {
position: relative;
width: 70%;
height: 80%;
}
#circle {
position: fixed;
border-radius: 50%;
z-index: 5;
height: 32px;
width: 32px;
background-color: white;
pointer-events: none;
transition:
background ease-in 10ms,
box-shadow ease-in 150ms,
transform ease-in 150ms;
/* Promote it to its own layer to enable hardware accelerated rendering: */
transform: translate3d(0, 0, 0);
}
.box {
height: 25%;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
}
#box-1 {
background-color: #e8edf3;
}
#box-1:hover ~ #circle {
background-color: #e6cf8b;
box-shadow: 0 0 0 0 transparent, inset 0em -0.3em 0.4em 0.2em #ca9e03a6;
}
#box-2 {
background-color: #e6cf8b;
}
#box-2:hover ~ #circle {
background-color: transparent;
/* Use box-shadow instead of border to avoid changing the dimensions of the
cursor, which will make it be off-center until the mouse moves again: */
aborder: 3px solid #E91E63;
box-shadow: 0 0 0 3px #E91E63;
}
#box-3 {
background-color: #b56969;
}
#box-3:hover ~ #circle {
background-color: #e6cf8b;
/* Change its size with scale() instead of width and height for better
performance performance: */
transform: scale(0.5) translate3d(0, 0, 0);
}
#box-4 {
background-color: #22264b;
color: white;
}
#box-4:hover ~ #circle {
background-image: linear-gradient(to top, #fbc2eb 0%, #a6c1ee 100%);
}
<div id="wrapper">
<div id="box-1" class="box">Sphere</div>
<div id="box-2" class="box">Circle outline</div>
<div id="box-3" class="box">Circle pin</div>
<div id="box-4" class="box">Circle color gradient</div>
<div id="circle"></div>
</div>
在这里你可以看到另一个很酷的例子,我使用类似于火炬的 CSS 制作了一个自定义光标:How to darken a CSS background image but keep area around cursor brighter.
此外,您可以在我的网站上查看光标,这与您所做的非常相似,因为它的不同形状或状态之间有 animations/transitions。
在这里查看:https://gmzcodes.com/.
检查这里的代码:https://github.com/Danziger/gmzcodes