index.vue 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. <template>
  2. <div class="editable-element-shape"
  3. :class="{ 'lock': elementInfo.lock }"
  4. :style="{
  5. top: elementInfo.top + 'px',
  6. left: elementInfo.left + 'px',
  7. width: elementInfo.width + 'px',
  8. transform: `rotate(${elementInfo.rotate}deg)`,
  9. }"
  10. @mousedown="$event => handleSelectElement($event)"
  11. >
  12. <div
  13. class="element-content"
  14. v-contextmenu="contextmenus"
  15. :style="{
  16. opacity: elementInfo.opacity,
  17. filter: shadowStyle ? `drop-shadow(${shadowStyle})` : '',
  18. }"
  19. >
  20. <SvgWrapper
  21. overflow="visible"
  22. :width="elementInfo.width"
  23. :height="elementInfo.height"
  24. >
  25. <g
  26. :transform="`scale(${elementInfo.width / elementInfo.viewBox}, ${elementInfo.height / elementInfo.viewBox}) translate(0,0) matrix(1,0,0,1,0,0)`"
  27. >
  28. <path
  29. vector-effect="non-scaling-stroke"
  30. stroke-linecap="butt"
  31. stroke-miterlimit="8"
  32. stroke-linejoin=""
  33. :d="elementInfo.path"
  34. :fill="elementInfo.fill"
  35. :stroke="outlineColor"
  36. :stroke-width="outlineWidth"
  37. :stroke-dasharray="outlineStyle === 'dashed' ? '10 5' : '0 0'"
  38. ></path>
  39. </g>
  40. </SvgWrapper>
  41. </div>
  42. </div>
  43. </template>
  44. <script lang="ts">
  45. import { computed, defineComponent, PropType } from 'vue'
  46. import { PPTShapeElement } from '@/types/slides'
  47. import { ContextmenuItem } from '@/components/Contextmenu/types'
  48. import useElementOutline from '@/views/components/element/hooks/useElementOutline'
  49. import useElementShadow from '@/views/components/element/hooks/useElementShadow'
  50. export default defineComponent({
  51. name: 'editable-element-shape',
  52. props: {
  53. elementInfo: {
  54. type: Object as PropType<PPTShapeElement>,
  55. required: true,
  56. },
  57. selectElement: {
  58. type: Function as PropType<(e: MouseEvent, element: PPTShapeElement, canMove?: boolean) => void>,
  59. required: true,
  60. },
  61. contextmenus: {
  62. type: Function as PropType<() => ContextmenuItem[]>,
  63. },
  64. },
  65. setup(props) {
  66. const handleSelectElement = (e: MouseEvent) => {
  67. if(props.elementInfo.lock) return
  68. e.stopPropagation()
  69. props.selectElement(e, props.elementInfo)
  70. }
  71. const outline = computed(() => props.elementInfo.outline)
  72. const { outlineWidth, outlineStyle, outlineColor } = useElementOutline(outline)
  73. const shadow = computed(() => props.elementInfo.shadow)
  74. const { shadowStyle } = useElementShadow(shadow)
  75. return {
  76. handleSelectElement,
  77. shadowStyle,
  78. outlineWidth,
  79. outlineStyle,
  80. outlineColor,
  81. }
  82. },
  83. })
  84. </script>
  85. <style lang="scss" scoped>
  86. .editable-element-shape {
  87. position: absolute;
  88. cursor: move;
  89. &.lock .element-content {
  90. cursor: default;
  91. }
  92. }
  93. .element-content {
  94. width: 100%;
  95. height: 100%;
  96. position: relative;
  97. svg {
  98. transform-origin: 0 0;
  99. overflow: visible;
  100. }
  101. }
  102. </style>