UNPKG

test-whiteboard

Version:

https://gitlab.gridsum.com/gov_law_tech/FrontEnd/whiteboard

335 lines (265 loc) 9.52 kB
import Mixin from './mixin'; import EventEmitter from './eventEmitter'; import math from 'mathjs'; import Stroke from './stroke'; import WhiteboardLine from './whiteboardLine'; import {canvasTransform} from 'canvas-transform'; class LineDataStore { constructor() { this.data = []; this.maxId = 1; } addData(line) { this.data.push(line); this.maxId++; } getNextId() { return this.maxId; } deleteData(groupId) { this.data = this.data.filter(function (item) { return item.groupId != groupId; }); } getMaxGroupId() { if (this.data.length == 0) { return 0; } else { return this.data[this.data.length - 1].groupId; } } } export default class LineDrawer extends Mixin(EventEmitter) { constructor(element, mode, transform) { super(); this.hasInit = false; this.canDraw = false; this.groupIndex = 0; this.currentGroup = null; this.root = element; this.mode = mode; this.canvas = element; this.context = element.getContext('2d'); // var grd = this.context.createLinearGradient(0, 0, 175, 50); // grd.addColorStop(0, "#FF0000"); // grd.addColorStop(1, "#00FF00"); // this.context.fillStyle = grd; // this.context.fillRect(0, 0, 175, 50); console.log('line constructor --') // 创建 临时画布 var cacheCanvas = document.createElement('canvas'); var cacheContext = cacheCanvas.getContext('2d'); cacheCanvas.width = this.canvas.width; cacheCanvas.height = this.canvas.height; this.cacheCanvas = cacheCanvas; this.cacheContext = cacheContext; this.eventDic = [ 'action_deleteLine', 'action_drawLine', 'notify_drawLine', 'notify_deleteLine' ]; this.currentLineData = null; this.dataStore = new LineDataStore(); this.on('action_deleteLine', this.delete.bind(this)); this.on('action_drawLine', this.draw.bind(this)); this.canvasTransform = transform; this.canvasTransform.drawCanvas(element); } init() { console.log('line init') let me = this; me.hasInit = true var context = this.context; var canvas = this.canvas; var bound = canvas.getBoundingClientRect(); var offsetLeft = bound.left; var offsetTop = bound.top; if (me.mode == 'view') { return; } var root = this.root; root.onmousedown = function (event) { if (!me.canDraw) { return; } if (event.button == 0) { //左键按下 offsetLeft = bound.left; offsetTop = bound.top; console.log('line ', offsetLeft, offsetTop) var groupIndex = me.dataStore.getMaxGroupId(); me.groupIndex = groupIndex + 1; var start = { x: event.clientX - offsetLeft, y: event.clientY - offsetTop }; //使用矩阵 自动计算新的坐标 var reverseMatrix = me.calReverseMatrix() var newCoord = me.matrixMultiCoor(reverseMatrix, [start.x, start.y]) start.x = newCoord[0]; start.y = newCoord[1]; console.log(start.x, start.y) console.log('draw start ', JSON.stringify(start)) var stroke = new Stroke(); me.currentLineData = new WhiteboardLine(me.groupIndex, stroke, -1, start); me.canDraw = true; console.log('line mousedown ') } } root.onmousemove = function (event) { if (!me.canDraw) { return; } if (!me.currentLineData) { return; } var currentData = me.currentLineData; var position = { x: event.clientX, y: event.clientY }; if (position.x != currentData.start.x || position.y != currentData.start.y) { var stroke = new Stroke(); var id = me.dataStore.getNextId(); var start = { x: currentData.start.x, y: currentData.start.y }; var end = { x: position.x - offsetLeft, y: position.y - offsetTop }; //使用矩阵 自动计算新的坐标 var reverseMatrix = me.calReverseMatrix() var newCoord = me.matrixMultiCoor(reverseMatrix, [end.x, end.y]) end.x = newCoord[0]; end.y = newCoord[1]; var lineData = new WhiteboardLine( me.groupIndex, stroke, id, start, end ); me.dataStore.addData(lineData); me.canvasTransform.lineStore = me.dataStore me.emit('notify_drawLine', lineData); me.draw(lineData); me.currentLineData = { groupId: lineData.groupId, id: lineData.id, start: { x: lineData.end.x, y: lineData.end.y }, end: { x: -1, y: -1 } }; // me.emit('notify_drawLine',me.currentLineData); } } root.onmouseup = function (event) { if (event.button == 0) { //左键弹起 // me.canDraw = false; context.closePath(); me.currentLineData = null; // me.canvasTransform.drawCanvas(canvas); // canvas宽高会改变 //.store(); } } } draw(data) { //绘制前先保存 var start = data.start; var end = data.end; this.context.beginPath(); this.context.moveTo(start.x, start.y); this.context.lineTo(end.x, end.y); this.context.stroke(); } // 重新画线 reDrawLine() { var me = this this.canvas.setAttribute('width',this.canvas.width) this.context.setTransform.apply(this.context,this.canvasTransform.matrix) me.dataStore.data.forEach(function (item) { me.draw(item); }) } // 删除最近一次画线 delete() { var groupId = this.groupIndex; var group = document.getElementById('draw_group_' + groupId); if(group){ group.remove(); } if (groupId) { this.dataStore.deleteData(groupId); this.canvasTransform.lines = this.dataStore this.groupIndex = this.dataStore.getMaxGroupId(); this.currentGroup = null; this.emit('notify_deleteLine', groupId); this.reDrawLine() } } // 计算逆矩阵 calReverseMatrix(){ var me = this var matrix = me.canvasTransform.matrix var oriMat = math.matrix([ [1, 0, 0], [0, 1, 0], [0, 0, 1] ]) var curMat = math.matrix([ [matrix[0], matrix[2], matrix[4]], [matrix[1], matrix[3], matrix[5]], [0, 0, 1] ]) var revMat = math.divide(oriMat, curMat) var revMatData = revMat._data // if(Math.abs(degR) == 90 || Math.abs(degR) == 270) if (revMatData[0][2] == 0) { if (matrix[4] != 0) { revMatData[0][2] = revMatData[1][2] / matrix[4] * matrix[5] * -1 } else { revMatData[0][2] = 0 } } var reverseMatrix = [revMatData[0][0], revMatData[1][0], revMatData[0][1], revMatData[1][1], revMatData[0][2], revMatData[1][2]] return reverseMatrix } // 计算逆矩阵的坐标 matrixMultiCoor(matrix1, coord) { var x = 0, y = 0 x = matrix1[0] * coord[0] + matrix1[2] * coord[1] + matrix1[4] * 1 y = matrix1[1] * coord[0] + matrix1[3] * coord[1] + matrix1[5] * 1 return [x, y] } active(active) { if (!this.hasInit && active) { this.init(); } if (!active) { this.canDraw = false; this.root.style.zIndex = '101'; this.root.style.cursor = 'move'; this.canvasTransform.canMove = true } else { this.root.style.zIndex = '99'; this.root.style.cursor = 'crosshair'; } if (this.hasInit && active) { this.canDraw = true; console.log('line active draw line') this.canvasTransform.canMove = false } } }