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.

117 lines
2.6 KiB

  1. <template>
  2. <v-rect
  3. :config="{
  4. id: rect.id,
  5. x: rect.x,
  6. y: rect.y,
  7. width: rect.width,
  8. height: rect.height,
  9. opacity: 0.6,
  10. stroke: strokeColor,
  11. fill: color,
  12. strokeWidth,
  13. draggable: true,
  14. dragBoundFunc
  15. }"
  16. @dragstart="onDragStart"
  17. @dragend="onDragEnd"
  18. @transformend="$emit('transformend', $event)"
  19. />
  20. </template>
  21. <script lang="ts">
  22. import Konva from 'konva'
  23. import type { PropType } from 'vue'
  24. import Vue from 'vue'
  25. import { inverseTransform, transform } from '@/domain/models/tasks/shared/Scaler'
  26. import Rectangle from '@/domain/models/tasks/boundingbox/Rectangle'
  27. export default Vue.extend({
  28. props: {
  29. rect: {
  30. type: Object as PropType<Rectangle>,
  31. required: true
  32. },
  33. color: {
  34. type: String,
  35. default: '#00FF00'
  36. },
  37. draggable: {
  38. type: Boolean,
  39. default: true
  40. },
  41. highlightId: {
  42. type: String,
  43. default: 'uuid'
  44. },
  45. opacity: {
  46. type: Number,
  47. default: 0.6
  48. },
  49. scale: {
  50. type: Number,
  51. required: true
  52. },
  53. maxWidth: {
  54. type: Number,
  55. required: true
  56. },
  57. maxHeight: {
  58. type: Number,
  59. required: true
  60. }
  61. },
  62. data() {
  63. return {
  64. stageX: 0,
  65. stageY: 0,
  66. originX: 0,
  67. originY: 0
  68. }
  69. },
  70. computed: {
  71. strokeColor() {
  72. return this.rect.id === this.highlightId ? '#ff0000' : `${this.color}CC`
  73. },
  74. strokeWidth() {
  75. return this.rect.id === this.highlightId ? 5 : 1
  76. }
  77. },
  78. methods: {
  79. dragBoundFunc(pos: { x: number; y: number }) {
  80. const [minX, minY, maxX, maxY] = this.rect.minMaxPoints()
  81. let x = transform(pos.x, this.stageX, this.scale)
  82. let y = transform(pos.y, this.stageY, this.scale)
  83. x -= this.originX
  84. y -= this.originY
  85. if (minY + y < 0) y = -minY
  86. if (minX + x < 0) x = -minX
  87. if (maxY + y > this.maxHeight) y = this.maxHeight - maxY
  88. if (maxX + x > this.maxWidth) x = this.maxWidth - maxX
  89. x += this.originX
  90. y += this.originY
  91. x = inverseTransform(x, this.stageX, this.scale)
  92. y = inverseTransform(y, this.stageY, this.scale)
  93. return { x, y }
  94. },
  95. onDragStart(e: Konva.KonvaEventObject<DragEvent>) {
  96. this.originX = e.target.attrs.x
  97. this.originY = e.target.attrs.y
  98. const { x = 0, y = 0 } = e.target.getStage()!.attrs
  99. this.stageX = x
  100. this.stageY = y
  101. },
  102. onDragEnd(e: Konva.KonvaEventObject<DragEvent>) {
  103. const { x, y } = e.target.attrs
  104. const newRect = this.rect.transform(x, y, this.rect.width, this.rect.height)
  105. this.$emit('dragend', newRect)
  106. }
  107. }
  108. })
  109. </script>