当鼠标悬停在链接上时,动画自定义光标。

6

我为我的body和链接设置了自定义图像光标。

我希望实现的效果是当悬停在链接上时,光标应该过渡到链接的光标图像,而不是直接改变。

目前,我拥有这段代码:

html {
  height:100%;
}
body {
  cursor:url(https://i.imgur.com/odlAwsz.png), auto  !important;
  width:100%;
  height:100%;
  background:red;
}

a {
  cursor:url(https://i.imgur.com/yxX4Snm.png), auto !important;
}
<a href="#">I'm a link</a>

如上所示,当悬停在<a>标签上时,两个圆形图标之间没有过渡效果。

我尝试使用CSS来实现这一点,但是没有成功。如何使用JavaScript实现这个效果?


1
这个问题在之前的如何使用JS实现的问题中没有得到回答吗? - probablybest
对于其他遇到这个问题的人,这里有一个演示如何使用JS在链接上动画光标的fiddle。https://jsfiddle.net/je6oxk1u/4/。我个人会使用SVG而不是.PNG。 - probablybest
我想出了一个类似的解决方案,但是针对HTML光标。我投票支持重新开放此问题,因为重复链接没有回答这个问题。如果问题重新开放并且确实如此,我将在下面发布答案。 - Ivan
@Temani,你能删除重复的内容吗?我不认为它是重复的。正如OP所说,这是关于解决JavaScript问题的,因此CSS-Cursor Transition在这里没有任何帮助。 - Ivan
1个回答

10

以下是一种实现方法:该解决方案允许您拥有自定义的HTML鼠标指针,当悬停在特定标签上时可以从一个状态过渡到另一个状态。

  1. 首先,让我们创建自定义的HTML鼠标指针:

#cursor {
  width: 20px;
  height: 20px;
  position: absolute;
  top: 0;
  left: 0;
  background: blue;
  border-radius: 10px;
}
<div id="cursor"></div>

  1. 然后我们需要使这个元素跟踪实际光标的位置:

$(document).mousemove(function(e) {

  const cursor = $('#cursor');
  const target = $(event.target);
  
  // update position of cursor
  cursor.css('left', e.clientX-10).css('top', e.clientY-10);
 
});
* {
  cursor: none;
}

#cursor {
  width: 20px;
  height: 20px;
  position: absolute;
  top: 0;
  left: 0;
  background: blue;
  border-radius: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="cursor"></div>

  1. When #cursor will be hovering <a> we will add a class (.hoveredCursor) that will change #cursor's initial properties (e.g. width and height). In order to not unnecessarily add or remove a class to the cursor on mousemove we can check for two things:

  2. the target is a <a> element, can be checked with jQuery's .is method:

      const isLinkTag = target.is('a');
    
  3. whether or not #cursor has the class .hoveredCursor i.e. #cursor is already hovering. With the method .hasClass:

       const isHovered = cursor.hasClass('hoveredCursor');
    
  4. You can set any property to .hoveredCursor, when hovering these will be added to #cursor's initial property (you might need to use !important to overwrite styles), for example:

    .hoveredCursor {
      width: 10px !important;
      height: 10px !important;
    }
    

然后设置#cursortransition属性,使其平滑过渡:

    #cursor {
      transition: linear height 0.2s, linear width 0.2s;
    } 
  1. 可能遇到的一个问题是#cursor挡住了event.target,导致target成为#cursor。这会导致一些不好的行为(#cursor会在两种状态之间不断切换...)

#cursorpointer-events设置为none就可以解决这个问题(事件将简单地忽略#cursor)。


最终代码如下:

$(document).mousemove(function(e) {

  const cursor = $('#cursor');
  const target = $(event.target);
  
  // update position of cursor
  cursor.css('left', e.clientX-10).css('top', e.clientY-10);
  
  const isLinkTag = target.is('a');
  const isHovered = cursor.hasClass('hoveredCursor');
  
  // toggle the cursor class if necessary 
  if(isLinkTag && !isHovered) {
  
    cursor.addClass('hoveredCursor');

  } else if(!isLinkTag && isHovered) {
  
    cursor.removeClass('hoveredCursor');
  
  }
  
});

$(document).mouseleave(function(e) {

  const cursor = $('#cursor');
  cursor.hide()

});

$(document).mouseenter(function(e) {

  const cursor = $('#cursor');
  cursor.show()

});
* {
  cursor: none;
}

#cursor {
  pointer-events: none;
  width: 20px;
  height: 20px;
  position: absolute;
  top: 0;
  left: 0;
  display: none;
  background: blue;
  border-radius: 10px;
  transition: linear height 0.2s, linear width 0.2s;
}

.hoveredCursor {
  width: 10px !important;
  height: 10px !important;
}

a {
  font-size: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="cursor"></div>

<a href="#">This is a link</a>

注意:我还在文档中添加了mouseentermouseleave,以便自定义光标相应地隐藏或显示。


这种方法的优点是可以让您在任何给定元素(通过标签 - 这里是<a> - 或甚至是选择器)之间过渡两组属性。


这段程序相关的内容的翻译如下:唯一的问题是当您滚动页面时,它会停留在相同的 x 轴位置而不更新。要修复此问题,您需要使用 pageX 和 pageY 而不是 clientX/Y。 - flakerimi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接