konva.js 工具类
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.scaleX = 0;
this.scaleY = 0;
// 鼠标滚轮控制的放大缩小倍数
this.scaleByX = 1;
this.scaleByY = 1;
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 x = this.stage.width() * 0.5 - element_x;
let y = this.stage.height() * 0.5 - 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,
},
id: id,
});
kImage.rotate(rotate);
that.layer.add(kImage);
console.log(`图片加载完成`);
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);
}
if (attr.y) {
attr.y = isNaN(Number(attr.y)) ? 0 : Number(attr.y);
}
if (attr.rotation) {
attr.rotation = isNaN(Number(attr.rotation)) ? 0 : Number(attr.rotation);
}
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 = "#ffffff") {
if (!this.layer) return;
var line = new Konva.Line({
points: points || [],
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.on("wheel", e => {
const direction = e.evt.deltaY > 0 ? -0.05 : 0.05;
this.scale = this.scale + direction;
this.stage.scaleX(this.scale);
this.stage.scaleY(this.scale);
this.stage.draw();
});
}
// ========================================== 私有方法 end
}
export default KonvaCanvas;