canvas實現手寫簽名並旋轉base64圖片

思路:

1. touchstart:當手指觸摸屏幕時,獲取初始座標,lastPos.x,lastPos.y。
2. touchmove: 當手指在屏幕上滑動的時,獲取當前座標,curLoc.x,curLoc.y。
起始位置爲鼠標落下的位置(lastPos.x,lastPos.y), 結束位置爲當前位置(curLoc.x,curLoc.y),從新設置初始座標(lastPos.x,lastPos.y)canvas

元素相對於視窗的位置集&點擊位置距離當前body可視區域的x,y座標

若是直接用鼠標點擊的座標在canvas上繪圖的話,會發現,畫出來的線,座標永遠都是有誤差的。後端

如圖,鼠標的座標系原點,和canvas的座標系原點,不是同一個。就形成了差異。紅色矩形在canvas上起始座標,是鼠標落下的x軸距離,減去畫布離頁面的距離pageX-left. bash

getBoundingClientRect()

getBoundingClientRect用於獲取某個元素相對於視窗的位置集合。集合中有top, right, bottom, left等屬性。你瞭解getBoundingClientRect()?post

完整代碼

// 獲取鼠標位置在畫布上的距離
      windowToCanvas(x,y){
        let rect = this.can.getBoundingClientRect()
        // x和y參數分別傳入的是鼠標距離窗口的座標,而後減去canvas距離窗口左邊和頂部的距離。
        return {
         x: x - rect.left 
         y: y - rect.top
        };
      },
        touchStart(e) {
        // 上一次的座標
        this.lastPos = this.windowToCanvas(e.touches[0].clientX,e.touches[0].clientY);
      },
       touchMove(e) {
        // 得到當前座標
        let curLoc =this.windowToCanvas(e.touches[0].clientX,e.touches[0].clientY);
        let lineWidth = 5;
        this.ctx.lineWidth=lineWidth;
        this.ctx.beginPath();
        // 起始位置爲鼠標落下的位置
        this.ctx.moveTo(this.lastPos.x,this.lastPos.y);
        // 結束位置爲當前位置
        this.ctx.lineTo(curLoc.x,curLoc.y);
        this.ctx.strokeStyle= 'black';
        this.ctx.stroke();
        // 將當前座標賦值給上一次座標
        this.lastPos = curLoc;
      },
複製代碼
<canvas id='canvas' class="canvas"
            @touchstart="touchStart"
            @touchmove="touchMove"
    ></canvas>  
複製代碼

旋轉base64圖片

調用toDataURL,把canvas轉爲base64發送給後端。發現發送過去的base64圖片是反的。 ui

但願是這樣的this

思路

  1. 畫布旋轉合適的角度,把傳入的base64圖片,畫在新建的畫布上
  2. getImageData() 提取裁剪後圖像數據
  3. putImageData()把提取的圖像數據畫到畫布上
  4. 調用toDataURL,生成最終的base64字符串

如圖,

1.爲了方便計算,新建畫布的寬高都設爲base64圖片的高度的兩倍
2.畫筆位移到畫布中心,如圖灰色的矩形
3.畫筆旋轉90度,如圖藍色矩形
4.設定裁剪座標,{sx: 0, sy: 0, ex: 0, ey: 0}
sx:開始複製的左上角位置的 ,如圖,image.heihgt
sy:開始複製的左上角位置的 y 座標,如圖,image.heihgt-image.width
ex:將要複製的矩形區域的寬度。如圖,image.height,
ey:將要複製的矩形區域的高度。url

rotateBase64(data){   //傳入須要旋轉的base64圖片
        return new Promise((resolve, reject) => {
          const imgView = new Image();
          imgView.src = data;
          const canvas = document.createElement('canvas');
          const context = canvas.getContext('2d');
          const cutCoor = {sx: 0, sy: 0, ex: 0, ey: 0}; // 裁剪座標
          imgView.onload = () => {
            const imgW = imgView.width;
            const imgH = imgView.height;
            const size = imgH;
            canvas.width = size * 2;
            canvas.height = size * 2;
            cutCoor.sx = size;
            cutCoor.sy = size - imgW;
            cutCoor.ex = size + imgH;
            cutCoor.ey = size + imgW;
            context.translate(size, size);
            context.rotate(Math.PI/2*3);
            context.drawImage(imgView, 0, 0);
            const imgData = context.getImageData(cutCoor.sx, cutCoor.sy, cutCoor.ex, cutCoor.ey);
            canvas.width = imgH;
            canvas.height = imgW;
            context.putImageData(imgData, 0, 0);
            resolve(canvas.toDataURL('image/png'));
          };
        });
      },
複製代碼

能夠這樣調用spa

rotateBase64(imgData)
            .then((img) => {
            console.log(`旋轉後的base64圖片:${img}`)
            });
複製代碼

延伸

後臺要求的是發送base64格式的圖片,若是,後臺要求其餘格式的呢。因而,我在想到底圖片有多少種顯示形式,之間又是怎樣切換的。 圖片的三種表現形式url、base6四、blob,三者之間是否能夠轉化以知足需求呢?3d

相關文章
相關標籤/搜索