最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Vue3+TypeScript實現(xiàn)抖音式卡片滑動交互功能

 更新時間:2026年06月03日 09:00:43   作者:龍蝦不加班  
本文介紹如何用 Vue 3 + TypeScript 實現(xiàn)類似抖音的卡片滑動交互,應用于單詞記憶場景,完整方案包含手勢識別、堆疊動畫、實時反饋和狀態(tài)管理,需要的朋友可以參考下

效果拆解

目標效果:屏幕中央一張主卡片,后方隱約可見兩張堆疊卡片。手指左滑(不認識)或右滑(認識),卡片跟隨手指移動并旋轉,松開后飛出屏幕,下一張頂上。

核心需求:

  • 3 張可見卡片(z-index 分層,縮放遞減)
  • Pointer Events 手勢跟蹤
  • 滑動過程實時視覺反饋(顏色、圖標、標簽)
  • 閾值判斷 + 飛出動畫 + 隊列循環(huán)

卡片堆疊布局

三張卡片用 v-for 渲染,通過 index 控制層級和變形:

const stackStyle = (stackIndex: number) => {
  if (stackIndex >= 3) return { display: 'none' }

  const scaleMap = [1, 0.95, 0.90]      // 越靠后越小
  const yOffsetMap = [0, 12, 24]         // 越靠后越向下
  const zIndexMap = [30, 29, 28]         // 越靠前越高

  return {
    zIndex: zIndexMap[stackIndex],
    transform: `scale(${scaleMap[stackIndex]}) translateY(${yOffsetMap[stackIndex]}px)`,
    transition: stackIndex === 0 && isDragging.value
      ? 'none'                           // 拖拽中不要過渡
      : 'transform 0.35s ease'
  }
}

數(shù)組用 ref<Word[]>([]) 存儲當前隊列。隊列用完時自動從后端拉取下一批。

Pointer Events 手勢跟蹤

用 Pointer Events 而非 Touch Events,因為 Pointer Events 同時支持觸屏和鼠標,方便開發(fā)調試:

const SWIPE_THRESHOLD = 72  // px,超過此值觸發(fā)飛出
const isDragging = ref(false)
const dragX = ref(0)

const onPointerDown = (e: PointerEvent) => {
  isDragging.value = true
  startX.value = e.clientX
  ;(e.target as HTMLElement).setPointerCapture(e.pointerId)
}

const onPointerMove = (e: PointerEvent) => {
  if (!isDragging.value) return
  dragX.value = e.clientX - startX.value
}

const onPointerUp = () => {
  if (!isDragging.value) return
  isDragging.value = false

  if (Math.abs(dragX.value) > SWIPE_THRESHOLD) {
    // 觸發(fā)飛出
    const direction = dragX.value > 0 ? 'right' : 'left'
    flyAway(direction)
  } else {
    // 復位
    dragX.value = 0
  }
}

關鍵點:setPointerCapture 確保手指滑出元素邊界后依然能跟蹤。不用這個 API 的話,手指移出卡片范圍就會丟失 tracking。

實時視覺反饋

根據拖拽距離動態(tài)計算顏色和圖標透明度:

const feedbackColor = computed(() => {
  const ratio = Math.min(Math.abs(dragX.value) / SWIPE_THRESHOLD, 1)
  if (dragX.value > 0) {
    return `rgba(34, 197, 94, ${ratio * 0.3})`  // 綠色 = 認識
  } else if (dragX.value < 0) {
    return `rgba(239, 68, 68, ${ratio * 0.3})`  // 紅色 = 不認識
  }
  return 'transparent'
})

const checkIconOpacity = computed(() =>
  dragX.value > 0 ? Math.min(dragX.value / SWIPE_THRESHOLD, 1) : 0
)

const crossIconOpacity = computed(() =>
  dragX.value < 0 ? Math.min(-dragX.value / SWIPE_THRESHOLD, 1) : 0
)

拖拽距離與閾值的比值驅動所有視覺過渡。不需要動畫庫,computed 全搞定。

飛出動畫 + 隊列推進

飛出用 CSS transition + 最終位置計算:

const flyAway = (direction: 'left' | 'right') => {
  const targetX = direction === 'right' ? window.innerWidth * 1.5 : -window.innerWidth * 1.5
  flyX.value = targetX
  flyRotation.value = direction === 'right' ? 20 : -20

  // 記錄結果
  const result = direction === 'right' ? 'known' : 'forgotten'
  submitReview(currentWord.value.id, result)

  // 動畫結束后移除當前詞,推進隊列
  setTimeout(() => {
    words.value.shift()
    flyX.value = 0
    flyRotation.value = 0
    dragX.value = 0
    // 隊列快用完時預加載
    if (words.value.length < 5) fetchMoreWords()
  }, 350)
}

飛出期間新卡片已經在原來的第二張位置就位,視覺上無縫銜接。

