图书馆综合管理系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

742 lines
24 KiB

7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
  1. <template>
  2. <div class="mark-handle">
  3. <div v-if="isBookShelf && currentMarkData && currentMarkData.shelfId !== undefined" class="mark-img">
  4. <canvas :id="'canvas' + currentMarkData.shelfId" :width="width" :height="height" />
  5. </div>
  6. <div v-else-if="!isBookShelf && currentMarkData && currentMarkData.id !== undefined" class="mark-img">
  7. <canvas :id="'canvas' + currentMarkData.id" :width="width" :height="height" />
  8. </div>
  9. <div class="mark-right">
  10. <ul v-if="!isBookShelf" class="mark-info">
  11. <li>
  12. <p>所属机构</p>
  13. <span>{{ user.fonds.fondsName }}</span>
  14. </li>
  15. <li>
  16. <p>所属楼层</p>
  17. <span>{{ currentMarkData && currentMarkData.floorName }}</span>
  18. </li>
  19. <li>
  20. <p>书架</p>
  21. <span>{{ currentMarkData && currentMarkData.booksheflCount }}</span>
  22. </li>
  23. <li><span :class="['row-state', currentMarkData && currentMarkData.signPoint ? 'end-state' : 'cancel-state' ]">{{ currentMarkData && currentMarkData.signPoint ? '已标注': '未标注' }}</span></li>
  24. </ul>
  25. <ul v-else class="mark-info">
  26. <li>
  27. <p>所属机构</p>
  28. <span>{{ user.fonds.fondsName }}</span>
  29. </li>
  30. <li>
  31. <p>所属楼层</p>
  32. <span>{{ currentMarkData && currentMarkData.floorName }}</span>
  33. </li>
  34. <li>
  35. <p>所属区域</p>
  36. <span>{{ currentMarkData && currentMarkData.regionName }}</span>
  37. </li>
  38. <li>
  39. <p>/双面</p>
  40. <span>{{ currentMarkData && currentMarkData.rowType === 1 ? '单面' :'双面' }}</span>
  41. </li>
  42. <li>
  43. <p>书架规格</p>
  44. <span>{{ currentMarkData && currentMarkData.shelfFloor+ ' X ' + currentMarkData.shelfShelf }}</span>
  45. </li>
  46. <li><span :class="['row-state', true ? 'end-state' : 'cancel-state' ]">{{ true ? '已标注': '未标注' }}</span></li>
  47. </ul>
  48. <div class="mark-button">
  49. <el-button type="primary" :disabled="!isDrawing" @click="clean"><i class="iconfont icon-shanchu" />清空</el-button>
  50. <el-button type="primary" :disabled="isDrawing" @click="drawPolygon"><i class="el-icon-edit" style="font-weight: bold; padding-right: 4px; font-size: 16px;" />标注</el-button>
  51. <el-button type="primary" :disabled="!isDrawing" @click="submitDraw"><i class="el-icon-folder-checked" style="font-weight: bold; padding-right: 4px; font-size: 16px;" />保存</el-button>
  52. </div>
  53. </div>
  54. <img id="expImg" :src="imageUrl">
  55. </div>
  56. </template>
  57. <script>
  58. import { saveLibraryRegionSignPoint } from '@/api/area/index'
  59. import { saveBookShelfSignPoint } from '@/api/shelf/index'
  60. import { fabric } from 'fabric'
  61. import { mapGetters } from 'vuex'
  62. export default {
  63. name: 'Mark',
  64. props: {
  65. currentMarkData: {
  66. type: Object,
  67. require: true,
  68. default: function() {
  69. return {}
  70. }
  71. },
  72. imageUrl: {
  73. type: String,
  74. default: ''
  75. },
  76. isBookShelf: {
  77. type: Boolean,
  78. default: false
  79. }
  80. },
  81. data() {
  82. return {
  83. bgImgFlag: true,
  84. bgImgSrc: this.imageUrl,
  85. width: 900,
  86. height: 600,
  87. canvas: {},
  88. mouseFrom: {},
  89. mouseTo: {},
  90. drawWidth: 2, // 笔触宽度
  91. drawingObject: null, // 当前绘制对象
  92. moveCount: 1, // 绘制移动计数器
  93. doDrawing: false, // 绘制状态
  94. // polygon 相关参数
  95. polygonMode: false,
  96. pointArray: [],
  97. lineArray: [],
  98. savePointsGroup: [],
  99. activeShape: false,
  100. activeLine: '',
  101. line: {},
  102. deleteIconURL: require('@/assets/images/closed.png'),
  103. drawinfo: null,
  104. isDrawing: false
  105. }
  106. },
  107. computed: {
  108. ...mapGetters([
  109. 'user',
  110. 'baseApi'
  111. ])
  112. },
  113. watch: {
  114. width() {
  115. this.canvas.setWidth(this.width)
  116. },
  117. height() {
  118. this.canvas.setHeight(this.height)
  119. },
  120. currentMarkData: {
  121. handler(newVal, oldVal) {
  122. // 检查 newVal 是否为 null 或 undefined
  123. if (!newVal) {
  124. console.log('newVal is null or undefined')
  125. return
  126. }
  127. // 提取公共逻辑
  128. const handleIdChange = (newId, oldId, idKey) => {
  129. if (newId !== oldId) {
  130. console.log('id has changed')
  131. console.log('handler')
  132. this.canvas.clear()
  133. this.canvas.dispose()
  134. this.drawinfo = newVal.signPoint ? JSON.parse(newVal.signPoint) : null
  135. this.$nextTick(() => {
  136. this.$refs.markRefs.initCanvas()
  137. })
  138. }
  139. }
  140. if (this.isBookShelf && oldVal && oldVal.shelfId !== undefined) {
  141. handleIdChange(newVal.shelfId, oldVal.shelfId, 'shelfId')
  142. } else if (!this.isBookShelf && oldVal && oldVal.id !== undefined) {
  143. handleIdChange(newVal.id, oldVal.id, 'id')
  144. }
  145. },
  146. deep: true
  147. },
  148. imageUrl(newVal, oldVal) {
  149. if (newVal !== oldVal) {
  150. console.log('imageUrl')
  151. }
  152. }
  153. },
  154. mounted() {
  155. // this.$nextTick(() => {
  156. // console.log('mounted')
  157. // this.drawinfo = this.currentMarkData && this.currentMarkData.signPoint ? JSON.parse(this.currentMarkData.signPoint) : null
  158. // this.initCanvas()
  159. // })
  160. },
  161. beforeDestroy() {
  162. if (this.canvas) {
  163. this.canvas.clear()
  164. this.canvas.dispose()
  165. }
  166. },
  167. methods: {
  168. initCanvas() {
  169. // 检查 currentMarkData 是否存在
  170. if (!this.currentMarkData) {
  171. console.error('currentMarkData is null or undefined')
  172. return
  173. }
  174. const canvasId = `canvas${this.isBookShelf ? this.currentMarkData.shelfId : this.currentMarkData.id}`
  175. // 初始化 fabric.js 画布
  176. this.canvas = new fabric.Canvas(canvasId, {
  177. skipTargetFind: false,
  178. selectable: false,
  179. selection: false
  180. })
  181. this.canvas.selectionColor = 'rgba(0,0,0,0.05)'
  182. this.canvas.on('mouse:down', this.mousedown)
  183. this.canvas.on('mouse:move', this.mousemove)
  184. this.canvas.on('object:moving', this.objectMoving)
  185. console.log('this.drawinfo', this.drawinfo)
  186. console.log('this.canvas', this.canvas)
  187. if (this.drawinfo) {
  188. console.log('444')
  189. this.loadDraw()
  190. } else {
  191. console.log('555')
  192. this.isDrawing = false
  193. this.bgImgFlag = true
  194. const imgElement = document.getElementById('expImg')
  195. imgElement.src = this.imageUrl
  196. this.loadExpImg()
  197. }
  198. },
  199. // 从已渲染的DOM元素加载图片至canvas
  200. loadExpImg() {
  201. console.log('loadExpImg')
  202. const imgElement = document.getElementById('expImg')
  203. const newWidth = this.canvas.width
  204. console.log('newWidth', newWidth)
  205. imgElement.onload = () => {
  206. // console.log('imgElement.src', imgElement.src)
  207. const newHeight = newWidth / (imgElement.width / imgElement.height)
  208. new fabric.Image.fromURL(
  209. imgElement.src,
  210. (img) => {
  211. img.set(
  212. {
  213. originX: 'center',
  214. originY: 'center',
  215. scaleX: newWidth / imgElement.width,
  216. scaleY: newHeight / imgElement.height
  217. },
  218. { crossOrigin: 'anonymous' }
  219. )
  220. img.on('scaling', (e) => {
  221. // 拉伸事件
  222. const h = img.scaleY
  223. const w = img.scaleX
  224. if (h !== w || w === h) {
  225. // 判断缩放值相等或不相等后执行图片等比缩放
  226. if (e.e.movementY === -1 || e.e.movementY === 1) {
  227. img.scale(h) // 缩放
  228. } else {
  229. img.scale(w)
  230. }
  231. }
  232. })
  233. img.setCoords()
  234. img.centeredScaling = true
  235. img.centerTransform = true
  236. this.canvas.add(img)
  237. this.canvas.centerObject(img)
  238. this.canvas.renderAll()
  239. },
  240. {
  241. selectable: true,
  242. hasControls: true,
  243. lockRotation: true, // 禁止旋转
  244. centeredScaling: true,
  245. zIndex: -99,
  246. isBgImg: true
  247. }
  248. )
  249. }
  250. },
  251. // 对象移动时的事件处理
  252. objectMoving(e) {
  253. const target = e.target
  254. if (target.type === 'polygon') {
  255. target.setCoords()
  256. // 更新params.pointInfo以确保点信息是最新的
  257. // const points = target.points.map(p => ({
  258. // x: p.x + target.left,
  259. // y: p.y + target.top
  260. // }));
  261. // const index = params.pointInfo.findIndex(info => info.pointInfo[0].x === target.points[0].x && info.pointInfo[0].y === target.points[0].y);
  262. // if (index !== -1) {
  263. // params.pointInfo[index] = { pointInfo: points };
  264. // } else {
  265. // params.pointInfo.push({ pointInfo: points });
  266. // }
  267. }
  268. },
  269. submitDraw() {
  270. const saveCanvasData = {
  271. pointInfo: [],
  272. imgInfo: ''
  273. // img: ''
  274. }
  275. this.canvas
  276. .toJSON(['isBgImg'])
  277. .objects.forEach((item) => {
  278. const element = {
  279. pointInfo: ''
  280. }
  281. if (item?.points) {
  282. element.pointInfo = item.points
  283. saveCanvasData.pointInfo.push(element)
  284. }
  285. if (item.isBgImg) {
  286. saveCanvasData.imgInfo = item
  287. // params.img = item.src
  288. delete saveCanvasData.imgInfo.src
  289. }
  290. })
  291. console.log('saveCanvasData', saveCanvasData)
  292. if (this.isBookShelf) {
  293. const params = {
  294. 'id': this.currentMarkData.shelfId,
  295. 'signPoint': JSON.stringify(saveCanvasData)
  296. }
  297. saveBookShelfSignPoint(params).then(res => {
  298. console.log(res)
  299. if (res) {
  300. this.$message({ message: '当前书架标注成功', type: 'success', offset: 8 })
  301. this.$emit('handleCloseDialog')
  302. }
  303. }).catch(err => {
  304. console.log(err)
  305. })
  306. } else {
  307. const params = {
  308. 'id': this.currentMarkData.id,
  309. 'signPoint': JSON.stringify(saveCanvasData)
  310. }
  311. saveLibraryRegionSignPoint(params).then(res => {
  312. if (res) {
  313. this.$message({ message: '当前区域标注成功', type: 'success', offset: 8 })
  314. this.$emit('handleCloseDialog')
  315. }
  316. }).catch(err => {
  317. console.log(err)
  318. })
  319. }
  320. },
  321. // 鼠标按下时触发
  322. mousedown(e) {
  323. if (e === undefined) return
  324. // 记录鼠标按下时的坐标
  325. const xy =
  326. e.pointer || this.transformMouse(e.e.offsetX, e.e.offsetY)
  327. this.mouseFrom.x = xy.x
  328. this.mouseFrom.y = xy.y
  329. this.doDrawing = true
  330. this.canvas.skipTargetFind = false
  331. try {
  332. console.log('this.pointArray', this.pointArray)
  333. // 判断是否闭合多边形,点击红点时闭合多边形
  334. if (this.pointArray.length > 1) {
  335. // e.target.id == this.pointArray[0].id 表示点击了初始红点
  336. if (e.target && e.target.id === this.pointArray[0].id) {
  337. this.generatePolygon()
  338. console.log('画完')
  339. this.isDrawing = true
  340. return
  341. } else {
  342. console.log('未画完')
  343. this.isDrawing = false
  344. }
  345. }
  346. // 未点击红点即闭合点则继续作画
  347. if (this.polygonMode) {
  348. console.log('作画')
  349. this.addPoint(e)
  350. }
  351. } catch (error) {
  352. console.log(error)
  353. }
  354. },
  355. // 鼠标松开执行
  356. mouseup(e) {
  357. if (e === undefined) return
  358. const xy =
  359. e.pointer || this.transformMouse(e.e.offsetX, e.e.offsetY)
  360. this.mouseTo.x = xy.x
  361. this.mouseTo.y = xy.y
  362. this.drawingObject = null
  363. this.moveCount = 1
  364. // 如果当前操作的是多边形,更新坐标
  365. if (this.activeShape && this.activeShape.type === 'polygon') {
  366. this.activeShape.setCoords()
  367. }
  368. },
  369. // 鼠标滚轮放大缩小
  370. mouse(e) {
  371. if (undefined === e) return
  372. let zoom = (e.e.deltaY > 0 ? -0.1 : 0.1) + this.canvas.getZoom()
  373. zoom = Math.max(0.8, zoom)
  374. // 最小为原来的1/10
  375. zoom = Math.min(3, zoom)
  376. // 最大是原来的3倍
  377. const zoomPoint = new fabric.Point(e.e.pageX, e.e.pageY)
  378. this.canvas.zoomToPoint(zoomPoint, zoom)
  379. },
  380. // 鼠标移动过程中已经完成了绘制
  381. mousemove(e) {
  382. if (e === undefined) return
  383. if (this.moveCount % 2 === 0 && !this.doDrawing) {
  384. // 减少绘制频率
  385. return
  386. }
  387. this.moveCount++
  388. const xy =
  389. e.pointer || this.transformMouse(e.e.offsetX, e.e.offsetY)
  390. this.mouseTo.x = xy.x
  391. this.mouseTo.y = xy.y
  392. if (this.activeLine && this.activeLine.class === 'line') {
  393. const pointer = this.canvas.getPointer(e.e)
  394. this.activeLine.set({
  395. x2: pointer.x,
  396. y2: pointer.y
  397. })
  398. const points = this.activeShape.get('points')
  399. points.push({
  400. x: pointer.x,
  401. y: pointer.y,
  402. zIndex: 1
  403. })
  404. this.activeShape.set({
  405. points: points
  406. })
  407. this.canvas.renderAll()
  408. }
  409. },
  410. // 从画布中删除当前选中的对象
  411. deleteObj() {
  412. const activeObjects = this.canvas.getActiveObjects()
  413. if (activeObjects.length > 0) {
  414. activeObjects.forEach((item) => {
  415. this.canvas.remove(item)
  416. })
  417. this.canvas.renderAll()
  418. }
  419. },
  420. // 转换鼠标坐标
  421. transformMouse(mouseX, mouseY) {
  422. return {
  423. x: mouseX,
  424. y: mouseY
  425. }
  426. },
  427. // 绘制多边形开始
  428. drawPolygon() {
  429. console.log(1111)
  430. if (this.bgImgFlag) {
  431. this.canvas.getObjects().forEach((obj) => {
  432. if (obj.isBgImg) {
  433. obj.hasControls = false
  434. obj.selectable = false
  435. obj.evented = false
  436. }
  437. })
  438. this.bgImgFlag = false
  439. this.canvas.renderAll()
  440. }
  441. this.polygonMode = true
  442. this.pointArray = [] // 顶点集合
  443. this.lineArray = [] // 线集合
  444. this.canvas.isDrawingMode = false
  445. },
  446. addPoint(e) {
  447. const random = Math.floor(Math.random() * 10000)
  448. const id = new Date().getTime() + random
  449. const circle = new fabric.Circle({
  450. radius: 5,
  451. fill: '#ffffff',
  452. stroke: '#333333',
  453. strokeWidth: 0.5,
  454. left: (e.pointer?.x || e.e.layerX) / this.canvas.getZoom(),
  455. top: (e.pointer?.y || e.e.layerY) / this.canvas.getZoom(),
  456. selectable: false,
  457. hasBorders: false,
  458. hasControls: false,
  459. originX: 'center',
  460. originY: 'center',
  461. id,
  462. objectCaching: false
  463. })
  464. if (this.pointArray.length === 0) {
  465. circle.set({ fill: 'rgba(196,43, 1, 1)' })
  466. }
  467. const points = [
  468. (e.pointer?.x || e.e.layerX) / this.canvas.getZoom(),
  469. (e.pointer?.y || e.e.layerY) / this.canvas.getZoom(),
  470. (e.pointer?.x || e.e.layerX) / this.canvas.getZoom(),
  471. (e.pointer?.y || e.e.layerY) / this.canvas.getZoom()
  472. ]
  473. const line = new fabric.Line(points, {
  474. strokeWidth: 2,
  475. fill: 'rgba(196,43, 1, 1)',
  476. stroke: 'rgba(196,43, 1, 1)',
  477. class: 'line',
  478. originX: 'center',
  479. originY: 'center',
  480. selectable: false,
  481. hasBorders: false,
  482. hasControls: false,
  483. evented: false,
  484. objectCaching: false
  485. })
  486. if (this.activeShape) {
  487. const pos = this.canvas.getPointer(e.e)
  488. const points = this.activeShape.get('points')
  489. points.push({ x: pos.x, y: pos.y })
  490. const polygon = new fabric.Polygon(points, {
  491. stroke: '#333333',
  492. strokeWidth: 1,
  493. fill: 'rgba(196,43, 1, 0.3)',
  494. opacity: 0.3,
  495. selectable: false,
  496. hasBorders: false,
  497. hasControls: false,
  498. evented: false,
  499. objectCaching: false
  500. })
  501. this.canvas.remove(this.activeShape)
  502. this.canvas.add(polygon)
  503. this.activeShape = polygon
  504. this.canvas.renderAll()
  505. } else {
  506. const polyPoint = [
  507. {
  508. x: (e.pointer?.x || e.e.layerX) / this.canvas.getZoom(),
  509. y: (e.pointer?.y || e.e.layerY) / this.canvas.getZoom()
  510. }
  511. ]
  512. const polygon = new fabric.Polygon(polyPoint, {
  513. stroke: '#333333',
  514. strokeWidth: 1,
  515. fill: '#cccccc',
  516. opacity: 0.3,
  517. selectable: false,
  518. hasBorders: false,
  519. hasControls: false,
  520. evented: false,
  521. objectCaching: false
  522. })
  523. this.activeShape = polygon
  524. this.canvas.add(polygon)
  525. }
  526. this.activeLine = line
  527. this.pointArray.push(circle)
  528. this.lineArray.push(line)
  529. this.canvas.add(line)
  530. this.canvas.add(circle)
  531. },
  532. generatePolygon() {
  533. const points = []
  534. this.pointArray.forEach((point) => {
  535. points.push({ x: point.left, y: point.top })
  536. this.canvas.remove(point)
  537. })
  538. this.lineArray.forEach((line) => {
  539. this.canvas.remove(line)
  540. })
  541. if (this.activeShape) {
  542. this.canvas.remove(this.activeShape)
  543. }
  544. if (this.activeLine) {
  545. this.canvas.remove(this.activeLine)
  546. }
  547. const polygon = new fabric.Polygon(points, {
  548. stroke: 'rgba(196,43, 1, 1)',
  549. strokeWidth: this.drawWidth,
  550. fill: 'rgba(196,43, 1, 0.3)',
  551. opacity: 1,
  552. selectable: false,
  553. hasBorders: false,
  554. hasControls: false,
  555. name: '测试架号name1'
  556. })
  557. let maxIndex = 0
  558. this.canvas._objects.forEach((obj) => {
  559. if (obj.index > maxIndex) maxIndex = obj.index
  560. })
  561. polygon.index = maxIndex + 1
  562. this.canvas.add(polygon)
  563. this.activeLine = null
  564. this.activeShape = null
  565. this.polygonMode = false
  566. this.doDrawing = false
  567. fabric.Image.fromURL(this.deleteIconURL, this.deletecallback)
  568. },
  569. // 从画布中删除当前选中的对象
  570. deleteObject() {
  571. const activeObject = this.canvas.getActiveObject()
  572. if (activeObject) {
  573. this.canvas._objects.forEach(item => {
  574. if (item.index === activeObject.index) {
  575. this.canvas.remove(item)
  576. }
  577. })
  578. const onlyBgImgItems = this.canvas._objects.filter(item => item.isBgImg)
  579. const allItemsAreBgImg = this.canvas._objects.length / 2 === onlyBgImgItems.length
  580. console.log('allItemsAreBgImg', allItemsAreBgImg)
  581. if (allItemsAreBgImg) {
  582. this.canvas.clear()
  583. this.bgImgFlag = true
  584. const imgElement = document.getElementById('expImg')
  585. imgElement.src = this.imageUrl
  586. this.isDrawing = false
  587. this.bgImgFlag = true
  588. this.loadExpImg()
  589. }
  590. this.canvas.remove(activeObject)
  591. this.canvas.renderAll()
  592. } else {
  593. console.log('this.canvas._objects.length', this.canvas._objects.length)
  594. }
  595. },
  596. // 渲染删除按钮
  597. async deletecallback(img) {
  598. const self = this
  599. let max = 0
  600. for (let i = 1; i < this.canvas._objects.length; i++) {
  601. if (this.canvas._objects[i].index > max) max = this.canvas._objects[i].index
  602. }
  603. img.index = max
  604. const oImg = await img.set({
  605. name: 'delete-btn',
  606. left: this.pointArray[0].left - 20,
  607. top: this.pointArray[0].top - 20,
  608. width: 40,
  609. height: 40,
  610. angle: 0
  611. }).scale(0.8)
  612. this.canvas.add(oImg).renderAll()
  613. this.canvas.setActiveObject(oImg)
  614. oImg.on('mousedown', function() {
  615. self.deleteObject()
  616. })
  617. },
  618. // 回显详情信息
  619. loadDraw() {
  620. const self = this
  621. if (this.currentMarkData.id === '') return
  622. const pointGroup = self.drawinfo.pointInfo
  623. const imgInfo = self.drawinfo.imgInfo
  624. imgInfo.src = self.imageUrl
  625. this.isDrawing = true
  626. // 加载底图
  627. fabric.util.enlivenObjects([imgInfo], objects => {
  628. objects.forEach(o => {
  629. o.selectable = false
  630. o.hasControls = false
  631. o.centeredScaling = false
  632. this.canvas.add(o)
  633. })
  634. // 处理多边形绘制回显操作
  635. pointGroup.forEach(async(item, index) => {
  636. if (item.pointInfo !== '') {
  637. const polygon = new fabric.Polygon(item.pointInfo, {
  638. name: item.name,
  639. stroke: 'rgba(196,43, 1, 1)',
  640. strokeWidth: self.drawWidth,
  641. fill: 'rgba(196,43, 1, 0.3)',
  642. opacity: 1,
  643. selectable: false,
  644. hasBorders: false,
  645. hasControls: false,
  646. originX: 'left', // 设置原点为左上角
  647. originY: 'top' // 设置原点为左上角
  648. })
  649. polygon.index = index
  650. self.canvas.add(polygon)
  651. self.activeLine = null
  652. self.activeShape = null
  653. self.polygonMode = false
  654. self.doDrawing = false
  655. polygon.on('mousedown', function(e) {
  656. console.log('Rect222' + (index + 1) + ' clicked', e)
  657. console.log('e.target.name222', e.target.name)
  658. })
  659. polygon.on('mouseover', function(e) {
  660. console.log('e22', e)
  661. console.log('e.target22', e.target)
  662. console.log('e.target.name22', e.target.name)
  663. // var delta = new fabric.Point(e.e.movementX, e.e.movementY)
  664. // if(e.target&&e.target.name){
  665. // // that.showDialog(e.target.name)
  666. // }
  667. this.set({ opacity: 0.3, hoverCursor: 'pointer' })
  668. this.canvas.renderAll()
  669. })
  670. // 监听鼠标移出事件
  671. polygon.on('mouseout', function() {
  672. this.set({ opacity: 1 })
  673. this.canvas.renderAll()
  674. })
  675. fabric.Image.fromURL(self.deleteIconURL, async img => {
  676. const _self = this
  677. img.index = index
  678. const oImg = await img.set({
  679. name: 'delete-btn',
  680. left: item.pointInfo[0].x - 20,
  681. top: item.pointInfo[0].y - 20,
  682. width: 40,
  683. height: 40,
  684. angle: 0
  685. }).scale(0.8)
  686. this.canvas.add(oImg)
  687. oImg.on('mousedown', function() {
  688. _self.deleteObject()
  689. })
  690. })
  691. }
  692. })
  693. })
  694. this.canvas.renderAll()
  695. },
  696. // 清除画布
  697. clean() {
  698. this.$confirm('确认清空标注吗?', '提示', {
  699. confirmButtonText: '确定',
  700. cancelButtonText: '取消',
  701. type: 'warning'
  702. }).then(() => {
  703. this.canvas.clear()
  704. this.isDrawing = false
  705. this.bgImgFlag = true
  706. const imgElement = document.getElementById('expImg')
  707. imgElement.src = this.imageUrl
  708. this.loadExpImg()
  709. }).catch(() => {
  710. console.log('取消清空标注')
  711. })
  712. }
  713. }
  714. }
  715. </script>
  716. <style lang="scss" scoped>
  717. #expImg{
  718. display: none;
  719. }
  720. </style>