日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線(xiàn)溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
如何使用vue開(kāi)發(fā)波紋點(diǎn)擊特效組件

最近在使用 vue2 做一個(gè)新的 material ui 庫(kù),波紋點(diǎn)擊效果在 material design 中被多次使用到,于是決定把它封裝成一個(gè)公共的組件,使用時(shí)直接調(diào)用就好啦。

開(kāi)發(fā)之前的思考

常見(jiàn)的波紋點(diǎn)擊效果的實(shí)現(xiàn)方式是監(jiān)聽(tīng)元素的 mousedown 事件,在元素內(nèi)部創(chuàng)建一個(gè) 波紋元素 ,并調(diào)整元素的 transform: scale(0); 到 transform: scale(1);, 通過(guò)計(jì)算點(diǎn)擊的位置來(lái)設(shè)置 波紋元素 的大小和位置,以達(dá)到波紋擴(kuò)散的效果。

我將組件分為兩個(gè)部分, circleRipple.vue 和 TouchRipple.vue 各自實(shí)現(xiàn)不同的功能

  1. circleRipple.vue 波紋擴(kuò)散組件,完成波紋擴(kuò)散的效果
  2. TouchRipple.vue 監(jiān)聽(tīng) mouse 和 touch 相關(guān)事件,控制 circleRipple 的顯示,位置。

circleRipple.vue

