1. 程式人生 > 其它 >canvas 實現簽名效果

canvas 實現簽名效果

效果圖

概述

線上簽名,現在在很多場景下都能看到,而且在移動端見的比較多。

canvassvg都可以實現,而且跨平臺能力也很好。

  • canvas基於畫素,提供 2D 繪製函式,提供的功能更原始,適合畫素處理、動態渲染和大量資料繪製,可控性高,繪製完了基本不記錄過程,繪圖效能會更好一點,各大廠商也早都實現了canvas的硬體加速機制。而且能夠以.png.jpg格式儲存結果影象
  • svg為向量,提供一序列圖形元素,功能更完善,建立了一大堆可互動物件,本性長於互動,但效能會弱些,更適合靜態圖片展示,高保真文件檢視和列印的應用場景。

兩者各有自己擅長的領域,基於以上,以下是用canvas

實現的移動端簽字功能。從建立、設定、監聽繪製、重繪、儲存等進行處理。

程式碼

html結構

<div id="canvas">
    <p id="clearCanvas">清除</p>
    <p id="saveCanvas">儲存</p>
</div>

css樣式

html,
body {
    width: 100%;
    height: 100%;
}

* {
    margin: 0;
    padding: 0;
}

#canvas {
    position: relative;
    width: 100%;
    height: 100%;
}

#canvas canvas {
    display: block;
}

#clearCanvas,
#saveCanvas {
    position: absolute;
    bottom: 0;
    z-index: 1;
    width: 50%;
    height: 40px;
    border: 1px solid #dedede;
    line-height: 40px;
    text-align: center;
}

#clearCanvas {
    left: 0;
}

#saveCanvas {
    right: 0;
}

.errorCanvas {
    width: 100%;
    height: 100%;
    text-align: center;
    transform: translateY(40%);
}

js內容

window.onload = function () {
  new lineCanvas({
    el: document.querySelector('#canvas'),
    clearEl: document.querySelector('#clearCanvas'),
    saveEl: document.querySelector('#saveCanvas'),
    // lineWidth: 1, // 線條粗細
    // color: 'black', // 線條顏色
    // background: '#fff'
  });
}

function lineCanvas(obj) {
  this.lineWidth = 5;
  this.color = '#000';
  this.background = '#fff';
  for (var i in obj) {
    this[i] = obj[i];
  };

  this.canvas = document.createElement('canvas');
  if (!(this.canvas.getContext && this.canvas.getContext('2d'))) {
    this.section = document.createElement('section');
    this.section.className = 'errorCanvas';
    this.section.innerHTML = '對不起,當前瀏覽器暫不支援此功能!'
    this.el.prepend(this.section);
    return
  }
  this.canvas.width = this.el.clientWidth;
  this.canvas.height = this.el.clientHeight;
  this.el.prepend(this.canvas);

  this.cxt = this.canvas.getContext('2d');
  this.cxt.fillStyle = this.background;
  this.cxt.fillRect(0, 0, this.canvas.width, this.canvas.height);
  this.cxt.strokeStyle = this.color;
  this.cxt.lineWidth = this.lineWidth;
  this.cxt.lineCap = 'round'; // 線條末端新增圓形線帽,減少線條的生硬感
  this.cxt.lineJoin = 'round'; // 線條交匯時為原型邊角
  // 利用陰影,消除鋸齒
  this.cxt.shadowBlur = 1;
  this.cxt.shadowColor = '#000';

  // 開始繪製
  this.canvas.addEventListener('touchstart', function (e) {
    this.cxt.beginPath();
    this.cxt.moveTo(e.changedTouches[0].pageX, e.changedTouches[0].pageY);
  }.bind(this), false);

  // 繪製中
  this.canvas.addEventListener('touchmove', function (e) {
    this.cxt.lineTo(e.changedTouches[0].pageX, e.changedTouches[0].pageY);
    this.cxt.stroke();
  }.bind(this), false);

  // 結束繪製
  this.canvas.addEventListener('touchend', function (e) {
    this.cxt.closePath();
  }.bind(this), false);

  // 清除畫布
  this.clearEl.addEventListener('click', function () {
    this.cxt.clearRect(0, 0, this.canvas.width, this.canvas.height);
  }.bind(this), false);

  // 儲存圖片
  this.saveEl.addEventListener('click', function () {
    var imgBase64 = this.canvas.toDataURL();
    var imgPng = this.canvas.toDataURL('image/png');
    var imgJpg = this.canvas.toDataURL('image/jpeg', 0.8);
    console.log(imgPng, imgJpg);
  }.bind(this), false);
}