首页 > 解决方案 > 悬停在链接上时动画自定义光标

问题描述

我的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 实现这一点?

标签: javascriptjqueryhtmlcss

解决方案


这是您可以实现的一种方法:以下解决方案允许您拥有自定义 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. 何时#cursor悬停<a>我们将添加一个类 ( .hoveredCursor),它将更改#cursor的初始属性(例如widthheight)。为了避免不必要地在光标上添加或删除一个类,mousemove我们可以检查两件事:

  2. 目标是一个<a>元素,可以用jQuery的.is方法检查:

      const isLinkTag = target.is('a');
    
  3. 是否#cursor有类.hoveredCursorie#cursor已经悬停。使用方法.hasClass

       const isHovered = cursor.hasClass('hoveredCursor');
    
  4. 您可以将任何属性设置为.hoveredCursor,当悬停时这些将被添加到#cursor的初始属性(您可能需要用于!important覆盖样式),例如:

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

然后设置transition属性#cursor使其平滑:

    #cursor {
      transition: linear height 0.2s, linear width 0.2s;
    } 
  1. 您可能会遇到的一个问题是#cursor妨碍了event.target目标的含义#cursor。这会导致一些不良行为(#cursor将在两种状态之间来回切换......)

设置none#cursor'spointer-events将解决该问题(事件将简单地忽略#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>

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


使用这种方法的优点是它允许您在任何给定元素的两组属性之间转换(通过标签 - 这里<a>- 甚至通过选择器)。


推荐阅读