最近两天一直在折腾网页样式,想给我的主页自定义一个指针样式,而且最好是动态的,于是乎有了这篇记录。
使用 CSS cursor 属性替换
CSS 是支持设置指针格式的,将页面上任意元素的cursor属性设置至目标图标的 url 即可,例如
* {
cursor: url('arrow.ico'),auto;
}
然而这种方法有一个很明显的缺点,那就是不能设置任何动态指针,也无法给指针实现各种动效。
2025.1.18更:其实是可以通过关键帧实现动态指针的,详见qingzhengQB/ani-cursor.js这个项目。用css cursor属性的优势是操作上无延迟并且性能要求更低,但是如果需要与网页元素互动的指针还是只能用js来实现。
在 HTML 中创造一个指针元素并通过 CSS 和 JavaScript 控制
换一种思路,我们可以通过网页上的一个div来表示鼠标指针,通过 js 和 CSS 来操作它并给他附上动效。
这样做后鼠标指针就成为了网页的一部分,所以我们需要先隐藏掉默认的系统指针:
* {
cursor: none !important;
}
HTML
现在如果将指针移动到网页上,就会发现它直接消失了,于是我们需要在 HTML 中创建一个div作为我们的新指针。
<div class="mouse"></div>
CSS
在 CSS
中编写指针的样式,我这边写了一个圆作为指针本体。记得将z-index设为999,这样才能让指针显示在所有元素的上方。注意:pointer-events需要设置为none,否则会导制指针本体挡住后方元素。
.mouse {
width: 12px;
height: 12px;
border-radius: 50%;
background-color: #ff9068;
position: fixed;
left: 50%;
top: 50%;
pointer-events: none;
z-index: 999;
transition: background 0.3s, width 0.3s, height 0.3s;
}
我们可以再创建一个lighter类作为指针在链接上方时的样式
.mouse.lighter {
background-color: #b6ff94;
width: 10px;
height: 10px;
}
JavaScript
使用一段 js 让指针元素跟随鼠标移动,并在移动到链接上方时自动添加lighter类
var mouse = document.querySelector('.mouse');
document.addEventListener('mousemove', function(e) {
mouse.style.left = e.pageX + 'px';
mouse.style.top = e.pageY + 'px';
});
var links = document.querySelectorAll('a');
links.forEach(function(link) {
link.addEventListener('mouseover', function() {
mouse.classList.add('lighter');
});
link.addEventListener('mouseout', function() {
mouse.classList.remove('lighter');
});
});
现在你应该能看到网页上的指针元素在跟随你的鼠标移动了。
动效添加
CSS
只是这样的一个静态指针并不能体现出这个方案的精髓所在。让我们给它加一点动态效果。我决定在这个小圆点外面再添加一个环,并让这个环不断旋转,CSS 代码如下:
.mouse-back {
position: absolute;
content: '';
width: 2em;
height: 2em;
background: url(/assets/cursor.svg) no-repeat center center;
background-size: contain;
left: -50%;
top: -50%;
margin: -0.42em 0 0 -0.42em;
animation: mouse 3s linear infinite both;
pointer-events: none;
z-index: 999;
}
.mouse-back.lighter {
background-image: url(/assets/cursor-orange.svg);
width: 2.5em;
height: 2.5em;
margin: -0.75em 0 0 -0.75em;
}
JavaScript
小改一下 JavaScript,加入新mouse-back类的控制:
var mouse = document.querySelector('.mouse');
var mouseback = document.querySelector('.mouse-back');
document.addEventListener('mousemove', function(e) {
mouse.style.left = e.pageX + 'px';
mouse.style.top = e.pageY + 'px';
mouseback.style.left = e.pageX + 'px';
mouseback.style.top = e.pageY + 'px';
});
var links = document.querySelectorAll('a');
links.forEach(function(link) {
link.addEventListener('mouseover', function() {
mouse.classList.add('lighter');
mouseback.classList.add('lighter');
});
link.addEventListener('mouseout', function() {
mouse.classList.remove('lighter');
mouseback.classList.remove('lighter');
});
});
我想让外侧的圆环在指针移动的时候不要马上跟随过去,添加一点延迟。这样中间的圆和外侧的圆环不锁死在一起,给网页添加一些动感。
只需在 CSS 的mouse-back类中加入一个transition属性
transition: 100ms;
这样在移动时mouse-back元素就不会马上跟到鼠标的当前位置,而是会有100毫秒的延迟。
效果演示
这样就大功告成了,欢迎来我的网站引导页看看最终的效果:rayann.cn