这篇文章将为大家详细讲解有关怎么在vue中实现水波涟漪效果的点击反馈指令,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
水波纹实际上就是通过用户点击的位置生成一个小圆圈,并且尺寸逐渐扩大到整个被点击元素的一个过程,所以这里先制定一个水波基本的样式,并设置好过度动画,过度动画应该是一个先慢后快的一个过程,这里使用贝塞尔曲线定制
.my-ripple {
position: absolute;
top: 0;
left: 0;
z-index: 100;
border-radius: 50%;
background-color: currentColor;
opacity: 0;
transition: transform 0.2s cubic-bezier(0.68, 0.01, 0.62, 0.6), opacity 0.08s linear;
will-change: transform, opacity;
pointer-events: none;
}
如果确定了水波的直径、创建时的(x,y)、过度动画结束时的(x,y),我们就可以通过transition去渲染水波动画了,创建时的(x,y)就是用户点击的位置,但是水波的直径和过度动画结束时的(x,y)怎么计算呢?我们的元素都是矩形,不论用户从元素的任意坐标进行点击,以矩形斜边作为直径的圆都可以完美的覆盖整个元素,斜边的计算我们利用小学数学知识求两边平方和进行开方得到,下面是过度动画结束时的水波推演图。
第一个箭头: 期望得到的水波
第二个箭头: 元素(0,0)点创建的水波
第三个箭头: 元素(0,0)点创建的水波, 不带圆角效果
我们可以发现通过元素(0,0)点创建的水波进行一定偏移就可以得到我们想要的水波,由此我们可以推断出
动画结束时的水波的尺寸 = 圆的斜边
创建时的(x,y) = 用户点击的位置
过度动画结束时的(x,y) = 元素(0,0)点创建的水波进行x和y的偏移得到
function computeRippleStyles(element, event) {
const { top, left } = element.getBoundingClientRect()
const { clientWidth, clientHeight } = element
const radius = Math.sqrt(clientWidth ** 2 + clientHeight ** 2) / 2
const size = radius * 2
const localX = event.clientX - left
const localY = event.clientY - top
const centerX = (clientWidth - radius * 2) / 2
const centerY = (clientHeight - radius * 2) / 2
const x = localX - radius
const y = localY - radius
return { x, y, centerX, centerY, size }
}
然后我们需要在鼠标按下时创建水波,监听鼠标按下的事件,这里以pc端为例子,刚创建水波时使用transform缩小到0.3,这是作者尝试过相对合适的创建大小, 然后修改transform触发过度水波扩散动画,这里还加入了透明度的过度,可以使水波涟漪更有质感。
function createRipple(event) {
const container = this
const { x, y, centerX, centerY, size } = computeRippleStyles(container, event)
const ripple = document.createElement('div')
ripple.classList.add('my-ripple')
ripple.style.opacity = `0`
ripple.style.transform = `translate(${x}px, ${y}px) scale3d(.3, .3, .3)`
ripple.style.width = `${size}px`
ripple.style.height = `${size}px`
// 记录水波的创建时间
ripple.dataset.createdAt = String(performance.now())
const { position } = window.getComputedStyle(container)
container.style.overflow = 'hidden'
position === 'static' && (this.style.position = 'relative')
container.appendChild(ripple)
window.setTimeout(() => {
ripple.style.transform = `translate(${centerX}px, ${centerY}px) scale3d(1, 1, 1)`
ripple.style.opacity = `.25`
})
}
const VRipple = {
mounted(el) {
el.addEventListener('mousedown', createRipple)
}
}
当鼠标抬起时,只需要找到这个生成的水波节点修改透明度,再等到透明度修改动画结束之后将水波纹节点移除即可
function removeRipple() {
const container = this
const ripples = container.querySelectorAll('.my-ripple')
if (!ripples.length) {
return
}
const lastRipple = ripples[ripples.length - 1]
// 通过水波的创建时间计算出扩散动画还需要执行多久,确保每一个水波都完整的执行了扩散动画
const delay = 300 - performance.now() + Number(lastRipple.dataset.createdAt)
setTimeout(() => {
lastRipple.style.opacity = `0`
setTimeout(() => lastRipple.parentNode?.removeChild(lastRipple), 300)
}, delay)
}
const VRipple = {
mounted(el) {
el.addEventListener('mousedown', createRipple)
document.addEventListener('mouseup', removeRipple)
},
unmounted(el) {
el.removeEventListener('mousedown', createRipple)
document.removeEventListener('mouseup', removeRipple)
}
}
关于怎么在vue中实现水波涟漪效果的点击反馈指令就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。