konva.js 工具类

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;
相关推荐
闲人编程8 小时前
Python的抽象基类(ABC):定义接口契约的艺术
开发语言·python·接口·抽象类·基类·abc·codecapsule
qq_172805598 小时前
Go 语言结构型设计模式深度解析
开发语言·设计模式·golang
lkbhua莱克瓦249 小时前
集合进阶8——Stream流
java·开发语言·笔记·github·stream流·学习方法·集合
骑自行车的码农9 小时前
🍂 React DOM树的构建原理和算法
javascript·算法·react.js
北极糊的狐9 小时前
Vue3 中父子组件传参是组件通信的核心场景,需遵循「父传子靠 Props,子传父靠自定义事件」的原则,以下是资料总结
前端·javascript·vue.js
20岁30年经验的码农9 小时前
Java Elasticsearch 实战指南
java·开发语言·elasticsearch
雾岛听蓝9 小时前
C++ 类和对象(一):从概念到实践,吃透类的核心基础
开发语言·c++·经验分享·笔记
CoderYanger9 小时前
优选算法-优先级队列(堆):75.数据流中的第K大元素
java·开发语言·算法·leetcode·职场和发展·1024程序员节
TracyCoder1239 小时前
MySQL 实战宝典(八):Java后端MySQL分库分表工具解析与选型秘籍
java·开发语言·mysql
非凡的世界9 小时前
为什么我和越来越多的PHP程序员,选择了 Webman ?
开发语言·php·workman·webman