当前位置: 首页 > Web前端 > CSS

Vue组件设计-点击反馈说明

时间:2023-03-30 16:22:35 CSS

,即可实现水波涟漪的效果。说点题外话。Varlet,一个基于Vue3的移动端组件库,诚邀社区有兴趣的朋友参与。如果你有兴趣加入我们,可以到仓库中的问题列表留下你的邮箱,我们会发邮件邀请你加入。仓库地址文件地址点击反馈不知道大家有没有注意到这样一个细节。有的应用按钮、链接、交互卡片是可以点击的,但有的好像是在白纸上点击的。是什么让他们让用户有如此明显的差异化感受?......鼠标移入时的小手,鼠标点击时按键按下弹出的动画,触屏时的屏幕震动应用程序被点击后,这些效果给用户的一种是直觉,我的动作产生了这样的效果。这些效果也统称为点击反馈。虽然看似是应用中的一个小细节,但只要稍加用心,对用户体验的提升是非常明显的。水波纹效果在这里,笔者为小伙伴们推荐一款笔者非常喜欢的点击反馈效果。当用户点击时,会产生以点击中心为圆心的水波荡漾效果。适用于各种场景,美观而不浮夸。关键是要给用户带来非常直观的反馈。让我们看看实现。首先,封装是基于Vue3自定义指令。与Vue2相比,Vue3的自定义指令变化不大。具体请参考Vue3自定义说明。我们的目标是完成一个水波指令的基本原型,这里会一步步进行。自定义一个水波纹默认样式水波纹实际上是在用户点击的位置生成一个小圆圈,大小逐渐扩大到整个点击元素的过程,所以这里我们先制定一个水波纹的基本样式和设置过渡动画。过度动画应该是一个先慢后快的过程。这里使用贝塞尔曲线定制。如果你不知道如何调试动画曲线,可以看这篇文章。my-ripple{position:absolute;顶部:0;左:0;z-指数:100;边界半径:50%;背景颜色:currentColor;不透明度:0;transition:transform0.2scubic-bezier(0.68,0.01,0.62,0.6),opacity0.08slinear;:变换,不透明度;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得到函数computeRippleStyles(element,event){const{top,left}=element.getBoundingClientRect()const{clientWidth,clientHeight}=elementconstradius=Math.sqrt(clientWidth**2+clientHeight**2)/2constsize=radius*2constlocalX=event.clientX-leftconstlocalY=event.clientY-topconstcenterX=(clientWidth-radius*2)/2constcenterY=(clientHeight-radius*2)/2constx=localX-radiusconsty=localY-radiusreturn{x,y,centerX,centerY,size}}鼠标按下时创建一个水波然后我们需要在鼠标按下时创建一个水波并监听鼠标被按下的事件。这里以PC端为例。刚刚创建水波时,使用transform将其缩小到0.3。这是作者尝试过Size,然后修改transform来触发过度水波扩散动画的比较合适的创作。这里还加入了透明度的过渡,让水波纹更有质感。functioncreateRipple(event){constcontainer=thisconst{x,y,centerX,centerY,size}=computeRippleStyles(container,event)constripple=document.createElement('div')ripple.classList.add('我的波纹')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.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`})}constVRipple={mounted(el){el.addEventListener('mousedown',createRipple)}}鼠标抬起时破坏水波。当鼠标抬起时,只需要找到生成的水波节点修改透明度,等透明度修改动画结束后再移除水波纹节点即可。函数删除eRipple(){constcontainer=thisconstripples=container.querySelectorAll('.my-ripple')if(!ripples.length){return}constlastRipple=ripples[ripples.length-1]//通过的创建时间theripple计算扩散动画需要执行多长时间,并保证每次水波都执行完扩散动画constdelay=300-performance.now()+Number(lastRipple.dataset.createdAt)setTimeout(()=>{lastRipple.style.opacity=`0`setTimeout(()=>lastRipple.parentNode?.removeChild(lastRipple),300)},delay)}constVRipple={mounted(el){el.addEventListener('mousedown',createRipple)document.addEventListener('mouseup',removeRipple)},unmounted(el){el.removeEventListener('mousedown',createRipple)document.removeEventListener('mouseup',removeRipple)}}通过命令绑定扩展您的Ripple选项。你也可以使用binding来扩展你的命令,比如你可以提供修改颜色、禁用状态等选项,这里我们就不详细展开了,一起来看看结果吧。在写作的最后,我们已经实现了一个简单的ripple命令。在我们的组件库中也有这样的命令,所以您可以查看我们的源代码以获得更完整的版本。希望它对每个人都有效。