konva.js 工具类
import StringUtils from "./StringUtil.js";class KonvaCanvas {/*** 初始化画布* @param {String} domId 容器dom id*/constructor(domId) {this.layer = null;this.stage = null;this.scale = 1.0;this.init(domId);}/*** 聚焦到指定元素* @param {String} elementId 元素dom id*/focusOn(elementId) {if (!this.layer || !this.stage || !elementId) return;var element = this.stage.find("#" + elementId)[0];let element_x = StringUtils.isNumeric(element.position().x) ? element.position().x : Number(element.position().x);let element_y = StringUtils.isNumeric(element.position().y) ? element.position().y : Number(element.position().y);let halfStageWidth = this.stage.width() * 0.5;let halfStageHeight = this.stage.height() * 0.5;let x = 0;let y = 0;if (element_x < 0) {x = Math.abs(element_x - halfStageWidth);} else {x = halfStageWidth - element_x;}if (element_y < 0) {y = Math.abs(element_y - halfStageHeight);} else {y = halfStageHeight - element_y;}this.stage.scaleX(1.0);this.stage.scaleY(1.0);this.scale = 1.0;this.stage.x(x);this.stage.y(y);this.layer.draw();}/*** 绘制图片* @param {String} url 图片路径* @param {String} id 唯一标识* @param {Number} x 横坐标* @param {Number} y 纵坐标* @param {Number} zoom 缩放比例* @param {Number} rotate 旋转角度*/drawImage(url, id, x = 0, y = 0, zoom = 1.0, rotate = 0) {return new Promise((resolve, reject) => {var img = new Image();img.src = url;const that = this;img.onload = function () {const img_w = img.width * zoom;const img_h = img.height * zoom;var kImage = new Konva.Image({image: img,x: x,y: y,width: img_w,height: img_h,offset: {x: img_w / 2,y: img_h / 2,},scale: {x: 1.0,y: 1.0,},id: id,});kImage.rotate(rotate);that.layer.add(kImage);console.log(`图片加载完成`);that.layer.draw();resolve(kImage);};});}/*** 更新元素属性信息* @param {String} id 元素id* @param {Object} attr 元素属性 {}*/updateElement(id, attr) {if (!this.layer || !this.stage) return;var shape = this.stage.find("#" + id)[0];if (shape) {if (attr.x) {attr.x = isNaN(Number(attr.x)) ? 0 : Number(attr.x);} else {attr.x = 0;}if (attr.y) {attr.y = isNaN(Number(attr.y)) ? 0 : Number(attr.y);} else {attr.y = 0;}if (attr.rotation) {attr.rotation = isNaN(Number(attr.rotation)) ? 0 : Number(attr.rotation);}if (attr.points) {let points = [];attr.points.forEach(element => {let val = Number(element);points.push(val);});attr.points = points;}attr = {...shape.getAttrs(),...attr,};shape.setAttrs(attr);this.stage.batchDraw(); //重绘}}/*** 绘制线* @param {Array} points 点位坐标 [x1, y1, x2, y2, x3, y3]* @param {String} id 唯一标识* @param {Number} lineWidth 线宽* @param {String} color 颜色* @returns*/drawLine(points, id, lineWidth = 1, color = "#72F31D") {if (!this.layer) return;let points2 = [];points.forEach(element => {let val = Number(element);points2.push(val);});var line = new Konva.Line({points: points2,stroke: color,strokeWidth: lineWidth,lineCap: "round",lineJoin: "round",tension: 0.5,id: id,});this.layer.add(line);}/*** 销毁画布*/destroyed() {if (this.layer) {this.layer.destroyChildren();this.layer.draw();}}// ========================================== 私有方法init(domId) {if (!domId) {return;}const container = document.getElementById(domId);var width = container.clientWidth;var height = container.clientHeight;var stage = new Konva.Stage({container: domId,width: width,height: height,draggable: true,});var layer = new Konva.Layer();stage.add(layer);this.stage = stage;this.layer = layer;this.stage.scaleX(this.scale);this.stage.scaleY(this.scale);this.stage.on("wheel", e => {const direction = e.evt.deltaY > 0 ? -0.08 : 0.08;this.scale = this.scale + direction;this.scale = this.scale < 0 ? 0 : this.scale;this.stage.scaleX(this.scale);this.stage.scaleY(this.scale);// 以鼠标为锚点缩放let pointer = this.stage.getPointerPosition();this.stage.x(-((pointer.x - this.stage.x()) * (this.scale / (this.scale - direction)) - pointer.x));this.stage.y(-((pointer.y - this.stage.y()) * (this.scale / (this.scale - direction)) - pointer.y));this.layer.draw();});}// ========================================== 私有方法 end
}export default KonvaCanvas;