| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- <template>
- <div class="mapdata">
- <div id="container" ref="container" style="width: 580px"></div>
- </div>
- </template>
- <script>
- import Konva from 'konva'
- import { selectLotoMapById, selectIsLotoStationById } from '@/api/mes/lotoStation/lotoStation'
- import { getTechnologyInfo } from '@/api/system/machinery'
- import { selectIsMapById } from '@/api/system/mapconfig'
- export default {
- name: 'KonvaExample',
- props: {
- machineryId: {
- type: String,
- default: ''
- }
- },
- data() {
- return {
- stage: null,
- layer: null,
- selectedStates: [], // 用于存储每个元素的选中状态
- selectedText: [], // 用于存储未选中的元素文本
- rects: [], // 白色r ect合集
- texts: [], // 白色text合集
- redrects: [], // 红色rect合集
- redtexts: [], // 白色text合集
- value: '',
- form: {}, //拿到单个数据
- orignData: null, //原始数据
- pointIdList: [], //选中的隔离点
- selectPoints: [], //回显之前选中的隔离点
- imageUrl: '',//获取底图
- width: '',//底图宽
- height: '',//底图高
- x: '',//底图横坐标
- y: '',//底图纵坐标
- pointList: null//接口给的所有点位数据
- }
- },
- watch: {
- machineryId: {
- handler(newValue) {
- if (newValue) {
- console.log(this.machineryId, 'Mapdata拿到的父组件machineryId')
- this.selectIsLotoStationById()
- }
- },
- immediate: true
- }
- },
- mounted() {
- this.$nextTick(() => {
- if (this.machineryId) {
- this.selectIsLotoStationById()
- const machineryId = this.machineryId
- console.log(machineryId, 'Mapdata拿到的父组件传递数据')
- }
- })
- },
- beforeDestroy() { // Vue 2
- this.imageUrl = ''
- this.pointList = null
- },
- methods: {
- selectIsLotoStationById() {
- const machineryId = this.machineryId
- getTechnologyInfo(machineryId).then((response) => {
- const lotoId = response.data.lotoId
- const sopId = ''
- const ticketId = ''
- selectIsLotoStationById(lotoId).then((response) => {
- console.log(response, '电柜信息')
- this.form = response.data
- // 获取不同底图 如地图或者柜子
- selectIsMapById(response.data.mapId).then((response) => {
- console.log(response, '获取底图')
- this.imageUrl = response.data.imageUrl
- this.width = response.data.width
- this.height = response.data.height
- this.x = response.data.x
- this.y = response.data.y
- this.pointList = response.data.pointList
- this.initKonva()
- })
- })
- // selectLotoMapById(lotoId, sopId, ticketId).then((response) => {
- // console.log(response, '电柜预览接口调用')
- // this.form.map = response.data
- //
- // if (response.data) {
- // try {
- // this.value = JSON.stringify(response.data, null, 4)
- // this.orignData = this.value
- // } catch (err) {
- // }
- // }
- // this.initKonva()
- // })
- })
- // 设备工艺详情
- getTechnologyInfo(this.machineryId).then((response) => {
- console.log(response, '设备/工艺详情')
- this.selectPoints = response.data.pointIdList
- })
- },
- initKonva() {
- // 创建舞台
- this.stage = new Konva.Stage({
- container: this.$refs.container, // 容器元素
- width: 580,
- height: 400
- })
- // 创建底图图层
- this.bgLayer = new Konva.Layer()
- // 创建底图
- const bgImage = new Image()
- // bgImage.src = require("@/assets/images/table.png");
- bgImage.src = this.imageUrl
- if (this.width > 1000) {
- bgImage.onload = () => {
- const knovaImage = new Konva.Image({
- x: this.x,
- y: this.y,
- image: bgImage,
- width: this.width / 2.1,
- height: this.height / 2,
- draggable: false
- })
- this.bgLayer.add(knovaImage)
- this.bgLayer.draw() // 绘制底图图层
- }
- } else {
- bgImage.onload = () => {
- const knovaImage = new Konva.Image({
- x: this.x - 220,
- y: this.y,
- image: bgImage,
- width: this.width / 2,
- height: this.height / 2,
- draggable: false
- })
- this.bgLayer.add(knovaImage)
- this.bgLayer.draw() // 绘制底图图层
- }
- }
- // 将底图图层添加到舞台
- this.stage.add(this.bgLayer)
- // 创建点位图层
- this.layer = new Konva.Layer()
- // 将点位图层添加到舞台
- this.stage.add(this.layer)
- // 禁止舞台拖拽
- this.stage.draggable(false)
- // 渲染数据
- const imageSrc = require('@/assets/images/localSetIcon.jpg') // 图片路径
- this.renderGrid(imageSrc, 6, 3, 450, 100, 120, 100, 50, 50, 60, 25)
- },
- renderGrid(imageSrc) {
- this.selectedStates = [] // 用数组存储选中状态
- this.rects = {}
- this.texts = {}
- this.bgrects = {}
- this.redrects = {}
- this.redtexts = {}
- this.selectedText = []
- this.pointIdList = [] // 初始化选中的点ID列表
- // const positions = JSON.parse(this.value); // 获取点位数据
- const positions = this.pointList
- console.log(positions, 'positions')
- // **计算柜子的布局范围**
- const cabinetWidth = this.stage.width() // 柜子的宽度
- const cabinetHeight = this.stage.height() // 柜子的高度
- const rows = Math.max(...positions.map((p) => p.x)) + 1 // 根据数据动态计算总行数
- const cols = Math.max(...positions.map((p) => p.y)) + 1 // 根据数据动态计算总列数
- // 调整横向和纵向间距
- let horizontalSpacingFactor
- let verticalSpacingFactor
- if (this.width > 1000) {
- horizontalSpacingFactor = 0.4 // 横向间距放大倍数
- verticalSpacingFactor = 0.4 // 纵向间距缩小倍数
- } else {
- horizontalSpacingFactor = 0.75 // 横向间距放大倍数
- verticalSpacingFactor = 0.53 // 纵向间距缩小倍数
- }
- const cellWidth = (cabinetWidth / rows) * horizontalSpacingFactor // 调整横向间距
- const cellHeight = (cabinetHeight / cols) * verticalSpacingFactor // 调整纵向间距
- // 遍历点位,按行列布局计算位置
- positions.forEach((pos) => {
- const col = pos.y // 当前点位的列
- const row = pos.x // 当前点位的行
- // 计算点位的实际位置,确保它们位于柜子显示区域内
- let x
- let y
- if (this.width > 1000) {
- // 计算柜子的布局范围
- x = row * 2 * 12
- y = col * 2 * 12
- console.log(pos.x, pos.y, x, y, '我打印了')
- } else {
- x = row * 2.4 * 12-104
- y = col * 2 * 12 + 8
- // x = row * cellWidth - 105; //这里之前是间距比较大的时候使用
- // y = col * cellHeight + 12;
- }
- const labelText = pos.entityName // 对应的文字
- const point = new Image()
- point.src = pos.pointIcon
- point.onload = () => {
- const knovaImage = new Konva.Image({
- x: x + 6, // 适当的偏移确保点位不重叠
- y: y + 6, // 适当的偏移确保点位不重叠
- image: point,
- width: 19,
- height: 18,
- draggable: false
- })
- // **绘制背景矩形**(以单元格大小为基础)
- const bgrect = new Konva.Rect({
- x: x,
- y: y,
- width: 30,
- height: 36,
- cornerRadius: 5,
- stroke: 'white',
- strokeWidth: 2,
- fill: 'white'
- })
- this.layer.add(bgrect)
- this.bgrects[labelText] = bgrect
- // **普通矩形边框**(同样按照单元格尺寸)
- const rect = new Konva.Rect({
- x: x + 4,
- y: y + 4,
- width: 30 - 8,
- height: 36 - 8,
- cornerRadius: 5,
- stroke: 'red',
- strokeWidth: 2,
- fill: 'white'
- })
- this.layer.add(rect)
- this.rects[labelText] = rect
- // 添加图片
- this.layer.add(knovaImage)
- // **绘制点位的文字**(确保与背景矩形不重叠)
- const text = new Konva.Text({
- x: x + 8, // 适当的偏移,确保文字不与背景矩形重叠
- y: y + 43 - 20, // 文字放在底部
- fontSize: 8,
- text: labelText,
- fontFamily: 'Calibri',
- fill: 'red'
- })
- this.layer.add(text)
- this.texts[labelText] = text
- // **选中覆盖矩形**(保持与背景矩形相同的尺寸)
- const redrect = new Konva.Rect({
- x: x,
- y: y,
- width: 30,
- height: 36,
- cornerRadius: 5,
- fill: 'rgba(97, 97, 97, 0.5)', // 半透明灰色
- visible: false, // 初始状态隐藏
- listening: false
- })
- this.layer.add(redrect)
- this.redrects[labelText] = redrect
- // **对号文字(表示选中)**
- const redtext = new Konva.Text({
- x: x + 30 / 2 - 5, // 水平居中
- y: y + 36 / 2 - 5, // 垂直居中
- fontSize: 13,
- text: '✔',
- fontFamily: 'Arial',
- fill: 'white',
- align: 'center',
- visible: false, // 初始隐藏状态
- listening: false
- })
- this.layer.add(redtext)
- this.redtexts[labelText] = redtext
- // 如果初始化时有选中的点位
- if (
- Array.isArray(this.selectPoints) &&
- this.selectPoints.length > 0
- ) {
- if (this.selectPoints.includes(pos.entityId)) {
- // 设置选中状态
- this.redrects[labelText].visible(true)
- this.redtexts[labelText].visible(true)
- this.pointIdList.push(pos.entityId) // 添加ID
- }
- }
- this.layer.draw() // 刷新画布
- }
- })
- }
- }
- }
- </script>
- <style scoped lang="scss">
- #container {
- width: 100%;
- height: 100%;
- }
- .mapdata {
- width: 100%;
- height: 100%;
- display: flex;
- }
- .left {
- flex: 1;
- display: flex;
- flex-direction: column;
- }
- </style>
|