事件坐標與 transform:scale 引發的問題

問題

當前需要開發彈窗拖拽移動功能,在通過mousemove計算坐標點位時,出現計算后點位始終與鼠標坐標存在一定比例差異,并且距離初始未知越遠差距越大。

移動計算公式

這里需要被移動塊與初始點擊點做相對偏移移動, 所以可知移動前后鼠標所在點與被移動塊的相對距離不變
x1, y1 移動塊初始坐標
px1, py1 鼠標按下初始坐標
x2, y2 移動后移動塊坐標
px2, px2 鼠標移動后坐標

px1 - x1 = px2 - x2
py1 - y1 = py2 - y2

求移動后的塊坐標

x2 = x1 + px2 - px1
y2 = y1 + py2 - py1

debug

  1. 將計算邏輯提取,放置到無任何依賴的純環境中, 計算結果正常, 未存在比例差問題
  2. 判斷問題與調用環境有關, 切換不同組件,上下文依舊, 所以與全局配置有關
  3. 切換不同屏幕比例,比例差不同,所以問題與屏幕適配有關
  4. 發現當前環境中使用的 transform:scale 做屏幕適配

解決

這里出現的問題是,通過mousemove獲取的 e.pageX, e.pageY 是相對于頁面的尺寸,不受全局樣式 transform:scale 的影響, 而實際dom定位是經過比例縮放的,所以始終存在一個比例差問題,且鼠標移動距離越遠,差距越大。
這里需要將 e.pageX, e.pageY 也做比例尺轉換,在做坐標計算。最終得出正確結果

x2 = x1 + px2*scale - px1
y2 = y1 + py2 *scale - py1

  function onMouseDown (e) {
  //  轉換初始坐標
    prePosition.value = ratePosition({
      startX: e.pageX,
      startY: e.pageY
    })

    ctx.emit('blockMouseDown', { ...prePosition.value })
    document.addEventListener('mousemove', throttledMove)
    document.addEventListener('mouseup', onMouseUp)
  }

 function onMouseMove (e) {
  //  轉換移動坐標
    const { startX, startY } = prePosition.value
    const { pageX, pageY } = ratePosition({
      pageX: e.pageX,
      pageY: e.pageY
    })
   ...
}

// 轉換函數
  function ratePosition (position = {}) {
    const rate = getSacleRate() // 獲取當前比例尺
    return Object.entries(position).reduce((acc, [prop, value]) => {
      return {
        ...acc,
        [prop]: value / rate
      }
    }, {})
  }


?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容