Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
V
V3-TailingPond
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
xinzhedeai
V3-TailingPond
Commits
8ec065fa
Commit
8ec065fa
authored
Jun 25, 2025
by
xinzhedeai
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add:canvas绘制方法封装rev1
parent
c3989c8e
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
307 additions
and
168 deletions
+307
-168
index.vue
src/views/dataMonitor/jrx/history/index.vue
+307
-168
No files found.
src/views/dataMonitor/jrx/history/index.vue
View file @
8ec065fa
...
...
@@ -156,6 +156,19 @@ export default {
bgImage
:
null
,
// 背景图对象
waterImage
:
null
,
// 新增:water.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
()
{
...
...
@@ -208,12 +221,144 @@ export default {
this
.
ctx
.
translate
(
0
,
this
.
canvas
.
height
);
// 向下移动画布高度
this
.
ctx
.
scale
(
1
,
-
1
);
// 翻转 Y 轴方向(上为正)
// 加载背景图并绘制
this
.
loadBackgroundImage
();
//
//
加载背景图并绘制
//
this.loadBackgroundImage();
// 加载所有图片并绘制
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
()
{
// 加载背景图(原有)
...
...
@@ -231,12 +376,6 @@ export default {
// 加载 guan.png
this
.
guanImage
=
new
Image
();
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
([
...
...
@@ -244,8 +383,6 @@ export default {
new
Promise
((
resolve
)
=>
(
this
.
waterImage
.
onload
=
resolve
)),
new
Promise
((
resolve
)
=>
(
this
.
poImage
.
onload
=
resolve
)),
new
Promise
((
resolve
)
=>
(
this
.
guanImage
.
onload
=
resolve
)),
new
Promise
((
resolve
)
=>
(
this
.
guanImage1
.
onload
=
resolve
)),
new
Promise
((
resolve
)
=>
(
this
.
guanImage2
.
onload
=
resolve
)),
])
.
then
(()
=>
{
...
...
@@ -267,164 +404,166 @@ export default {
* 6.超过4个po,要动态变换画布高度。
*/
drawAllImages
()
{
// 1. 绘制背景图(原有逻辑)
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
();
// 恢复之前的变换
// 3. 绘制 po.png(同样临时恢复默认坐标系)
this
.
ctx
.
save
();
this
.
ctx
.
setTransform
(
1
,
0
,
0
,
1
,
0
,
0
);
this
.
ctx
.
drawImage
(
this
.
poImage
,
0
,
this
.
canvas
.
height
-
150
,
// Y坐标调整为画布高度 - 图片高度
879
,
150
// 绘制尺寸(与原尺寸一致)
);
this
.
ctx
.
restore
();
// 新增:第二张po.png(在第一张上方叠加)
this
.
ctx
.
save
();
this
.
ctx
.
setTransform
(
1
,
0
,
0
,
1
,
0
,
0
);
const
secondPoWidth
=
879
-
250
;
// 宽度减少100px
const
secondPoHeight
=
150
;
// 高度保持不变
const
secondPoY
=
(
this
.
canvas
.
height
-
150
)
-
secondPoHeight
;
// Y坐标:第一张顶部位置(原Y坐标 - 自身高度)
this
.
ctx
.
drawImage
(
this
.
poImage
,
0
,
// X轴保持0
secondPoY
,
// Y轴为第一张顶部位置
secondPoWidth
,
// 新宽度
secondPoHeight
// 保持高度
);
this
.
ctx
.
restore
();
// 3. 绘制 guan0.png(po.png 右侧中间,上层)
this
.
ctx
.
save
();
this
.
ctx
.
setTransform
(
1
,
0
,
0
,
1
,
0
,
0
);
// 计算位置:
// po.png 右侧 x 坐标 = po.png x + po.png 宽度 = 0 + 879 = 879
// po.png 垂直中间 y 坐标 = po.png y + po.png 高度/2 = (canvas.height - 150) + 75 = canvas.height - 75
// guan0.png 垂直居中需要 y = po.png中间y - guan0.png高度/2 = (canvas.height - 75) - (121/2) = canvas.height - 135.5
const
guanX
=
879
-
150
;
const
guanY
=
this
.
canvas
.
height
-
135.5
;
this
.
ctx
.
drawImage
(
this
.
guanImage
,
guanX
,
guanY
,
// 目标位置(右侧中间)
6
,
121
// 目标尺寸(宽6px,高121px)
);
this
.
ctx
.
restore
();
/**
* canvas绘画原则。坐标轴从左上角开始画,y轴要从上往下找y轴的起始原点。
* canvasWidth:this.canvas.height // 画布的宽度(目前为600)
* poHeight:150px // 每个坡的高度
* guanPaddingTop:30px // 每个管孔距离对应层级坡顶部的距离
drawImage:(imgsrc, 起始x,起始y,绘画宽度距离, 绘画高度距离)
*/
// 新增:第二张guanImage(在第一张基础上叠加)
this
.
ctx
.
save
();
this
.
ctx
.
setTransform
(
1
,
0
,
0
,
1
,
0
,
0
);
const
canvasHeight
=
this
.
canvas
.
height
const
secondGuanX
=
secondPoWidth
-
150
;
// x轴:原宽度值(6px)-250px
const
secondGuanY
=
this
.
canvas
.
height
-
135.5
;
// y轴:原高度值(121px)
this
.
ctx
.
drawImage
(
this
.
guanImage
,
secondGuanX
,
// 新x坐标
secondPoY
+
30
,
// 新y坐标
6
,
// 保持宽度6px
200
// secondPoY/1.5 // 保持高度121px
);
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
.
lineWidth
=
2
;
// 设置线宽
this
.
ctx
.
beginPath
();
// 开始路径
// 第一坐标点:第一个guanImage的x,y=guanY+30
this
.
ctx
.
moveTo
(
guanX
,
(
guanY
+
100
));
// 第二坐标点:第二个guanImage的x,y=secondGuanY+30+150
this
.
ctx
.
lineTo
(
secondGuanX
,
secondGuanY
+
50
);
// 新增:第三坐标点(示例坐标,需根据实际业务调整)
const
thirdX
=
secondGuanX
-
100
;
// 假设第三个点x坐标在第二个点基础上右移100px
const
thirdY
=
secondGuanY
-
10
;
// 假设第三个点y坐标在第二个点基础上下移80px(根据实际需求调整)
this
.
ctx
.
lineTo
(
thirdX
,
thirdY
);
this
.
ctx
.
stroke
();
// 描边绘制
this
.
ctx
.
restore
();
// 新增:绘制红色连接线(关键修改)
this
.
ctx
.
save
();
this
.
ctx
.
setTransform
(
1
,
0
,
0
,
1
,
0
,
0
);
// 恢复默认坐标系(原点在左上角)
this
.
ctx
.
strokeStyle
=
"
yellow
"
;
// 设置线颜色为红色
this
.
ctx
.
lineWidth
=
2
;
// 设置线宽
this
.
ctx
.
beginPath
();
// 开始路径
// 第一坐标点:第一个guanImage的x,y=guanY+30
this
.
ctx
.
moveTo
(
guanX
,
(
guanY
+
100
-
20
));
// 第二坐标点:第二个guanImage的x,y=secondGuanY+30+150
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
);
// 恢复默认变换(不翻转)
this
.
ctx
.
drawImage
(
this
.
waterImage
,
0
,
this
.
canvas
.
height
-
255
,
// Y坐标调整为画布高度 - 图片高度(原点在左下角)
485
,
255
// 绘制尺寸(与原尺寸一致)
);
this
.
ctx
.
restore
();
// 恢复之前的变换
},
/** 加载背景图并绘制 */
loadBackgroundImage
()
{
this
.
bgImage
=
new
Image
();
this
.
bgImage
.
src
=
require
(
"
@/assets/images/jrx/bg.png
"
);
// 路径根据项目实际结构调整
// 图片加载完成后绘制
this
.
bgImage
.
onload
=
()
=>
{
// 绘制背景图(注意:坐标系已变换,Y轴向上)
// 原点在左下角,直接从 (0,0) 开始绘制,高度方向需适配翻转后的坐标系
this
.
ctx
.
drawImage
(
this
.
bgImage
,
0
,
0
,
// 图片在画布上的起始坐标(左下角原点)
this
.
canvas
.
width
,
// 绘制宽度
this
.
canvas
.
height
// 绘制高度
);
};
// 处理图片加载错误
this
.
bgImage
.
onerror
=
()
=>
{
console
.
error
(
"
背景图加载失败
"
);
this
.
ctx
.
fillStyle
=
"
#f0f0f0
"
;
this
.
ctx
.
fillRect
(
0
,
0
,
this
.
canvas
.
width
,
this
.
canvas
.
height
);
};
},
// drawAllImages() {
// const canvasWidth = this.canvas.width
// const canvasHeight = this.canvas.height
// // 1. 绘制背景图(原有逻辑)
// 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(); // 恢复之前的变换
// // 3. 绘制 po.png(同样临时恢复默认坐标系)
// this.ctx.save();
// this.ctx.setTransform(1, 0, 0, 1, 0, 0);
// this.ctx.drawImage(
// this.poImage,
// 0,
// this.canvas.height - 150, // Y坐标调整为画布高度 - 图片高度
// 879,
// 150 // 绘制尺寸(与原尺寸一致)
// );
// this.ctx.restore();
// // 新增:第二张po.png(在第一张上方叠加)
// this.ctx.save();
// this.ctx.setTransform(1, 0, 0, 1, 0, 0);
// const secondPoWidth = 879 - 250; // 宽度减少100px
// const secondPoHeight = 150; // 高度保持不变
// const secondPoY = (this.canvas.height - 150) - secondPoHeight; // Y坐标:第一张顶部位置(原Y坐标 - 自身高度)
// this.ctx.drawImage(
// this.poImage,
// 0, // X轴保持0
// secondPoY, // Y轴为第一张顶部位置
// secondPoWidth, // 新宽度
// secondPoHeight // 保持高度
// );
// this.ctx.restore();
// // 3. 绘制 guan0.png(po.png 右侧中间,上层)
// this.ctx.save();
// this.ctx.setTransform(1, 0, 0, 1, 0, 0);
// // 计算位置:
// // po.png 右侧 x 坐标 = po.png x + po.png 宽度 = 0 + 879 = 879
// // po.png 垂直中间 y 坐标 = po.png y + po.png 高度/2 = (canvas.height - 150) + 75 = canvas.height - 75
// // guan0.png 垂直居中需要 y = po.png中间y - guan0.png高度/2 = (canvas.height - 75) - (121/2) = canvas.height - 135.5
// const guanX = 879 - 150;
// const guanY = this.canvas.height - 135.5;
// this.ctx.drawImage(
// this.guanImage,
// guanX,
// guanY, // 目标位置(右侧中间)
// 6,
// 121 // 目标尺寸(宽6px,高121px)
// );
// this.ctx.restore();
// /**
// * canvas绘画原则。坐标轴从左上角开始画,y轴要从上往下找y轴的起始原点。
// * canvasWidth:this.canvas.height // 画布的宽度(目前为600)
// * poHeight:150px // 每个坡的高度
// * guanPaddingTop:30px // 每个管孔距离对应层级坡顶部的距离
// drawImage:(imgsrc, 起始x,起始y,绘画宽度距离, 绘画高度距离)
// */
// // 新增:第二张guanImage(在第一张基础上叠加)
// this.ctx.save();
// this.ctx.setTransform(1, 0, 0, 1, 0, 0);
// const secondGuanX = secondPoWidth - 150; // x轴:原宽度值(6px)-250px
// const secondGuanY = this.canvas.height - 135.5; // y轴:原高度值(121px)
// this.ctx.drawImage(
// this.guanImage,
// secondGuanX, // 新x坐标
// secondPoY + 30, // 新y坐标
// 6, // 保持宽度6px
// 200 // secondPoY/1.5 // 保持高度121px
// );
// 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.lineWidth = 2; // 设置线宽
// this.ctx.beginPath(); // 开始路径
// // 第一坐标点:第一个guanImage的x,y=guanY+30
// this.ctx.moveTo(guanX, (guanY + 100));
// // 第二坐标点:第二个guanImage的x,y=secondGuanY+30+150
// this.ctx.lineTo(secondGuanX, secondGuanY+50);
// // 新增:第三坐标点(示例坐标,需根据实际业务调整)
// const thirdX = secondGuanX - 100; // 假设第三个点x坐标在第二个点基础上右移100px
// const thirdY = secondGuanY - 10; // 假设第三个点y坐标在第二个点基础上下移80px(根据实际需求调整)
// this.ctx.lineTo(thirdX, thirdY);
// this.ctx.stroke(); // 描边绘制
// this.ctx.restore();
// // 新增:绘制红色连接线(关键修改)
// this.ctx.save();
// this.ctx.setTransform(1, 0, 0, 1, 0, 0); // 恢复默认坐标系(原点在左上角)
// this.ctx.strokeStyle = "yellow"; // 设置线颜色为红色
// this.ctx.lineWidth = 2; // 设置线宽
// this.ctx.beginPath(); // 开始路径
// // 第一坐标点:第一个guanImage的x,y=guanY+30
// this.ctx.moveTo(guanX, (guanY + 100 - 20));
// // 第二坐标点:第二个guanImage的x,y=secondGuanY+30+150
// 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); // 恢复默认变换(不翻转)
// this.ctx.drawImage(
// this.waterImage,
// 0,
// this.canvas.height - 255, // Y坐标调整为画布高度 - 图片高度(原点在左下角)
// 485,
// 255 // 绘制尺寸(与原尺寸一致)
// );
// this.ctx.restore(); // 恢复之前的变换
// },
// /** 加载背景图并绘制 */
// loadBackgroundImage() {
// this.bgImage = new Image();
// this.bgImage.src = require("@/assets/images/jrx/bg.png"); // 路径根据项目实际结构调整
// // 图片加载完成后绘制
// this.bgImage.onload = () => {
// // 绘制背景图(注意:坐标系已变换,Y轴向上)
// // 原点在左下角,直接从 (0,0) 开始绘制,高度方向需适配翻转后的坐标系
// this.ctx.drawImage(
// this.bgImage,
// 0,
// 0, // 图片在画布上的起始坐标(左下角原点)
// this.canvas.width, // 绘制宽度
// this.canvas.height // 绘制高度
// );
// };
// // 处理图片加载错误
// this.bgImage.onerror = () => {
// console.error("背景图加载失败");
// this.ctx.fillStyle = "#f0f0f0";
// this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
// };
// },
/** 初始化图表(关键修改:调整图例位置) */
initChart
()
{
return
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment