|
@@ -3,20 +3,24 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
<script>
|
|
|
-import Konva from 'konva'
|
|
|
|
|
|
|
+import Konva from "konva";
|
|
|
|
|
|
|
|
export default {
|
|
export default {
|
|
|
- name: 'KonvaExample',
|
|
|
|
|
|
|
+ name: "KonvaExample",
|
|
|
data() {
|
|
data() {
|
|
|
return {
|
|
return {
|
|
|
stage: null,
|
|
stage: null,
|
|
|
layer: null,
|
|
layer: null,
|
|
|
selectedStates: [], // 用于存储每个元素的选中状态
|
|
selectedStates: [], // 用于存储每个元素的选中状态
|
|
|
- selectedText: [] // 用于存储未选中的元素文本
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ selectedText: [], // 用于存储未选中的元素文本
|
|
|
|
|
+ rects:[],//白色rect合集
|
|
|
|
|
+ texts:[],//白色text合集
|
|
|
|
|
+ redrects:[],//红色rect合集
|
|
|
|
|
+ redtexts:[],//白色text合集
|
|
|
|
|
+ };
|
|
|
},
|
|
},
|
|
|
mounted() {
|
|
mounted() {
|
|
|
- this.initKonva()
|
|
|
|
|
|
|
+ this.initKonva();
|
|
|
},
|
|
},
|
|
|
methods: {
|
|
methods: {
|
|
|
initKonva() {
|
|
initKonva() {
|
|
@@ -32,7 +36,7 @@ export default {
|
|
|
|
|
|
|
|
// 创建底图
|
|
// 创建底图
|
|
|
const bgImage = new Image();
|
|
const bgImage = new Image();
|
|
|
- bgImage.src = require('@/assets/images/table.png');
|
|
|
|
|
|
|
+ bgImage.src = require("@/assets/images/table.png");
|
|
|
bgImage.onload = () => {
|
|
bgImage.onload = () => {
|
|
|
const knovaImage = new Konva.Image({
|
|
const knovaImage = new Konva.Image({
|
|
|
x: 330,
|
|
x: 330,
|
|
@@ -47,10 +51,10 @@ export default {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// 绘制无限网格
|
|
// 绘制无限网格
|
|
|
- this.drawGrid(50, 50, '#e0e0e0'); // 每个单元格50x50,浅灰色网格
|
|
|
|
|
|
|
+ this.drawGrid(50, 50, "#e0e0e0"); // 每个单元格50x50,浅灰色网格
|
|
|
|
|
|
|
|
// 渲染数据
|
|
// 渲染数据
|
|
|
- const imageSrc = require('@/assets/images/localSetIcon.jpg'); // 图片路径
|
|
|
|
|
|
|
+ const imageSrc = require("@/assets/images/localSetIcon.jpg"); // 图片路径
|
|
|
this.renderGrid(imageSrc, 6, 3, 450, 100, 120, 100, 50, 50, 60, 25);
|
|
this.renderGrid(imageSrc, 6, 3, 450, 100, 120, 100, 50, 50, 60, 25);
|
|
|
|
|
|
|
|
// 将图层添加到舞台
|
|
// 将图层添加到舞台
|
|
@@ -61,7 +65,7 @@ export default {
|
|
|
this.stage.draggable(false);
|
|
this.stage.draggable(false);
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
-// 绘制无限网格
|
|
|
|
|
|
|
+ // 绘制无限网格
|
|
|
drawGrid(cellWidth, cellHeight, gridColor) {
|
|
drawGrid(cellWidth, cellHeight, gridColor) {
|
|
|
const width = 1270;
|
|
const width = 1270;
|
|
|
const height = 830;
|
|
const height = 830;
|
|
@@ -89,7 +93,12 @@ export default {
|
|
|
this.layer.draw();
|
|
this.layer.draw();
|
|
|
},
|
|
},
|
|
|
renderGrid(imageSrc) {
|
|
renderGrid(imageSrc) {
|
|
|
- this.selectedStates = [];
|
|
|
|
|
|
|
+ this.selectedStates = {}; // 用对象来存储选中状态,键为文字内容
|
|
|
|
|
+ this.rects = {};
|
|
|
|
|
+ this.texts = {};
|
|
|
|
|
+ this.redrects = {};
|
|
|
|
|
+ this.redtexts = {};
|
|
|
|
|
+ this.selectedText = [];
|
|
|
|
|
|
|
|
const positions = [
|
|
const positions = [
|
|
|
{ row: 2, col: 9 }, // E-1
|
|
{ row: 2, col: 9 }, // E-1
|
|
@@ -97,24 +106,25 @@ export default {
|
|
|
{ row: 2, col: 13 }, // E-3
|
|
{ row: 2, col: 13 }, // E-3
|
|
|
{ row: 4, col: 9 }, // E-4
|
|
{ row: 4, col: 9 }, // E-4
|
|
|
{ row: 4, col: 11 }, // E-5
|
|
{ row: 4, col: 11 }, // E-5
|
|
|
- { row: 4, col: 13 }, // E-6
|
|
|
|
|
|
|
+ { row: 4, col: 13 }, // E-6
|
|
|
{ row: 6, col: 9 }, // E-7
|
|
{ row: 6, col: 9 }, // E-7
|
|
|
{ row: 6, col: 11 }, // E-8
|
|
{ row: 6, col: 11 }, // E-8
|
|
|
{ row: 6, col: 13 }, // E-9
|
|
{ row: 6, col: 13 }, // E-9
|
|
|
{ row: 8, col: 9 }, // E-10
|
|
{ row: 8, col: 9 }, // E-10
|
|
|
{ row: 8, col: 11 }, // E-11
|
|
{ row: 8, col: 11 }, // E-11
|
|
|
- { row: 8, col: 13 }, // E-12
|
|
|
|
|
|
|
+ { row: 8, col: 13 }, // E-12
|
|
|
{ row: 10, col: 9 }, // E-13
|
|
{ row: 10, col: 9 }, // E-13
|
|
|
{ row: 10, col: 11 }, // E-14
|
|
{ row: 10, col: 11 }, // E-14
|
|
|
{ row: 10, col: 13 }, // E-15
|
|
{ row: 10, col: 13 }, // E-15
|
|
|
{ row: 12, col: 9 }, // E-16
|
|
{ row: 12, col: 9 }, // E-16
|
|
|
{ row: 12, col: 11 }, // E-17
|
|
{ row: 12, col: 11 }, // E-17
|
|
|
- { row: 12, col: 13 }, // E-18
|
|
|
|
|
|
|
+ { row: 12, col: 13 }, // E-18
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
positions.forEach((pos, index) => {
|
|
positions.forEach((pos, index) => {
|
|
|
const x = pos.col * 50; // 每个单元格宽度为50
|
|
const x = pos.col * 50; // 每个单元格宽度为50
|
|
|
const y = pos.row * 50; // 每个单元格高度为50
|
|
const y = pos.row * 50; // 每个单元格高度为50
|
|
|
|
|
+ const labelText = `E-${index + 1}`; // 对应的文字
|
|
|
|
|
|
|
|
const point = new Image();
|
|
const point = new Image();
|
|
|
point.src = imageSrc;
|
|
point.src = imageSrc;
|
|
@@ -128,56 +138,126 @@ export default {
|
|
|
draggable: false,
|
|
draggable: false,
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- knovaImage.on('click', () => {
|
|
|
|
|
- this.selectedStates[index] = !this.selectedStates[index];
|
|
|
|
|
|
|
+ knovaImage.on("click", () => {
|
|
|
|
|
+ // 切换选中状态,基于文本内容
|
|
|
|
|
+ this.selectedStates[labelText] = !this.selectedStates[labelText];
|
|
|
|
|
+
|
|
|
|
|
+ // 判断当前是否选中
|
|
|
|
|
+ if (this.selectedStates[labelText]) {
|
|
|
|
|
+ // 选中状态
|
|
|
|
|
+ // 显示红色矩形和文字,隐藏普通矩形和文字
|
|
|
|
|
+ this.rects[labelText].visible(false);
|
|
|
|
|
+ this.texts[labelText].visible(false);
|
|
|
|
|
+ this.redrects[labelText].visible(true);
|
|
|
|
|
+ this.redtexts[labelText].visible(true);
|
|
|
|
|
+
|
|
|
|
|
+ // 切换图片为选中状态的图片
|
|
|
|
|
+ const selectedImage = new Image();
|
|
|
|
|
+ selectedImage.src = require('@/assets/images/localSetSelect.jpg'); // 选中的图片路径
|
|
|
|
|
+ selectedImage.onload = () => {
|
|
|
|
|
+ knovaImage.image(selectedImage); // 更新图像
|
|
|
|
|
+ this.layer.draw(); // 更新图层
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 将选中的 labelText 推入数组
|
|
|
|
|
+ this.selectedText.push({
|
|
|
|
|
+ label: labelText,
|
|
|
|
|
+ value: index + 1,
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
- if (this.selectedStates[index]) {
|
|
|
|
|
- point.src = require('@/assets/images/localSetSelect.jpg');
|
|
|
|
|
- this.selectedText.push({ label: `E-${index + 1}`, value: index + 1 });
|
|
|
|
|
} else {
|
|
} else {
|
|
|
- point.src = imageSrc;
|
|
|
|
|
- this.selectedText = this.selectedText.filter(item => item.value !== index + 1);
|
|
|
|
|
|
|
+ // 取消选中状态
|
|
|
|
|
+ // 显示普通矩形和文字,隐藏红色矩形和文字
|
|
|
|
|
+ this.rects[labelText].visible(true);
|
|
|
|
|
+ this.texts[labelText].visible(true);
|
|
|
|
|
+ this.redrects[labelText].visible(false);
|
|
|
|
|
+ this.redtexts[labelText].visible(false);
|
|
|
|
|
+
|
|
|
|
|
+ // 切换图片为未选中状态的图片
|
|
|
|
|
+ const normalImage = new Image();
|
|
|
|
|
+ normalImage.src = imageSrc; // 未选中的默认图片路径
|
|
|
|
|
+ normalImage.onload = () => {
|
|
|
|
|
+ knovaImage.image(normalImage); // 更新图像
|
|
|
|
|
+ this.layer.draw(); // 更新图层
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 从选中数组中移除该项
|
|
|
|
|
+ this.selectedText = this.selectedText.filter(
|
|
|
|
|
+ (item) => item.label !== labelText
|
|
|
|
|
+ );
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- knovaImage.image(point);
|
|
|
|
|
|
|
+ // 最后确保图层重新渲染
|
|
|
this.layer.draw();
|
|
this.layer.draw();
|
|
|
|
|
|
|
|
// 传递选中的元素文本到父组件
|
|
// 传递选中的元素文本到父组件
|
|
|
- this.$emit('selection-changed', this.selectedText);
|
|
|
|
|
|
|
+ this.$emit("selection-changed", this.selectedText);
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
this.layer.add(knovaImage);
|
|
this.layer.add(knovaImage);
|
|
|
|
|
|
|
|
|
|
+ // 普通矩形
|
|
|
const rect = new Konva.Rect({
|
|
const rect = new Konva.Rect({
|
|
|
x: x - 3,
|
|
x: x - 3,
|
|
|
y: y + 55,
|
|
y: y + 55,
|
|
|
width: 60,
|
|
width: 60,
|
|
|
height: 25,
|
|
height: 25,
|
|
|
cornerRadius: 10,
|
|
cornerRadius: 10,
|
|
|
- stroke: 'red',
|
|
|
|
|
|
|
+ stroke: "red",
|
|
|
strokeWidth: 2,
|
|
strokeWidth: 2,
|
|
|
- fill: 'white',
|
|
|
|
|
|
|
+ fill: "white",
|
|
|
});
|
|
});
|
|
|
this.layer.add(rect);
|
|
this.layer.add(rect);
|
|
|
|
|
+ this.rects[labelText] = rect; // 用文字作为键存储
|
|
|
|
|
|
|
|
|
|
+ // 普通文字
|
|
|
const text = new Konva.Text({
|
|
const text = new Konva.Text({
|
|
|
x: x + 12,
|
|
x: x + 12,
|
|
|
y: y + 60,
|
|
y: y + 60,
|
|
|
fontSize: 20,
|
|
fontSize: 20,
|
|
|
- text: `E-${index + 1}`,
|
|
|
|
|
- fontFamily: 'Calibri',
|
|
|
|
|
- fill: 'red',
|
|
|
|
|
|
|
+ text: labelText,
|
|
|
|
|
+ fontFamily: "Calibri",
|
|
|
|
|
+ fill: "red",
|
|
|
});
|
|
});
|
|
|
this.layer.add(text);
|
|
this.layer.add(text);
|
|
|
|
|
+ this.texts[labelText] = text; // 用文字作为键存储
|
|
|
|
|
+
|
|
|
|
|
+ // 红色矩形(初始隐藏)
|
|
|
|
|
+ const redrect = new Konva.Rect({
|
|
|
|
|
+ x: x - 3,
|
|
|
|
|
+ y: y + 55,
|
|
|
|
|
+ width: 60,
|
|
|
|
|
+ height: 25,
|
|
|
|
|
+ cornerRadius: 10,
|
|
|
|
|
+ stroke: "red",
|
|
|
|
|
+ strokeWidth: 2,
|
|
|
|
|
+ fill: "red",
|
|
|
|
|
+ visible: false,
|
|
|
|
|
+ });
|
|
|
|
|
+ this.layer.add(redrect);
|
|
|
|
|
+ this.redrects[labelText] = redrect; // 用文字作为键存储
|
|
|
|
|
+
|
|
|
|
|
+ // 红色文字(初始隐藏)
|
|
|
|
|
+ const redtext = new Konva.Text({
|
|
|
|
|
+ x: x + 12,
|
|
|
|
|
+ y: y + 60,
|
|
|
|
|
+ fontSize: 20,
|
|
|
|
|
+ text: labelText,
|
|
|
|
|
+ fontFamily: "Calibri",
|
|
|
|
|
+ fill: "white",
|
|
|
|
|
+ visible: false,
|
|
|
|
|
+ });
|
|
|
|
|
+ this.layer.add(redtext);
|
|
|
|
|
+ this.redtexts[labelText] = redtext; // 用文字作为键存储
|
|
|
|
|
|
|
|
this.layer.draw();
|
|
this.layer.draw();
|
|
|
};
|
|
};
|
|
|
});
|
|
});
|
|
|
},
|
|
},
|
|
|
- // methods结束
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
-}
|
|
|
|
|
|
|
+ // methods结束
|
|
|
|
|
+ },
|
|
|
|
|
+};
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
<style scoped lang="scss">
|