四隊列切換

高頻詞、大綱詞、綜合、錯詞鞏固,四種模式對應不同 API 參數(shù):

type QueueMode = 'high' | 'outline' | 'mixed' | 'wrong'

const switchQueue = async (mode: QueueMode) => {
  currentMode.value = mode
  words.value = []
  await fetchWords(mode)
}

錯詞隊列的每個詞帶有復習記錄,后端根據復習次數(shù)和上次復習時間動態(tài)計算下次推送時機,實現(xiàn)間隔重復。

性能注意事項

  • 事件監(jiān)聽用 passive: false:Pointer Events 需要 preventDefault 防止頁面滾動,所以要顯式設置 { passive: false }
  • 動畫用 transform 而非 left/top:transform 走合成層,不觸發(fā)重排
  • 隊列預加載:剩 5 張時自動拉取,滑動體驗零等待

完整代碼較長,核心邏輯即上面這些。這個交互方案可以直接復用到任何需要卡片滑動判斷的場景——背單詞、刷題、審閱、相親……

在線體驗:m.dobell.top,打開就能看到效果。

以上就是基于Vue3+TypeScript實現(xiàn)抖音式卡片滑動交互功能的詳細內容,更多關于Vue3 TypeScript抖音式卡片滑動交互的資料請關注腳本之家其它相關文章!

相關文章

  • vue樣式穿透 ::v-deep的具體使用

    vue樣式穿透 ::v-deep的具體使用

    這篇文章主要介紹了vue樣式穿透 ::v-deep的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • vue3 $attrs和inheritAttrs的用法說明

    vue3 $attrs和inheritAttrs的用法說明

    這篇文章主要介紹了vue3 $attrs和inheritAttrs的用法說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue?input組件如何設置失焦與聚焦

    vue?input組件如何設置失焦與聚焦

    這篇文章主要介紹了vue?input組件如何設置失焦與聚焦,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • Vue+Vant實現(xiàn)7天日歷展示并在切換日期時實時變換功能

    Vue+Vant實現(xiàn)7天日歷展示并在切換日期時實時變換功能

    本文介紹了如何利用Vue和Vant框架結合moment.js插件來實現(xiàn)一個7天日歷展示功能,在這個功能中,用戶可以在切換日期時看到界面的實時變化,此外,文章還提供了代碼實現(xiàn)和效果測試的詳細步驟,幫助開發(fā)者能夠順利完成類似的項目開發(fā)
    2024-10-10
  • 使用konva和vue-konva庫實現(xiàn)拖拽滑塊驗證功能

    使用konva和vue-konva庫實現(xiàn)拖拽滑塊驗證功能

    這篇文章主要介紹了使用konva和vue-konva完成前端拖拽滑塊驗證功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • elementUI實現(xiàn)級聯(lián)選擇器

    elementUI實現(xiàn)級聯(lián)選擇器

    這篇文章主要為大家詳細介紹了elementUI實現(xiàn)級聯(lián)選擇器,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Webpack+Vue如何導入Jquery和Jquery的第三方插件

    Webpack+Vue如何導入Jquery和Jquery的第三方插件

    本文主要介紹了Webpack+Vue導入Jquery和Jquery的第三方插件的方法,具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • vue watch監(jiān)聽變量值的實時變動示例詳解

    vue watch監(jiān)聽變量值的實時變動示例詳解

    這篇文章主要介紹了vue 監(jiān)聽變量值的實時變動 watch,使用字符串形式的偵聽器函數(shù),還有一種是使用函數(shù)形式的偵聽器函數(shù),本文通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-08-08
  • vue.js+boostrap項目實踐(案例詳解)

    vue.js+boostrap項目實踐(案例詳解)

    這篇文章主要介紹了vue.js+boostrap項目實踐(案例詳解)的相關資料,本文圖文并茂介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下
    2016-09-09
  • 詳解@Vue/Cli 3 Invalid Host header 錯誤解決辦法

    詳解@Vue/Cli 3 Invalid Host header 錯誤解決辦法

    這篇文章主要介紹了詳解@Vue/Cli 3 Invalid Host header 錯誤解決辦法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01

最新評論

武胜县| 五峰| 宁国市| 合江县| 偏关县| 台东市| 崇阳县| 周宁县| 咸阳市| 舒兰市| 疏勒县| 固阳县| 水城县| 忻州市| 涡阳县| 屯昌县| 南华县| 武平县| 武邑县| 康保县| 阿瓦提县| 南部县| 禄劝| 巴南区| 昌邑市| 朝阳市| 呼和浩特市| 朝阳县| 南丰县| 蚌埠市| 新竹市| 阜阳市| 阿拉善盟| 崇信县| 阳西县| 巢湖市| 淳化县| 延边| 军事| 荆州市| 涡阳县|