原生JS實現移動端模組的左右滑動切換效果,基於vue、stylus
阿新 • • 發佈:2019-01-02
原生JS實現移動端模組的左右滑動動畫效果,基於vue、stylus
大概實現方案:
手指touch螢幕的整個過程,會派發touchstart、touchmove、touchend三個事件,對這三個事件設定相應函式,通過移動過程中位置的變化計算出偏移值,進行對應的設定。
注:以下講解請忽略資料(可用兩個設定高度寬度的空dom代替),這篇部落格只針對切換效果的實現
效果展示
①歌詞未左滑:
②歌詞左滑後:
所需資料定義:
解釋:currentShow用於標記當前顯示的模組為CD模組還是歌詞模組、touchInfo物件用於儲存touch事件的相關屬性
vue dom結構:
stylus:
原生JavaScript:
解釋:三個皆為相應dom中touch事件的方法,詳情請註釋即可。
middleTouchStart(e) { // touch開始時,將touchInfo物件設定為已初始化狀態 this.touchInfo.initiated = true // 用來判斷是否是一次移動 this.touchInfo.moved = false const touch = e.touches[0] // 記錄touch位置的橫座標與縱座標 this.touchInfo.startX = touch.pageX this.touchInfo.startY = touch.pageY }, middleTouchMove(e) { if (!this.touchInfo.initiated) { return } const touch = e.touches[0] // 橫座標與縱座標的偏移 const deltaX = touch.pageX - this.touchInfo.startX const deltaY = touch.pageY - this.touchInfo.startY if (Math.abs(deltaY) > Math.abs(deltaX)) { return } if (!this.touchInfo.moved) { this.touchInfo.moved = true } // 判斷當前顯示的是cd還是歌詞,如果是cd,則當前左偏移值為0,否則偏移值為-window.innerWidth const left = this.currentShow === 'cd' ? 0 : -window.innerWidth // 求偏移值 const offsetWidth = Math.min(0, Math.max(-window.innerWidth, left + deltaX)) // 求偏移值佔可視區域的百分比,用於判斷是否應該切換顯示狀態 this.touchInfo.percent = Math.abs(offsetWidth / window.innerWidth) // 移動時歌詞模組的偏移效果 this.$refs.lyricList.$el.style.transform = `translate3d(${offsetWidth}px,0,0)` this.$refs.lyricList.$el.style.transitionDuration = 0 // 移動時CD模組的淡出效果 this.$refs.cd.style.opacity = 1 - this.touchInfo.percent this.$refs.cd.style.transitionDuration = 0 }, middleTouchEnd() { if (!this.touchInfo.moved) { return } let offsetWidth let opacity if (this.currentShow === 'cd') { // 移動百分比大於螢幕一半,則切換顯示狀態 if (this.touchInfo.percent > 0.5) { offsetWidth = -window.innerWidth opacity = 0 this.currentShow = 'lyric' } else { offsetWidth = 0 opacity = 1 } } else { if (this.touchInfo.percent < 0.5) { offsetWidth = 0 this.currentShow = 'cd' opacity = 1 } else { offsetWidth = -window.innerWidth opacity = 0 } } // 最終狀態的設定 // 動畫時間 const time = 300 // touch完畢後歌詞模組應該放置的位置 this.$refs.lyricList.$el.style.transform = `translate3d(${offsetWidth}px,0,0)` this.$refs.lyricList.$el.style.transitionDuration = `${time}ms` // touch完畢後CD模組的透明度 this.$refs.cd.style.opacity = opacity this.$refs.cd.style.transitionDuration = `${time}ms` // 一次touch完成後,重置touchInfo物件尚未初始化狀態 this.touchInfo.initiated = false }
至此,原生JS實現移動端模組的左右滑動動畫效果實現完成。