自己照着别人教程写的canvas操作类
预览图
类源码
/*
* @Author: mulingyuer
* @Date: 2021-06-21 11:29:12
* @LastEditTime: 2021-06-21 18:39:31
* @LastEditors: mulingyuer
* @Description: canvas
* @FilePath: \form-create\src\utils\canvas.js
* 怎么可能会有bug!!!
*/
class Chart {
constructor(options) {
const defaultOptions = {
el: null, //dom或者选择器
data: [], //组件数据
scale: 1, //canvas缩放等级
minScale: 0.2, //最小缩放
maxScale: 3, //最大缩放
scaleStep: 0.1, //每次缩放比率
offsetX: 0, //画布x轴缩放偏移值
offsetY: 0, //画布y轴缩放偏移值
};
//合并配置
Object.assign(this, defaultOptions, options);
this.init(); //初始化
this.addScaleEvent(); //添加缩放
this.addCanvasDragEvent(); //添加画布拖拽
this.render(); //首次渲染
}
//初始化
init() {
this.wrap = null;
//获取容器
if (typeof this.el === "string") {
this.wrap = document.querySelector(el);
} else {
if (this.utils.getType(this.el) !== "htmldivelement") {
throw new Error("el参数不正确:它应该是选择器或者dom对象");
}
this.wrap = this.el;
}
//获取容器样式&创建canvas
const wrapStyle = getComputedStyle(this.wrap);
this.width = parseInt(wrapStyle.width, 10);
this.height = parseInt(wrapStyle.height, 10);
this.canvas = document.createElement('canvas');
this.canvas.width = this.width;
this.canvas.height = this.height;
this.ctx = this.canvas.getContext('2d');
this.wrap.appendChild(this.canvas);
}
//绘制背景图
drawBg(bgData) {
const { src, data } = bgData;
if (!src) return;
if (bgData.el) {
this.ctx.drawImage(bgData.el, data.left ?? 0, data.top ?? 0, data.width ?? 0, data.height ?? 0);
} else {
bgData.el = new Image();
bgData.el.onload = () => {
this.ctx.drawImage(bgData.el, data.left ?? 0, data.top ?? 0, data.width ?? 0, data.height ?? 0);
};
bgData.el.src = src;
}
}
//是否为背景图
isDrawBg(itemData, x, y) {
const { data } = itemData;
const isX = x >= data.left && x <= data.left + data.width;
const isY = y >= data.top && y <= data.top + data.height;
return isX && isY;
}
//添加滚轮缩放事件
addScaleEvent() {
//移入-添加
this.canvas.addEventListener('mouseenter', () => {
document.addEventListener('mousewheel', this.scaleMouseWhell, { passive: false });
document.addEventListener('DOMMouseScroll', this.scaleMouseWhell, { passive: false }); //火狐
});
//移出-删除
this.canvas.addEventListener('mouseleave', () => {
document.removeEventListener('mousewheel', this.scaleMouseWhell, { passive: false });
document.removeEventListener('DOMMouseScroll', this.scaleMouseWhell, { passive: false });//火狐
});
}
//缩放滚轮
scaleMouseWhell = (event) => {
//阻止默认事件 (缩放时外部容器禁止滚动)
event.preventDefault();
const delta = event.deltaY || event.detail;
// const x = event.offsetX - this.offsetX;
// const y = event.offsetY - this.offsetY;
const offsetX = (x / this.scale) * this.scaleStep;
const offsetY = (y / this.scale) * this.scaleStep;
if (delta > 0) {
//往下滚-缩放
// this.offsetX -= this.scale >= this.maxScale ? 0 : offsetX;
// this.offsetY -= this.scale >= this.maxScale ? 0 : offsetY;
this.scale -= this.scaleStep
} else {
//往上滚-放大
// this.offsetX += this.scale <= this.minScale ? 0 : offsetX;
// this.offsetY += this.scale <= this.minScale ? 0 : offsetY;
this.scale += this.scaleStep;
};
this.scale = Math.min(this.maxScale, Math.max(this.scale, this.minScale));
//重新渲染
this.render();
}
//添加画布拖拽事件
addCanvasDragEvent = () => {
this.canvas.addEventListener('mousedown', this.addMoveEvent);
document.addEventListener('mouseup', this.removeMoveEvent);
}
//添加鼠标移动 功能,获取保存当前点击坐标
addMoveEvent = (event) => {
this.targetX = event.offsetX;
this.targetY = event.offsetY;
this.mousedownOriginX = this.offsetX;
this.mousedownOriginY = this.offsetY;
const x = (this.targetX - this.offsetX) / this.scale;
const y = (this.targetY - this.offsetY) / this.scale;
//判断移动的是谁
this.activeModData = null;
this.data.forEach((itemData, index) => {
switch (itemData.type) {
case 'background':
if (this.isDrawBg(itemData, x, y)) {
//提高层级
this.data.push(...this.data.splice(index, 1));
this.draw(itemData);
this.activeModData = itemData;
}
break;
}
});
if (!this.activeModData) {
this.wrap.style.cursor = 'grabbing'
this.canvas.addEventListener('mousemove', this.moveCanvasFunc, false);
} else {
this.wrap.style.cursor = 'all-scroll'
this.modOldX = null
this.modOldY = null
this.canvas.addEventListener('mousemove', this.moveModFunc, false)
}
}
//移除拖拽事件
removeMoveEvent = () => {
this.wrap.style.cursor = '';
this.canvas.removeEventListener('mousemove', this.moveCanvasFunc, false);
this.canvas.removeEventListener('mousemove', this.moveModFunc, false);
}
//画布拖拽方法
moveCanvasFunc = (event) => {
// 获取 最大可移动宽
const maxMoveX = this.canvas.width / 2;
const maxMoveY = this.canvas.height / 2;
const offsetX = this.mousedownOriginX + (event.offsetX - this.targetX);
const offsetY = this.mousedownOriginY + (event.offsetY - this.targetY);
this.offsetX = Math.abs(offsetX) > maxMoveX ? this.offsetX : offsetX;
this.offsetY = Math.abs(offsetY) > maxMoveY ? this.offsetY : offsetY;
this.render()
}
//模块拖动事件
moveModFunc = (event) => {
let moveX = event.offsetX - (this.modOldX || this.targetX);
let moveY = event.offsetY - (this.modOldY || this.targetY);
moveX /= this.scale
moveY /= this.scale
switch (this.activeModData.type) {
case 'background':
const { data } = this.activeModData;
let x = data.left;
let y = data.top;
Object.assign(this.activeModData.data, { left: x + moveX, top: y + moveY })
break;
}
this.modOldX = event.offsetX
this.modOldY = event.offsetY
this.render()
}
//通用绘制方法
draw(data) {
this.ctx.setTransform(this.scale, 0, 0, this.scale, this.offsetX, this.offsetY);
switch (data.type) {
case 'background':
this.drawBg(data);
break;
default:
console.log("该组件数据暂不支持", data);
}
}
//渲染
render() {
this.canvas.width = this.width;
this.data.forEach(itemData => {
this.draw(itemData);
});
}
//push
push(data) {
this.data.push(data);
this.draw(data);
}
//工具
utils = {
//获取文件类型
getType(value) {
let type = typeof value;
if (type !== "object") {
return type;
}
return Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
}
}
}
export default Chart;
使用
const $canvas = new Chart({
el: this.$refs.chartWrap,
data: [],
});
$canvas.push({
id: uuid(),
type: "background",
src: "https://testsuperres.shetuan.pro/cos/admin/images/20210427/928c2e5ba23997b3e19307608b2fe76e.png",
data: {
top: 20,
left: 18,
width: 80,
height: 80,
},
});
$canvas.push({
id: uuid(),
type: "background",
src: "https://testsuperres.shetuan.pro/cos/admin/images/20210408/843ebf2969ad1635cf893ec74887ddd8.png",
data: {
top: 20,
left: 18,
width: 364,
height: 350,
},
});
参考文章
分类:
JavaScript
标签:
canvasjavascriptclass类
版权申明
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
暂无评论数据