Commit 8ec065fa authored by xinzhedeai's avatar xinzhedeai

add:canvas绘制方法封装rev1

parent c3989c8e
...@@ -156,6 +156,19 @@ export default { ...@@ -156,6 +156,19 @@ export default {
bgImage: null, // 背景图对象 bgImage: null, // 背景图对象
waterImage: null, // 新增:water.png 图片对象 waterImage: null, // 新增:water.png 图片对象
poImage: null, // 新增:po.png 图片对象 poImage: null, // 新增:po.png 图片对象
// Canvas绘制配置(支持批量扩展)
poConfigs: [
{ x: 0, y: null, width: 879, height: 150 }, // 第一张po.png配置
{ x: 0, y: null, width: 879 - 250, height: 150 } // 第二张po.png配置(宽度减少250px)
],
guanConfigs: [
{ x: null, y: null, width: 6, height: 121, image: 'guanImage' }, // 第一张guan0.png
{ x: null, y: null, width: 6, height: 200, image: 'guanImage' } // 第二张guan0.png(高度调整)
],
lineConfigs: [
{ points: [], color: 'red', lineWidth: 2 }, // 红色连接线配置
{ points: [], color: 'yellow', lineWidth: 2 } // 黄色连接线配置
]
}; };
}, },
created() { created() {
...@@ -208,12 +221,144 @@ export default { ...@@ -208,12 +221,144 @@ export default {
this.ctx.translate(0, this.canvas.height); // 向下移动画布高度 this.ctx.translate(0, this.canvas.height); // 向下移动画布高度
this.ctx.scale(1, -1); // 翻转 Y 轴方向(上为正) this.ctx.scale(1, -1); // 翻转 Y 轴方向(上为正)
// 加载背景图并绘制 // // 加载背景图并绘制
this.loadBackgroundImage(); // this.loadBackgroundImage();
// 加载所有图片并绘制 // 加载所有图片并绘制
this.loadAllImages(); this.loadAllImages();
}, },
// 绘制单个po.png(支持配置参数)
drawPoImage(config) {
this.ctx.save();
this.ctx.setTransform(1, 0, 0, 1, 0, 0);
// 动态计算y坐标(若未指定则默认画布底部-高度)
const y = config.y ? config.y : (this.canvas.height - config.height);
this.ctx.drawImage(
this.poImage,
config.x,
y,
config.width,
config.height
);
this.ctx.restore();
},
// 绘制单个guan.png(支持不同图片类型)
drawGuanImage(config) {
this.ctx.save();
this.ctx.setTransform(1, 0, 0, 1, 0, 0);
const targetImage = this[config.image]; // 根据配置获取具体图片对象(如guanImage/guanImage1)
this.ctx.drawImage(
targetImage,
config.x,
config.y,
config.width,
config.height
);
this.ctx.restore();
},
// 绘制连接线(支持多坐标点)
drawLine(config) {
this.ctx.save();
this.ctx.setTransform(1, 0, 0, 1, 0, 0);
this.ctx.strokeStyle = config.color;
this.ctx.lineWidth = config.lineWidth;
this.ctx.beginPath();
config.points.forEach((point, index) => {
index === 0 ? this.ctx.moveTo(point.x, point.y) : this.ctx.lineTo(point.x, point.y);
});
this.ctx.stroke();
this.ctx.restore();
},
// 绘制背景图(独立方法)
drawBackground() {
this.ctx.save();
this.ctx.setTransform(1, 0, 0, 1, 0, 0);
this.ctx.drawImage(
this.bgImage,
0,
0,
this.canvas.width,
this.canvas.height
);
this.ctx.restore();
},
// 绘制water.png(独立方法)
drawWaterImage() {
this.ctx.save();
this.ctx.setTransform(1, 0, 0, 1, 0, 0);
this.ctx.drawImage(
this.waterImage,
0,
this.canvas.height - 255,
485,
255
);
this.ctx.restore();
},
// 重构后的统一绘制入口(通过配置驱动)
drawAllImages() {
const canvasHeight = this.canvas.height;
// 1. 绘制背景图
this.drawBackground();
// 2. 绘制po.png(遍历配置数组)
this.poConfigs.forEach((config, index) => {
// 第二张po.png的y坐标需要基于第一张计算(顶部对齐)
if (index === 1) {
const prevPo = this.poConfigs[0];
config.y = (canvasHeight - prevPo.height) - config.height; // 第一张顶部位置 - 自身高度
}
this.drawPoImage(config);
});
// 3. 绘制guan.png(遍历配置数组)
this.guanConfigs.forEach((config, index) => {
const firstPo = this.poConfigs[0];
const secondPo = this.poConfigs[1];
// 第一张guan.png坐标计算(基于第一张po.png)
if (index === 0) {
config.x = firstPo.width - 150; // 879 - 150
config.y = canvasHeight - 135.5; // 原计算逻辑
}
// 第二张guan.png坐标计算(基于第二张po.png)
if (index === 1) {
config.x = secondPo.width - 150; // secondPoWidth - 150
config.y = secondPo.y + 30; // secondPoY + 30
}
this.drawGuanImage(config);
});
// 4. 绘制连接线(遍历配置数组)
this.lineConfigs.forEach((config, index) => {
const firstGuan = this.guanConfigs[0];
const secondGuan = this.guanConfigs[1];
// 红色连接线坐标(原逻辑)
if (index === 0) {
config.points = [
{ x: firstGuan.x, y: firstGuan.y + 100 },
{ x: secondGuan.x, y: secondGuan.y + 50 },
{ x: secondGuan.x - 100, y: secondGuan.y - 10 } // 扩展第三点
];
}
// 黄色连接线坐标(原逻辑)
if (index === 1) {
config.points = [
{ x: firstGuan.x, y: firstGuan.y + 80 }, // 调整偏移量
{ x: secondGuan.x, y: secondGuan.y + 30 }
];
}
this.drawLine(config);
});
// 5. 绘制water.png
this.drawWaterImage();
},
/** 加载所有图片并绘制 */ /** 加载所有图片并绘制 */
loadAllImages() { loadAllImages() {
// 加载背景图(原有) // 加载背景图(原有)
...@@ -231,12 +376,6 @@ export default { ...@@ -231,12 +376,6 @@ export default {
// 加载 guan.png // 加载 guan.png
this.guanImage = new Image(); this.guanImage = new Image();
this.guanImage.src = require("@/assets/images/jrx/guan0.png"); this.guanImage.src = require("@/assets/images/jrx/guan0.png");
// 加载 guan1.png
this.guanImage1 = new Image();
this.guanImage1.src = require("@/assets/images/jrx/guan1.png");
// 加载 guan2.png
this.guanImage2 = new Image();
this.guanImage2.src = require("@/assets/images/jrx/guan2.png");
// 等待所有图片加载完成 // 等待所有图片加载完成
Promise.all([ Promise.all([
...@@ -244,8 +383,6 @@ export default { ...@@ -244,8 +383,6 @@ export default {
new Promise((resolve) => (this.waterImage.onload = resolve)), new Promise((resolve) => (this.waterImage.onload = resolve)),
new Promise((resolve) => (this.poImage.onload = resolve)), new Promise((resolve) => (this.poImage.onload = resolve)),
new Promise((resolve) => (this.guanImage.onload = resolve)), new Promise((resolve) => (this.guanImage.onload = resolve)),
new Promise((resolve) => (this.guanImage1.onload = resolve)),
new Promise((resolve) => (this.guanImage2.onload = resolve)),
]) ])
.then(() => { .then(() => {
...@@ -267,164 +404,166 @@ export default { ...@@ -267,164 +404,166 @@ export default {
* 6.超过4个po,要动态变换画布高度。 * 6.超过4个po,要动态变换画布高度。
*/ */
drawAllImages() { // drawAllImages() {
// 1. 绘制背景图(原有逻辑) // const canvasWidth = this.canvas.width
this.ctx.save(); // 保存当前变换状态 // const canvasHeight = this.canvas.height
this.ctx.setTransform(1, 0, 0, 1, 0, 0); // 恢复默认变换(不翻转)
this.ctx.drawImage( // // 1. 绘制背景图(原有逻辑)
this.bgImage, // this.ctx.save(); // 保存当前变换状态
0, // this.ctx.setTransform(1, 0, 0, 1, 0, 0); // 恢复默认变换(不翻转)
0, // this.ctx.drawImage(
this.canvas.width, // this.bgImage,
this.canvas.height // 0,
); // 0,
this.ctx.restore(); // 恢复之前的变换 // this.canvas.width,
// this.canvas.height
// 3. 绘制 po.png(同样临时恢复默认坐标系) // );
this.ctx.save(); // this.ctx.restore(); // 恢复之前的变换
this.ctx.setTransform(1, 0, 0, 1, 0, 0);
this.ctx.drawImage( // // 3. 绘制 po.png(同样临时恢复默认坐标系)
this.poImage, // this.ctx.save();
0, // this.ctx.setTransform(1, 0, 0, 1, 0, 0);
this.canvas.height - 150, // Y坐标调整为画布高度 - 图片高度 // this.ctx.drawImage(
879, // this.poImage,
150 // 绘制尺寸(与原尺寸一致) // 0,
); // this.canvas.height - 150, // Y坐标调整为画布高度 - 图片高度
this.ctx.restore(); // 879,
// 150 // 绘制尺寸(与原尺寸一致)
// 新增:第二张po.png(在第一张上方叠加) // );
this.ctx.save(); // this.ctx.restore();
this.ctx.setTransform(1, 0, 0, 1, 0, 0);
const secondPoWidth = 879 - 250; // 宽度减少100px // // 新增:第二张po.png(在第一张上方叠加)
const secondPoHeight = 150; // 高度保持不变 // this.ctx.save();
const secondPoY = (this.canvas.height - 150) - secondPoHeight; // Y坐标:第一张顶部位置(原Y坐标 - 自身高度) // this.ctx.setTransform(1, 0, 0, 1, 0, 0);
this.ctx.drawImage( // const secondPoWidth = 879 - 250; // 宽度减少100px
this.poImage, // const secondPoHeight = 150; // 高度保持不变
0, // X轴保持0 // const secondPoY = (this.canvas.height - 150) - secondPoHeight; // Y坐标:第一张顶部位置(原Y坐标 - 自身高度)
secondPoY, // Y轴为第一张顶部位置 // this.ctx.drawImage(
secondPoWidth, // 新宽度 // this.poImage,
secondPoHeight // 保持高度 // 0, // X轴保持0
); // secondPoY, // Y轴为第一张顶部位置
this.ctx.restore(); // secondPoWidth, // 新宽度
// secondPoHeight // 保持高度
// );
// 3. 绘制 guan0.png(po.png 右侧中间,上层) // this.ctx.restore();
this.ctx.save();
this.ctx.setTransform(1, 0, 0, 1, 0, 0);
// 计算位置: // // 3. 绘制 guan0.png(po.png 右侧中间,上层)
// po.png 右侧 x 坐标 = po.png x + po.png 宽度 = 0 + 879 = 879 // this.ctx.save();
// po.png 垂直中间 y 坐标 = po.png y + po.png 高度/2 = (canvas.height - 150) + 75 = canvas.height - 75 // this.ctx.setTransform(1, 0, 0, 1, 0, 0);
// guan0.png 垂直居中需要 y = po.png中间y - guan0.png高度/2 = (canvas.height - 75) - (121/2) = canvas.height - 135.5 // // 计算位置:
const guanX = 879 - 150; // // po.png 右侧 x 坐标 = po.png x + po.png 宽度 = 0 + 879 = 879
const guanY = this.canvas.height - 135.5; // // po.png 垂直中间 y 坐标 = po.png y + po.png 高度/2 = (canvas.height - 150) + 75 = canvas.height - 75
this.ctx.drawImage( // // guan0.png 垂直居中需要 y = po.png中间y - guan0.png高度/2 = (canvas.height - 75) - (121/2) = canvas.height - 135.5
this.guanImage, // const guanX = 879 - 150;
guanX, // const guanY = this.canvas.height - 135.5;
guanY, // 目标位置(右侧中间) // this.ctx.drawImage(
6, // this.guanImage,
121 // 目标尺寸(宽6px,高121px) // guanX,
); // guanY, // 目标位置(右侧中间)
this.ctx.restore(); // 6,
// 121 // 目标尺寸(宽6px,高121px)
// );
/** // this.ctx.restore();
* canvas绘画原则。坐标轴从左上角开始画,y轴要从上往下找y轴的起始原点。
* canvasWidth:this.canvas.height // 画布的宽度(目前为600)
// /**
* poHeight:150px // 每个坡的高度 // * canvas绘画原则。坐标轴从左上角开始画,y轴要从上往下找y轴的起始原点。
// * canvasWidth:this.canvas.height // 画布的宽度(目前为600)
* guanPaddingTop:30px // 每个管孔距离对应层级坡顶部的距离
// * poHeight:150px // 每个坡的高度
drawImage:(imgsrc, 起始x,起始y,绘画宽度距离, 绘画高度距离)
*/ // * guanPaddingTop:30px // 每个管孔距离对应层级坡顶部的距离
// 新增:第二张guanImage(在第一张基础上叠加)
this.ctx.save(); // drawImage:(imgsrc, 起始x,起始y,绘画宽度距离, 绘画高度距离)
this.ctx.setTransform(1, 0, 0, 1, 0, 0); // */
const canvasHeight = this.canvas.height // // 新增:第二张guanImage(在第一张基础上叠加)
const secondGuanX = secondPoWidth - 150; // x轴:原宽度值(6px)-250px // this.ctx.save();
const secondGuanY = this.canvas.height - 135.5; // y轴:原高度值(121px) // this.ctx.setTransform(1, 0, 0, 1, 0, 0);
this.ctx.drawImage( // const secondGuanX = secondPoWidth - 150; // x轴:原宽度值(6px)-250px
this.guanImage, // const secondGuanY = this.canvas.height - 135.5; // y轴:原高度值(121px)
secondGuanX, // 新x坐标 // this.ctx.drawImage(
secondPoY + 30, // 新y坐标 // this.guanImage,
6, // 保持宽度6px // secondGuanX, // 新x坐标
200 // secondPoY/1.5 // 保持高度121px // secondPoY + 30, // 新y坐标
); // 6, // 保持宽度6px
console.log((secondPoY/2), '(secondPoY/2) ') // 200 // secondPoY/1.5 // 保持高度121px
// );
this.ctx.restore(); // console.log((secondPoY/2), '(secondPoY/2) ')
// this.ctx.restore();
// 新增:绘制红色连接线(关键修改)
this.ctx.save();
this.ctx.setTransform(1, 0, 0, 1, 0, 0); // 恢复默认坐标系(原点在左上角) // // 新增:绘制红色连接线(关键修改)
this.ctx.strokeStyle = "red"; // 设置线颜色为红色 // this.ctx.save();
this.ctx.lineWidth = 2; // 设置线宽 // this.ctx.setTransform(1, 0, 0, 1, 0, 0); // 恢复默认坐标系(原点在左上角)
this.ctx.beginPath(); // 开始路径 // this.ctx.strokeStyle = "red"; // 设置线颜色为红色
// 第一坐标点:第一个guanImage的x,y=guanY+30 // this.ctx.lineWidth = 2; // 设置线宽
this.ctx.moveTo(guanX, (guanY + 100)); // this.ctx.beginPath(); // 开始路径
// 第二坐标点:第二个guanImage的x,y=secondGuanY+30+150 // // 第一坐标点:第一个guanImage的x,y=guanY+30
this.ctx.lineTo(secondGuanX, secondGuanY+50); // this.ctx.moveTo(guanX, (guanY + 100));
// 新增:第三坐标点(示例坐标,需根据实际业务调整) // // 第二坐标点:第二个guanImage的x,y=secondGuanY+30+150
const thirdX = secondGuanX - 100; // 假设第三个点x坐标在第二个点基础上右移100px // this.ctx.lineTo(secondGuanX, secondGuanY+50);
const thirdY = secondGuanY - 10; // 假设第三个点y坐标在第二个点基础上下移80px(根据实际需求调整) // // 新增:第三坐标点(示例坐标,需根据实际业务调整)
this.ctx.lineTo(thirdX, thirdY); // const thirdX = secondGuanX - 100; // 假设第三个点x坐标在第二个点基础上右移100px
// const thirdY = secondGuanY - 10; // 假设第三个点y坐标在第二个点基础上下移80px(根据实际需求调整)
this.ctx.stroke(); // 描边绘制 // this.ctx.lineTo(thirdX, thirdY);
this.ctx.restore();
// this.ctx.stroke(); // 描边绘制
// 新增:绘制红色连接线(关键修改) // this.ctx.restore();
this.ctx.save();
this.ctx.setTransform(1, 0, 0, 1, 0, 0); // 恢复默认坐标系(原点在左上角) // // 新增:绘制红色连接线(关键修改)
this.ctx.strokeStyle = "yellow"; // 设置线颜色为红色 // this.ctx.save();
this.ctx.lineWidth = 2; // 设置线宽 // this.ctx.setTransform(1, 0, 0, 1, 0, 0); // 恢复默认坐标系(原点在左上角)
this.ctx.beginPath(); // 开始路径 // this.ctx.strokeStyle = "yellow"; // 设置线颜色为红色
// 第一坐标点:第一个guanImage的x,y=guanY+30 // this.ctx.lineWidth = 2; // 设置线宽
this.ctx.moveTo(guanX, (guanY + 100 - 20)); // this.ctx.beginPath(); // 开始路径
// 第二坐标点:第二个guanImage的x,y=secondGuanY+30+150 // // 第一坐标点:第一个guanImage的x,y=guanY+30
this.ctx.lineTo(secondGuanX, secondGuanY+50 -20); // this.ctx.moveTo(guanX, (guanY + 100 - 20));
this.ctx.stroke(); // 描边绘制 // // 第二坐标点:第二个guanImage的x,y=secondGuanY+30+150
this.ctx.restore(); // this.ctx.lineTo(secondGuanX, secondGuanY+50 -20);
// this.ctx.stroke(); // 描边绘制
// this.ctx.restore();
// 2. 绘制 water.png(临时恢复默认坐标系,避免翻转)
this.ctx.save(); // 保存当前变换状态
this.ctx.setTransform(1, 0, 0, 1, 0, 0); // 恢复默认变换(不翻转) // // 2. 绘制 water.png(临时恢复默认坐标系,避免翻转)
this.ctx.drawImage( // this.ctx.save(); // 保存当前变换状态
this.waterImage, // this.ctx.setTransform(1, 0, 0, 1, 0, 0); // 恢复默认变换(不翻转)
0, // this.ctx.drawImage(
this.canvas.height - 255, // Y坐标调整为画布高度 - 图片高度(原点在左下角) // this.waterImage,
485, // 0,
255 // 绘制尺寸(与原尺寸一致) // this.canvas.height - 255, // Y坐标调整为画布高度 - 图片高度(原点在左下角)
); // 485,
this.ctx.restore(); // 恢复之前的变换 // 255 // 绘制尺寸(与原尺寸一致)
}, // );
// this.ctx.restore(); // 恢复之前的变换
/** 加载背景图并绘制 */ // },
loadBackgroundImage() {
this.bgImage = new Image(); // /** 加载背景图并绘制 */
this.bgImage.src = require("@/assets/images/jrx/bg.png"); // 路径根据项目实际结构调整 // loadBackgroundImage() {
// this.bgImage = new Image();
// 图片加载完成后绘制 // this.bgImage.src = require("@/assets/images/jrx/bg.png"); // 路径根据项目实际结构调整
this.bgImage.onload = () => {
// 绘制背景图(注意:坐标系已变换,Y轴向上) // // 图片加载完成后绘制
// 原点在左下角,直接从 (0,0) 开始绘制,高度方向需适配翻转后的坐标系 // this.bgImage.onload = () => {
this.ctx.drawImage( // // 绘制背景图(注意:坐标系已变换,Y轴向上)
this.bgImage, // // 原点在左下角,直接从 (0,0) 开始绘制,高度方向需适配翻转后的坐标系
0, // this.ctx.drawImage(
0, // 图片在画布上的起始坐标(左下角原点) // this.bgImage,
this.canvas.width, // 绘制宽度 // 0,
this.canvas.height // 绘制高度 // 0, // 图片在画布上的起始坐标(左下角原点)
); // this.canvas.width, // 绘制宽度
}; // this.canvas.height // 绘制高度
// );
// 处理图片加载错误 // };
this.bgImage.onerror = () => {
console.error("背景图加载失败"); // // 处理图片加载错误
this.ctx.fillStyle = "#f0f0f0"; // this.bgImage.onerror = () => {
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); // console.error("背景图加载失败");
}; // this.ctx.fillStyle = "#f0f0f0";
}, // this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
// };
// },
/** 初始化图表(关键修改:调整图例位置) */ /** 初始化图表(关键修改:调整图例位置) */
initChart() { initChart() {
return; return;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment