0

我正在尝试创建一个自定义光标,当将鼠标悬停在 a 上时会发生变化<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>

4

1 回答 1

2

那是因为您的鼠标移动得比圆圈快,并且您将鼠标悬停在它上面,因此适用于它的样式与光标位于页面的背景绿色/蓝色区域时的样式相同。

您可以通过添加pointer-events: none到圆圈来解决此问题,使其感觉有点像这样:

事件笑话

好吧,我们在哪里?哦是的......所以你应该使用position: fixed而不是absolute(因为你真的希望你的光标相对于视口的左上角定位)并且可能window.requestAnimationFrame获得更平滑的动画并将元素translate3d(0, 0, 0)提升到它自己的图层并启用硬件加速渲染,这也将有助于使其感觉更流畅。

您还可以隐藏默认光标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 制作了自定义光标:如何使 CSS 背景图像变暗但保持光标周围的区域更亮

此外,您可以查看我网站上的光标,这与您所做的非常相似,因为它在不同形状或状态之间具有动画/过渡。

在这里查看:https ://gmzcodes.com/ 。

‍在这里查看代码:https ://github.com/Danziger/gmzcodes

于 2018-05-26T02:28:47.193 回答