index.vue 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. <template>
  2. <div class="editable-element-frame"
  3. :style="{
  4. top: elementInfo.top + 'px',
  5. left: elementInfo.left + 'px',
  6. width: elementInfo.width + 'px',
  7. height: elementInfo.height + 'px',
  8. }"
  9. >
  10. <div
  11. class="rotate-wrapper"
  12. :style="{ transform: `rotate(${elementInfo.rotate}deg)` }"
  13. >
  14. <div
  15. class="element-content"
  16. v-contextmenu="contextmenus"
  17. @mousedown="$event => handleSelectElement($event)"
  18. @touchstart="$event => handleSelectElement($event)"
  19. >
  20. <iframe :srcdoc="elementInfo.url" v-if="elementInfo.isHTML"
  21. :width="elementInfo.width"
  22. :height="elementInfo.height"
  23. :frameborder="0"
  24. :allowfullscreen="true"></iframe>
  25. <iframe v-else
  26. :src="elementInfo.url"
  27. :width="elementInfo.width"
  28. :height="elementInfo.height"
  29. :frameborder="0"
  30. :allowfullscreen="true"
  31. ></iframe>
  32. <div class="drag-handler top"></div>
  33. <div class="drag-handler bottom"></div>
  34. <div class="drag-handler left"></div>
  35. <div class="drag-handler right"></div>
  36. <div class="mask"
  37. v-if="handleElementId !== elementInfo.id"
  38. @mousedown="$event => handleSelectElement($event, false)"
  39. @touchstart="$event => handleSelectElement($event, false)"
  40. ></div>
  41. </div>
  42. </div>
  43. </div>
  44. </template>
  45. <script lang="ts" setup>
  46. import type { PropType } from 'vue'
  47. import { storeToRefs } from 'pinia'
  48. import { useMainStore } from '@/store'
  49. import type { PPTFrameElement } from '@/types/slides'
  50. import type { ContextmenuItem } from '@/components/Contextmenu/types'
  51. const props = defineProps({
  52. elementInfo: {
  53. type: Object as PropType<PPTFrameElement>,
  54. required: true,
  55. },
  56. selectElement: {
  57. type: Function as PropType<(e: MouseEvent | TouchEvent, element: PPTFrameElement, canMove?: boolean) => void>,
  58. required: true,
  59. },
  60. contextmenus: {
  61. type: Function as PropType<() => ContextmenuItem[] | null>,
  62. required: true,
  63. },
  64. })
  65. const { handleElementId } = storeToRefs(useMainStore())
  66. const handleSelectElement = (e: MouseEvent | TouchEvent, canMove = true) => {
  67. e.stopPropagation()
  68. props.selectElement(e, props.elementInfo, canMove)
  69. }
  70. </script>
  71. <style lang="scss" scoped>
  72. .editable-element-frame {
  73. position: absolute;
  74. }
  75. .element-content {
  76. width: 100%;
  77. height: 100%;
  78. cursor: move;
  79. }
  80. .drag-handler {
  81. position: absolute;
  82. &.top {
  83. height: 20px;
  84. left: 0;
  85. right: 0;
  86. top: 0;
  87. }
  88. &.bottom {
  89. height: 20px;
  90. left: 0;
  91. right: 0;
  92. bottom: 0;
  93. }
  94. &.left {
  95. width: 20px;
  96. top: 0;
  97. bottom: 0;
  98. left: 0;
  99. }
  100. &.right {
  101. width: 20px;
  102. top: 0;
  103. bottom: 0;
  104. right: 0;
  105. }
  106. }
  107. .mask {
  108. position: absolute;
  109. top: 0;
  110. bottom: 0;
  111. left: 0;
  112. right: 0;
  113. }
  114. </style>