您好,登錄后才能下訂單哦!
本篇內容主要講解“怎么使用vue開發波紋點擊特效組件”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么使用vue開發波紋點擊特效組件”吧!
開發之前的思考
常見的波紋點擊效果的實現方式是監聽元素的 mousedown 事件,在元素內部創建一個 波紋元素 ,并調整元素的 transform: scale(0); 到 transform: scale(1);, 通過計算點擊的位置來設置 波紋元素 的大小和位置,以達到波紋擴散的效果。
我將組件分為兩個部分, circleRipple.vue 和 TouchRipple.vue 各自實現不同的功能
circleRipple.vue 波紋擴散組件,完成波紋擴散的效果
TouchRipple.vue 監聽 mouse 和 touch 相關事件,控制 circleRipple 的顯示,位置。
circleRipple.vue
circleRipple 需要完成波紋擴展的效果,而且可以從外部控制它的大小和位置, 所以利用 vue 的 transition 動畫完成效果, 提供mergeStyle 、 color 、opacity 參數來從外部控制它的樣式。實現代碼如下。
<template> <transition name="mu-ripple"> <div class="mu-circle-ripple" :style="styles"></div> </transition> </template> <script> import {merge} from '../utils' export default { props: { mergeStyle: { type: Object, default () { return {} } }, color: { type: String, default: '' }, opacity: { type: Number } }, computed: { styles () { return merge({}, {color: this.color, opacity: this.opacity}, this.mergeStyle) } } } </script> <style lang="less"> @import "../styles/import.less"; .mu-circle-ripple{ position: absolute; width: 100%; height: 100%; left: 0; top: 0; pointer-events: none; user-select: none; border-radius: 50%; background-color: currentColor; background-clip: padding-box; opacity: 0.1; } .mu-ripple-enter-active, .mu-ripple-leave-active{ transition: transform 1s @easeOutFunction, opacity 2s @easeOutFunction; } .mu-ripple-enter { transform: scale(0); } .mu-ripple-leave-active{ opacity: 0 !important; } </style>
vue2 對于動畫方面做了比較大的修改,除了把指令換成組件外,它還可以完成更復雜的動畫效果,具體可以看這里 vue2 transition
TouchRipple.vue
TouchRipple 需要控制 circleRipple 的顯示。完成以下內容:
監聽 mouse 和 touch 相關事件, 控制 circleRipple 的顯示。
通過點擊事件 event 對象, 計算出 circleRipple 的大小和位置
如果頻繁點擊可能出現多個 circleRipple
首先,基本模板 + 數據模型
<template> <!--最外層用div包裹--> <div @mousedown="handleMouseDown" @mouseup="end()" @mouseleave="end()" @touchstart="handleTouchStart" @touchend="end()" @touchcancel="end()"> <!--外層包裹防止波紋溢出--> <div :style="style" ref="holder"> <!--多個波紋用 v-for 控制--> <circle-ripple :key="ripple.key" :color="ripple.color" :opacity="ripple.opacity" :merge-style="ripple.style" v-for="ripple in ripples"></circle-ripple> </div> <!--利用slot分發實際內容--> <slot></slot> </div> </template> <script> import circleRipple from './circleRipple' export default { props: { // 是否從中間擴散,設為false會從點擊處擴散 centerRipple: { type: Boolean, default: true }, // 外層包裹的樣式 style: { type: Object, default () { return { height: '100%', width: '100%', position: 'absolute', top: '0', left: '0', overflow: 'hidden' } } }, // 波紋顏色 color: { type: String, default: '' }, // 波紋透明度 opacity: { type: Number } }, data () { return { nextKey: 0, // 記錄下一個波紋元素的key值, 相當于uuid,不設置的話會使動畫失效 ripples: [] // 波紋元素參數數組 } }, mounted () { this.ignoreNextMouseDown = false // 防止既有 touch 又有 mouse點擊的情況 }, methods: { start (event, isRippleTouchGenerated) { // 開始波紋效果 }, end () { // 結束波紋效果 }, handleMouseDown (event) { // 監聽 鼠標單擊 }, handleTouchStart (event) { // 監聽 touchstart 方法 } }, components: { 'circle-ripple': circleRipple } } </script>
開始和結束波紋效果
增加一個波紋元素只需要在 ripple 增加一個 object 即可,不同的是當需要從點擊處擴展時,需要計算一下波紋元素的大小和位置。
{ // isRippleTouchGenerated 是否是touch 事件開始的 start (event, isRippleTouchGenerated) { // 過濾 touchstart 和 mousedown 同時存在的情況 if (this.ignoreNextMouseDown && !isRippleTouchGenerated) { this.ignoreNextMouseDown = false return } // 添加一個 波紋元素組件 this.ripples.push({ key: this.nextKey++, color: this.color, opacity: this.opacity, style: this.centerRipple ? {} : this.getRippleStyle(event) // 不是從中心擴展的需要計算波紋元素的位置 }) this.ignoreNextMouseDown = isRippleTouchGenerated }, end () { if (this.ripples.length === 0) return this.ripples.splice(0, 1) // 刪除一個波紋元素 this.stopListeningForScrollAbort() // 結束 touch 滾動的處理 } }
因為 vue2 基于 Virtual DOM 的, 所以如果沒有 key 在增加一個元素又同時刪除一個元素的時候,dom tree并沒有發生變化,是不會產生動畫效果的。
監聽 mousedown 和 touchstart
mousedown 和 touchstart 處理上會有所不同,但都是用來啟動波紋效果的, touch涉及到多點點擊的問題,我們一般取***個即可。
{ handleMouseDown (event) { // 只監聽鼠標左鍵的點擊 if (event.button === 0) { this.start(event, false) } }, handleTouchStart (event) { event.stopPropagation() // 防止多個波紋點擊組件嵌套 if (event.touches) { this.startListeningForScrollAbort(event) // 啟動 touchmove 觸發滾動處理 this.startTime = Date.now() } this.start(event.touches[0], true) } }
touchmove控制
當發生touchMove事件是需要判斷是否,移動的距離和時間,然后結束小波紋點擊小姑
{ // touchmove 結束波紋控制 stopListeningForScrollAbort () { if (!this.handleMove) this.handleMove = this.handleTouchMove.bind(this) document.body.removeEventListener('touchmove', this.handleMove, false) }, startListeningForScrollAbort (event) { this.firstTouchY = event.touches[0].clientY this.firstTouchX = event.touches[0].clientX document.body.addEventListener('touchmove', this.handleMove, false) }, handleTouchMove (event) { const timeSinceStart = Math.abs(Date.now() - this.startTime) if (timeSinceStart > 300) { this.stopListeningForScrollAbort() return } const deltaY = Math.abs(event.touches[0].clientY - this.firstTouchY) const deltaX = Math.abs(event.touches[0].clientX - this.firstTouchX) // 滑動范圍在 > 6px 結束波紋點擊效果 if (deltaY > 6 || deltaX > 6) this.end() } }
計算波紋的位置和大小
需要從點擊處擴散的波紋效果,需要計算波紋元素的大小和位置
{ getRippleStyle (event) { let holder = this.$refs.holder // 這個方法返回一個矩形對象,包含四個屬性:left、top、right和bottom。分別表示元素各邊與頁面上邊和左邊的距離。 let rect = holder.getBoundingClientRect() // 獲取點擊點的位置 let x = event.offsetX let y if (x !== undefined) { y = event.offsetY } else { x = event.clientX - rect.left y = event.clientY - rect.top } // 獲取***邊長 let max if (rect.width === rect.height) { max = rect.width * 1.412 } else { max = Math.sqrt( (rect.width * rect.width) + (rect.height * rect.height) ) } const dim = (max * 2) + 'px' return { width: dim, height: dim, // 通過margin控制波紋中心點和點擊點一致 'margin-left': -max + x + 'px', 'margin-top': -max + y + 'px' } } }
使用
由于 touchRipple 內部都是 position:absolute 布局,使用時,需要在外部加上 position:relative
// listItem.vue <a :href="href" @mouseenter="hover = true" @mouseleave="hover = false" @touchend="hover = false" @touchcancel="hover = false" class="mu-item-wrapper" :class="{'hover': hover}"> <touch-ripple class="mu-item" :class="{'mu-item-link': link}" :center-ripple="false"> <div class="mu-item-media"> <slot name="media"></slot> </div> <div class="mu-item-content"> // ... </div> </touch-ripple> </a> <style> .mu-item-wrapper { display: block; color: inherit; position: relative; } </style>
到此,相信大家對“怎么使用vue開發波紋點擊特效組件”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。