写一个带追踪特效的渐变按钮
开头先观看这张GIF
图:
是否被它的出色动画效果所吸引?
这是从一个完美竞技平台中录制出来的
我脑海中萌生了用CSS
来模仿这一效果的念头
绘画元素
我们先记录下这个按钮浮动的颜色(#868BFF
),还有按钮的背景的渐变色(#39D5FF
->#868bff
)
外部使用一个div
元素表示一个自定义按钮元素,内部包含一个div
元素(follow
),用于实现一个尾随鼠标的效果。
当鼠标移动到按钮上时,follow
元素将跟随鼠标的位置,创造出一个视觉上的尾随效果,以增强用户界面的交互性
<div class="custom-button"> <div class="follow"></div> 按钮 </div>
接下来,结合我们之前记录下来的色值,给按钮添加上渐变色和浮动的元素
.custom-button { height: 80px; width: 400px; background: linear-gradient(to right, #39D5FF, #868bff); color: #fff; border: none; border-radius: 5px; cursor: pointer; overflow: hidden; display: flex; justify-content: center; align-items: center; position: relative; } .follow { width: 180px; height: 180px; background: radial-gradient(circle, #868bff 0%, transparent 70%, transparent 100%); transform-origin: center; position: absolute; left: 0; top: 0; }
设置完毕后,你将会得到以下这个效果图
绑定事件
在我们录制的GIF
图中,我们可以看到当我们鼠标移动到按钮上面的时候,会出现一个动画效果的软化边缘圆形,以增强元素的视觉吸引力
你是不是也和我一样第一时间想到了利用mousemove
事件来监听鼠标移动
我们给外部的div
绑定上mousemove
事件
<div class="custom-button" @mousemove="move"> <span class="follow"></span> 按钮 </div>
const move=()=>{}
通过mouseEvent
事件,我们可以拿到很多关于鼠标的各种信息,例如鼠标的位置,按钮状态,事件类型...
如果您对
mouseEvent
事件不是很熟悉,可以看看这里 MouseEvent
接下来,我们通过mouseEvent
事件拿到offsetX
和offsetY
属性
这两个属性表示的是鼠标相对于目标元素内部左上角的偏移量
const move = (e: MouseEvent) => { const { offsetX, offsetY } = e loc.X = offsetX - 90; loc.Y = offsetY - 90; }
现在当我们鼠标进入到按钮内移动时,控制台就会持续打印出当前鼠标基于元素的坐标位置
我们新建一个reactive
属性,用来存放当前鼠标坐标系,方便后续将值绑定到元素中
这里要注意的是,我们的鼠标指针是在圆形元素的中间,所以我们要将offsetX
,offsetY
各自减去90px
,也就是width/2
和height/2
// 存放坐标信息 const loc = reactive({ X: 0, Y: 0 }) // 鼠标事件 const move = (e: MouseEvent) => { const { offsetX, offsetY } = e loc.X = offsetX - 90; loc.Y = offsetY - 90; }
将loc
对象绑定给follow
元素作为样式
<span class="follow" ref="followRef" :style="{ transform: `translate(${loc.X}px, ${loc.Y}px)` }"></span>
小小知识点:使用
transform
进行移动可以优化性能,因为它不会触发页面的reflow
,reflow
是比较消耗性能的操作
我们试一下效果,跟着鼠标移动的效果貌似是实现了,但是你有没有发现每次移动的时候follow
元素总会闪到坐上角去,而且offsetX
,offsetY
输出了{offsetX: 171, offsetY: 63}
我们给follow
元素添加上pointer-events: none;
即可解决问题
在多个元素重叠在一起时,event.target
会发生变动,可以打印一下看看
事件目标元素一直在span
和div
标签中来回切换,导致我们出现抖动的效果
来看看调整过的效果!
实现动画效果
这里可以使用CSS中的过渡动画来实现我们的需求,这里使用scale
函数用来改变follow
元素的缩放效果,当鼠标进入到元素中,scale
值会从0
到1
,反之,重置为0
我们给外部的div
绑定多两个事件,分别是mouseenter
,mouseleave
,用来记录当前鼠标是否进入到元素中
定义两个ref
属性,用来记录transitionDuration
值(元素CSS属性的过渡时间)和isShowCircle
是否显示follow
元素
<!-- 绑定鼠标事件和CSS属性值 --> <div class="custom-button" @mousemove="move" @mouseenter="enter" @mouseleave="leave"> <span class="follow" ref="followRef" :style="{ transform: `translate(${loc.X}px, ${loc.Y}px) scale(${isShowCircle ? 1 : 0})`, transitionDuration: tds }"></span> 按钮 </div>
// 是否显示圆形 const isShowCircle = ref(false) // 过渡时间 const tds = ref('0.2s') // 当鼠标进入到元素后触发 const enter = () => { isShowCircle.value = true // 这里要注意下 // 需要延迟设置tds值,否则会出现进入时动画丢失效果 setTimeout(() => { tds.value = '0s'; }, 200); } // 当鼠标离开元素后触发 const leave = () => { isShowCircle.value = false tds.value = '0.2s'; }
现在就可以来看看我们效果怎么样
解决文字层级问题
现在我们的特效会将按钮中的文字覆盖掉,是因为当兄弟元素脱离了文档流之后,元素的层级可能会比兄弟元素略高一些,我们只需要在按钮里的文字用span
标签包裹着,并给他指定一个适当的z-index
即可解决这个问题
别忘记了,也要设置pointer-events: none;
哦,否则会出现抖动问题
.text { z-index: 1; pointer-events: none; }
扩展
在Vue
项目开发中,我们可能会遇到一份代码重复使用的情况,这个时候我们可以使用Vue
组件的方式来封装这个按钮
这里我就直接把代码贴在这里啦,有需要的同学可以从这里Copy
~~
<template> <div class="custom-button" @mousemove="move" @mouseenter="enter" @mouseleave="leave"> <span class="follow" ref="followRef" :style="{ transform: `translate(${loc.X}px, ${loc.Y}px) scale(${isShowCircle ? 1 : 0})`, transitionDuration: tds }"></span> <span class="text"> <slot></slot> </span> </div> </template> <script setup lang="ts"> import { reactive, ref } from 'vue'; const isShowCircle = ref(false) const followRef = ref() const loc = reactive({ X: 0, Y: 0 }) const tds = ref('0.2s') const enter = () => { isShowCircle.value = true setTimeout(() => { tds.value = '0s'; }, 200); } const leave = () => { isShowCircle.value = false tds.value = '0.2s'; } const move = (e: MouseEvent) => { const { offsetX, offsetY } = e loc.X = offsetX - 90; loc.Y = offsetY - 90; } </script> <style scoped> .custom-button { height: 80px; width: 400px; background: linear-gradient(to right, #39D5FF, #868bff); color: #fff; border: none; border-radius: 5px; cursor: pointer; overflow: hidden; display: flex; justify-content: center; align-items: center; position: relative; } .follow { width: 180px; height: 180px; background: radial-gradient(circle, #868bff 0%, transparent 70%, transparent 100%); transform-origin: center; pointer-events: none; position: absolute; left: 0; top: 0; } .text { z-index: 1; pointer-events: none; } </style>
以上就是使用CSS写一个带追踪特效的渐变按钮的详细内容,更多关于CSS追踪特效的渐变按钮的资料请关注 『沙漠渔溏』 其它相关文章!