小程序飛入購物車(拋物線繪製運動軌跡點)

h5,小程序飛入購物車(拋物線繪製運動軌跡點)

前言:最近有朋友在做小程序的過程中,遇到開發過飛入購物車效果的功能的需求。針對這個情況一些網上的demo,多少會有一些不符合情景的問題(bug)存在,針對這一情況小編決定幫朋友寫一個方案來幫助解決問題。

思考如果實現 ? 超級簡單的!

無論是小程序還是h5飛入購物車無非就是平拋 ,或者是上拋兩種情況,對於這兩種情況,初中就開始學習拋物線理論知識是完全可以搞定的,高中一年級物理學的自由落體運動,平拋運動就是拋物線理論的具體實現。

在這裏插入圖片描述

構建虛擬直角座標系,拋物線繪製軌跡點

此方案的本質就是,根據購物車起點和終點,分別做爲拋物線的兩點,這樣一個感念就是要以起始點作爲直角座標系(0,0)方便後續其他座標點的運算。還有一個應該注意的是,如果是配置了上拋h ,就要求最高點(頂點)座標

此方案均適合 H5 ,小程序


/**
* 飛入購物車,軌跡點繪製
* @author  👽
* @param {Array} start`在這裏插入代碼片`Point 起點clientX, clientY值 (必要) 
* @param {Array} endPoint   終點clientX, clientY值 (必要)
* @param {number} point     點數          (必要) 
* @param {number} h         拋物線向上高度(上拋運動)  (可選)
* @param {number} hclientX  當存在h情況下,達到最高點時候的clientX值
* @return {Array}  [ left ,top ] 值組成的數組
*/
function flycart(startPoint, endPoint, point, h = 0, hclientX) {
   /* 
   設置startPoint 爲(0,0)點 , 此拋物線經過(0,0)點 ,可以推到出模型關係式 y =  ax^2 + bx 或者 y = ax^ 2
   1 當存在 h 的情況,拋物線會y軸向上偏移 h, 此時的關係式 y = ax^2 + bx
   2 當不存在h 的情況 ,拋物線startPoint爲頂點, 此時關係式 y = ax^2 
   */

   /* 參數校驗 */
   function Validityparameter() {
       let isOkey = true
       Array.isArray(startPoint) && startPoint.length !== 2 && (isOkey = false)
       Array.isArray(endPoint) && endPoint.length !== 2 && (isOkey = false)
           (point.constructor !== Number) && (isOkey = false)
       return isOkey
   }

   /* 參數驗證 */
   if (!Validityparameter()) {
       return []
   }

   /* A點橫座標 */
   const xA = 0
   /* A點縱座標 */
   const yA = 0
   /* x軸偏移量 */
   const offsetX = startPoint[0]
   /* y軸偏移量 */
   const offsetY = startPoint[1]
   /* B點橫座標 */
   const xB = endPoint[0] - offsetX
   /* B縱座標 */
   const yB = endPoint[1] - offsetY

   /* 根據B點座標和最大高度h求係數a,b 參數*/
   let b = 0
   let a = 0

   /* 計算係數 a ,b */
   function handerComputer() {
       if (h < 10) {
           a = yB / Math.pow(xB, 2)
       } else {
           /* 因爲一般購物車的情況都是向下,實際上我們購物車的座標系是反向的,所以我們這裏要把h 設置成負值 */
           h = -h
           /* 一元二次求解a,b ,現在知道一點  ( xB , yB ) 另外一點 ( maxHx,h )  */
           /* 有效達到最高點時候的x座標 */
           const effectMaHx = hclientX && Math.abs(hclientX - offsetX) > 0 && Math.abs(hclientX - offsetX) < Math.abs(xB)
           /* 如果hclientX不滿足要求,則選A , B 中點爲   */
           let maxHx = effectMaHx ? (hclientX - offsetX) : (xB + xA) / 2
           /* 已知兩點 求 a , b值  根據解方程式解得 y = ax^2 + bx  */
           a = ((yB / xB) - (h / maxHx)) / (xB - maxHx)
           /* 將 a 帶入其中一個求解 b */
           b = (yB - a * Math.pow(xB, 2)) / xB
       }
   }


   /* 軌跡數組 */
   const travelList = []
   /* x 均等分 */
   const averageX = (xB - xA) / point

   /* 處理直線運動 */
   function handerLinearMotion(type) {
       if (type === 'X') {
           const averageY = (yB - yA) / point
           for (let i = 1; i <= point; i++) {
               travelList.push([offsetX, i * averageY + offsetY])
           }
       } else {
           for (let i = 1; i <= point; i++) {
               travelList.push([offsetX + i * averageX, offsetY])
           }
       }
       return travelList
   }

   /* 當 xB的絕對值小於10的情況,我們看作Y軸直線運功    */
   if (Math.abs(xB) < 10) {
       return handerLinearMotion('X')
   }
   /*當 yB的絕對值小於10的情況,我們看作x軸直線運功  */
   if (Math.abs(yB) < 10) {
       return handerLinearMotion('Y')
   }

   handerComputer()
   /* 繪製路徑 */
   for (let i = 1; i <= point; i++) {
       const currentX = averageX * i
       const currentY = Math.pow(currentX, 2) * a + b * currentX - yA
       travelList.push([currentX + offsetX, currentY + offsetY])
   }

   return travelList
}

export default flycart

效果

在這裏插入圖片描述

小程序h5飛入購物車組件?

這裏可以把這個方案和組件聯繫到一起,於是乎飛入購物車組件就搞定了,這裏大家要記住的點

1此方案得到的是拋物線各點的left,top值,我們只需要定時改變飛入購物車的圖片的left值 ,top就可以

2可以通過計數器功能來改變縮放比,說白了就是改變圖片transform:scale值

3不要忘記給圖片加上fixed固定定位哦😄😄😄

主要方法

 startCart(){
    /* 開啓購物車 */
    /* this.start 儲存起始點 clientY clientY  ,this.end儲存最終點 clientX clientY*/
    this.start = {}
    this.start['x'] = this.data.current['x']
    this.start['y'] = this.data.current['y']
    const travelList = flycart([ this.start['x'] , this.start['y'] ] ,[ this.end['x'] , this.end['y'] ],25,50 )
    this.startAnimate(travelList)
        },
 startAnimate(travelList) {
    let index = 0
    this.setData({
        cartHidden: false,
        bus_x: this.start['x'],
        bus_y: this.start['y']
    })
    if(travelList.length===0) return
    this.timer = setInterval( ()=> {
        index++
        const currentPoint = travelList.shift()
        this.setData({
            bus_x: currentPoint[0],
            bus_y: currentPoint[1],
            scale: 1 - index / 25
        })
        if (travelList.length === 0) {
            clearInterval(this.timer)
            this.triggerEvent('close')
        }
    }, 33)
}

這裏只做了原生小程序飛入購物車組件,h5大致差別不大。

git地址如下

代碼地址https://github.com/AlienZhaolin/flycart

謝謝大家鼓勵與支持🌹🌹🌹

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章