signature.js 7.25 KB
/**
 * @param {*} params {}
 * /**
 *  whiteBord 白板盒子canvas id名
 *  popverBox 确认签字以后想要隐藏掉的盒子
 *  againWrite 重写按钮id名
 *  sureWrite 确定按钮id名
 *  mobileOri 移动端方向
 *  canvasWidth 画布宽
 *  canvasHeight 画布高
 *  writeColor 轨迹颜色
 *  clearWriteCallback 重写后的回调函数
 *  sureWriteCallback 确定签名之后的回调函数
 * @returns 签名的图片:格式base64
 */
let mobileOri = null;
let canvasWidth = null;
let canvasHeight = null;
let whiteBord = null;
let writeColor = "#000";
let hascontent = false;
let whiteBoardDom = null;
let clientWidth = document.documentElement.clientWidth;
let points = [];

export function signature(params) {
	console.log("signature");
	let {
		againWrite,
		sureWrite,
		clearWriteCallback,
		sureWriteCallback,
	} = params;
	whiteBord = params.whiteBord;
	whiteBoardDom = document.getElementById(whiteBord);
	let againWriteBtn = document.getElementById(againWrite);
	let sureWriteBtn = document.getElementById(sureWrite);
	let devicePixelRatio = window.devicePixelRatio;
	console.log(whiteBoardDom);
	canvasWidth = whiteBoardDom.offsetWidth;
	canvasHeight = whiteBoardDom.offsetHeight;
	let writeCanvas;
	let imageBase64='';
	againWriteBtn.addEventListener("click", function () {
		drawClear();
	})
	sureWriteBtn.addEventListener('click', function () {
		savePict();
	})
	function WriteFont() {
		let obj = {
			canvas: whiteBoardDom,
			context: whiteBoardDom.getContext("2d"),
			isWrite: false, //是否开始
			lastPoint: {}, //上次点
			writeWidth: 4, //初始轨迹宽度
			lastWriteTime: 0, /* 上次写入时间 */
			oldW: 4, /* 上次写入宽度 */
		}
		/**
		 * 轨迹宽度
		 */
		this.setLineWidth = function () {
			obj.context.lineWidth = obj.writeWidth;
		}

		/**
		 * 绘制轨迹
		 */
		this.writing = function (point) {
			points.push(point);
			obj.context.beginPath();
			if(mobileOri == "notlandscape") { /* 竖屏 */
				obj.context.moveTo(obj.lastPoint.y, clientWidth - obj.lastPoint.x);
				obj.context.lineTo(point.y, clientWidth - point.x);
			}else if(mobileOri == "landscape") { /* 横屏 */
				obj.context.moveTo(obj.lastPoint.x, obj.lastPoint.y);
				obj.context.lineTo(point.x, point.y );
			}else { /* pc端 */
				let x = (points[points.length - 2].x + points[points.length - 1].x) / 2;
				let y = (points[points.length - 2].y + points[points.length - 1].y) / 2;
				if(points.length == 2) {
					obj.context.moveTo(points[points.length - 2].x, points[points.length - 2].y);
					obj.context.lineTo(x, y);
				}else {
					let lastX = (points[points.length - 3].x + points[points.length - 2].x) / 2;
					let lastY = (points[points.length - 3].y + points[points.length - 2].y) / 2;
					obj.context.moveTo(lastX, lastY);
					obj.context.quadraticCurveTo(points[points.length - 2].x, points[points.length - 2].y, x, y); /* 贝塞尔曲线实现平滑效果 */
				}
				// obj.context.moveTo(obj.lastPoint.x, obj.lastPoint.y);
				// obj.context.lineTo(point.x, point.y);
			}

			// 动态计算画笔宽度
			let pow = Math.pow(point.x - obj.lastPoint.x, 2) + Math.pow(point.y - obj.lastPoint.y, 2)
			let d = Math.sqrt(pow);
			let nowTime = new Date().getTime();
			let v = d / (nowTime - obj.lastWriteTime);
			obj.lastWriteTime = nowTime;
			let w = 2 / v;
			let offset = 0.5;
			if(w - obj.oldW > offset) {
				w = obj.oldW + offset;
			}
			if(obj.oldW - w > offset) {
				w = obj.oldW - offset;
			}
			if (w < 2) {
				w = 2
			}
			if(w > 8) {
				w = 8
			}

			obj.writeWidth = w;
			obj.oldW = w;
			this.setLineWidth();
			obj.context.stroke();
			points.slice(0, 1);
			obj.lastPoint = point;
			obj.context.closePath();
			hascontent = true;
		}


		/**
		 * 轨迹样式
		 */
		this.writeContextStyle = function () {
			obj.context.beginPath();
			obj.context.strokeStyle = writeColor;
			obj.context.lineCap = 'round';
			obj.context.lineJoin = "round";
		}

		/**
		 * 写开始
		 */
		this.writeBegin = function (point) {
			obj.isWrite = true;
			obj.lastWriteTime = new Date().getTime();
			obj.lastPoint = point;
			points.push(point);
			this.writeContextStyle();
		}

		/**
		 * 写结束
		 */
		this.writeEnd = function () {
			obj.isWrite = false;
			points = [];
		}

		/**
		 * 清空画板
		 */
		this.canvasClear = function () {
			obj.context.save();
			obj.context.strokeStyle = '#fff';
			obj.context.clearRect(0, 0, canvasWidth, canvasHeight);
			obj.context.restore();
		}

		/**
		 * 初始化画板
		 */
		this.canvasInit = function () {
			whiteBoardDom.width = canvasWidth;
			whiteBoardDom.height = canvasHeight;
		}
		let that = this
		/**======================事件绑定===========================**/
		// 移动端
		whiteBoardDom.addEventListener('touchstart', function (e) {
			// console.log("touchstart");
			let point = {
				x: e.touches[0].pageX,
				y: e.touches[0].pageY
			};
			that.writeBegin(point);
			that.writing(point);
		}, {passive: false});
		whiteBoardDom.addEventListener('touchmove', function (e) {
			e.preventDefault();
			if (obj.isWrite) {
				let point = {
					x: e.touches[0].pageX,
					y: e.touches[0].pageY
				};
				that.writing(point);
			}
		}, {passive: false});
		document.addEventListener('touchend', function (e) {
			that.writeEnd();
		}, {passive: false});

		// pc端
		whiteBoardDom.addEventListener('mousedown', function (e) {
			let point = {
				x: e.offsetX,
				y: e.offsetY,
			};
			that.writeBegin(point);
			that.writing(point);
		}, {passive: false});
		whiteBoardDom.addEventListener('mousemove', function (e) {
			if (obj.isWrite) {
				let point = {
					x: e.offsetX,
					y: e.offsetY
				};
				that.writing(point);
			}
		}, {passive: false});
		document.addEventListener('mouseup', function (e) {
			that.writeEnd();
		}, {passive: false});

		this.canvasInit();
		this.canvasClear();
		obj.control = {
			clearCanvas: that.canvasClear
		};

		this.option = obj;

	}

	/**
			 * 初始化调用
			 * 设置参数
	*/
	writeCanvas = new WriteFont();

	function savePict() {
		if(hascontent) {
			imageBase64 = whiteBoardDom.toDataURL("image/png"); //base64
			writeCanvas.option.control.clearCanvas();
			sureWriteCallback(imageBase64)
		}else {
			sureWriteCallback("empty")
		}
		hascontent = false;
	}
	function drawClear() {
		writeCanvas.option.control.clearCanvas();
		hascontent = false;
		clearWriteCallback && clearWriteCallback();

	}
}

export function changeOri(event, color) {
	if(event == "changeColor") {
		writeColor = color;
	}else {
		mobileOri = event;
		clientWidth = document.documentElement.clientWidth;
		canvasWidth = whiteBoardDom.offsetWidth;
		canvasHeight = whiteBoardDom.offsetHeight;
		// 重设画布宽高
		whiteBoardDom.width = canvasWidth;
		whiteBoardDom.height = canvasHeight;
		// // 消除锯齿
		// let width = canvasWidth,
		// height = canvasHeight;
		// let whiteBoardDom = document.getElementById(whiteBord);
		// if (devicePixelRatio) {
		// 	console.log("devicePixelRatio", devicePixelRatio);
		// 	whiteBoardDom.style.width = width + "px";
		// 	whiteBoardDom.style.height = height + "px";
		// 	whiteBoardDom.height = height * devicePixelRatio;
		// 	whiteBoardDom.width = width * devicePixelRatio;
		// 	obj.context.scale(devicePixelRatio, devicePixelRatio);
		// }
		hascontent = false;
		return canvasWidth + "-" + canvasHeight
	}
}
export default {
	signature,
	changeOri,
}