circleRipple 需要完成波紋擴(kuò)展的效果,而且可以從外部控制它的大小和位置, 所以利用 vue 的 transition 動(dòng)畫(huà)完成效果, 提供mergeStyle 、 color 、opacity 參數(shù)來(lái)從外部控制它的樣式。實(shí)現(xiàn)代碼如下。

 
 
  1.  
  2.  
  3.  
  4.  
  5.  
  6. @import "../styles/import.less"; 
  7. .mu-circle-ripple{ 
  8.   position: absolute; 
  9.   width: 100%; 
  10.   height: 100%; 
  11.   left: 0; 
  12.   top: 0; 
  13.   pointer-events: none; 
  14.   user-select: none; 
  15.   border-radius: 50%; 
  16.   background-color: currentColor; 
  17.   background-clip: padding-box; 
  18.   opacity: 0.1; 
  19.  
  20. .mu-ripple-enter-active, .mu-ripple-leave-active{ 
  21.   transition: transform 1s @easeOutFunction, opacity 2s @easeOutFunction; 
  22.  
  23. .mu-ripple-enter { 
  24.   transform: scale(0); 
  25.  
  26. .mu-ripple-leave-active{ 
  27.   opacity: 0 !important; 
  28.  

 vue2 對(duì)于動(dòng)畫(huà)方面做了比較大的修改,除了把指令換成組件外,它還可以完成更復(fù)雜的動(dòng)畫(huà)效果,具體可以看這里 vue2 transition

TouchRipple.vue

TouchRipple 需要控制 circleRipple 的顯示。完成以下內(nèi)容:

  1. 監(jiān)聽(tīng) mouse 和 touch 相關(guān)事件, 控制 circleRipple 的顯示。
  2. 通過(guò)點(diǎn)擊事件 event 對(duì)象, 計(jì)算出 circleRipple 的大小和位置
  3. 如果頻繁點(diǎn)擊可能出現(xiàn)多個(gè) circleRipple

首先,基本模板 + 數(shù)據(jù)模型

 
 
  1.  
  2.  
  3.  

 開(kāi)始和結(jié)束波紋效果

增加一個(gè)波紋元素只需要在 ripple 增加一個(gè) object 即可,不同的是當(dāng)需要從點(diǎn)擊處擴(kuò)展時(shí),需要計(jì)算一下波紋元素的大小和位置。

 
 
  1.   // isRippleTouchGenerated 是否是touch 事件開(kāi)始的 
  2.   start (event, isRippleTouchGenerated) { 
  3.     // 過(guò)濾 touchstart 和 mousedown 同時(shí)存在的情況 
  4.     if (this.ignoreNextMouseDown && !isRippleTouchGenerated) { 
  5.       this.ignoreNextMouseDown = false 
  6.       return 
  7.     } 
  8.      
  9.     // 添加一個(gè) 波紋元素組件 
  10.     this.ripples.push({ 
  11.       key: this.nextKey++,  
  12.       color: this.color, 
  13.       opacity: this.opacity, 
  14.       style: this.centerRipple ? {} : this.getRippleStyle(event) // 不是從中心擴(kuò)展的需要計(jì)算波紋元素的位置 
  15.     }) 
  16.     this.ignoreNextMouseDown = isRippleTouchGenerated 
  17.  }, 
  18.  end () { 
  19.    if (this.ripples.length === 0) return 
  20.    this.ripples.splice(0, 1) // 刪除一個(gè)波紋元素 
  21.    this.stopListeningForScrollAbort() // 結(jié)束 touch 滾動(dòng)的處理 
  22.   } 

 因?yàn)?vue2 基于 Virtual DOM 的, 所以如果沒(méi)有 key 在增加一個(gè)元素又同時(shí)刪除一個(gè)元素的時(shí)候,dom tree并沒(méi)有發(fā)生變化,是不會(huì)產(chǎn)生動(dòng)畫(huà)效果的。

監(jiān)聽(tīng) mousedown 和 touchstart

mousedown 和 touchstart 處理上會(huì)有所不同,但都是用來(lái)啟動(dòng)波紋效果的, touch涉及到多點(diǎn)點(diǎn)擊的問(wèn)題,我們一般取***個(gè)即可。

 
 
  1.     handleMouseDown (event) { 
  2.       // 只監(jiān)聽(tīng)鼠標(biāo)左鍵的點(diǎn)擊 
  3.       if (event.button === 0) { 
  4.         this.start(event, false) 
  5.       } 
  6.     }, 
  7.     handleTouchStart (event) { 
  8.       event.stopPropagation() // 防止多個(gè)波紋點(diǎn)擊組件嵌套 
  9.       if (event.touches) { 
  10.         this.startListeningForScrollAbort(event) // 啟動(dòng) touchmove 觸發(fā)滾動(dòng)處理 
  11.         this.startTime = Date.now() 
  12.       } 
  13.       this.start(event.touches[0], true) 
  14.     } 

 touchmove控制

當(dāng)發(fā)生touchMove事件是需要判斷是否,移動(dòng)的距離和時(shí)間,然后結(jié)束小波紋點(diǎn)擊小姑

 
 
  1.   // touchmove 結(jié)束波紋控制 
  2.   stopListeningForScrollAbort () { 
  3.     if (!this.handleMove) this.handleMove = this.handleTouchMove.bind(this) 
  4.     document.body.removeEventListener('touchmove', this.handleMove, false) 
  5.   }, 
  6.   startListeningForScrollAbort (event) { 
  7.     this.firstTouchY = event.touches[0].clientY 
  8.     this.firstTouchX = event.touches[0].clientX 
  9.     document.body.addEventListener('touchmove', this.handleMove, false) 
  10.   }, 
  11.   handleTouchMove (event) { 
  12.     const timeSinceStart = Math.abs(Date.now() - this.startTime) 
  13.     if (timeSinceStart > 300) { 
  14.       this.stopListeningForScrollAbort() 
  15.       return 
  16.     } 
  17.     const deltaY = Math.abs(event.touches[0].clientY - this.firstTouchY) 
  18.     const deltaX = Math.abs(event.touches[0].clientX - this.firstTouchX) 
  19.     // 滑動(dòng)范圍在 > 6px 結(jié)束波紋點(diǎn)擊效果 
  20.     if (deltaY > 6 || deltaX > 6) this.end() 
  21.   } 

 計(jì)算波紋的位置和大小

需要從點(diǎn)擊處擴(kuò)散的波紋效果,需要計(jì)算波紋元素的大小和位置

 
 
  1.   getRippleStyle (event) { 
  2.     let holder = this.$refs.holder 
  3.     //  這個(gè)方法返回一個(gè)矩形對(duì)象,包含四個(gè)屬性:left、top、right和bottom。分別表示元素各邊與頁(yè)面上邊和左邊的距離。 
  4.     let rect = holder.getBoundingClientRect()  
  5.     // 獲取點(diǎn)擊點(diǎn)的位置 
  6.     let x = event.offsetX 
  7.     let y 
  8.     if (x !== undefined) { 
  9.       y = event.offsetY 
  10.     } else { 
  11.       x = event.clientX - rect.left 
  12.       y = event.clientY - rect.top 
  13.     } 
  14.     // 獲取***邊長(zhǎng) 
  15.     let max 
  16.     if (rect.width === rect.height) { 
  17.       max = rect.width * 1.412 
  18.     } else { 
  19.       max = Math.sqrt( 
  20.         (rect.width * rect.width) + (rect.height * rect.height) 
  21.       ) 
  22.     } 
  23.     const dim = (max * 2) + 'px' 
  24.     return { 
  25.       width: dim, 
  26.       height: dim, 
  27.       // 通過(guò)margin控制波紋中心點(diǎn)和點(diǎn)擊點(diǎn)一致 
  28.       'margin-left': -max + x + 'px', 
  29.       'margin-top': -max + y + 'px' 
  30.     } 
  31.   } 

 使用

由于 touchRipple 內(nèi)部都是 position:absolute 布局,使用時(shí),需要在外部加上 position:relative

 
 
  1. // listItem.vue 
  2.     @touchcancel="hover = false" class="mu-item-wrapper" :class="{'hover': hover}"> 
  3.      
  4.        
  5.          
  6.       
 
  •        
  •         // ... 
  •       
  •  
  •      
  •  
  •  
  •  ***

    到這點(diǎn)擊波紋組件就開(kāi)發(fā)完了, 這些代碼借鑒了 keen-ui 和 material-ui 的實(shí)現(xiàn)方式。


    網(wǎng)站題目:如何使用vue開(kāi)發(fā)波紋點(diǎn)擊特效組件
    轉(zhuǎn)載來(lái)于:http://m.5511xx.com/article/djdpscg.html