BaseTextElement.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <template>
  2. <div
  3. class="base-element-text"
  4. :style="{
  5. top: elementInfo.top + 'px',
  6. left: elementInfo.left + 'px',
  7. width: elementInfo.width + 'px',
  8. height: elementInfo.height + 'px',
  9. }"
  10. >
  11. <div
  12. class="rotate-wrapper"
  13. :style="{ transform: `rotate(${elementInfo.rotate}deg)` }"
  14. >
  15. <div
  16. class="element-content"
  17. :style="{
  18. width: elementInfo.vertical ? 'auto' : elementInfo.width + 'px',
  19. height: elementInfo.vertical ? elementInfo.height + 'px' : elementInfo.height + 'px',
  20. backgroundColor: elementInfo.fill,
  21. opacity: elementInfo.opacity,
  22. textShadow: shadowStyle,
  23. lineHeight: elementInfo.lineHeight,
  24. letterSpacing: (elementInfo.wordSpace || 0) + 'px',
  25. color: elementInfo.defaultColor,
  26. fontFamily: elementInfo.defaultFontName,
  27. writingMode: elementInfo.vertical ? 'vertical-rl' : 'horizontal-tb',
  28. display: 'flex',
  29. alignItems: 'center',
  30. overflow: hidden,
  31. }"
  32. >
  33. <div class="shape-text" :style="elementInfo.style" :class="[elementInfo.align, { 'editable': editable || elementInfo.content }]">
  34. <ElementOutline
  35. :width="elementInfo.width"
  36. :height="elementInfo.height"
  37. :outline="elementInfo.outline"
  38. />
  39. <div
  40. class="text ProseMirror-static"
  41. :class="{ 'thumbnail': target === 'thumbnail' }"
  42. :style="{
  43. '--paragraphSpace': `${elementInfo.paragraphSpace === undefined ? 5 : elementInfo.paragraphSpace}px`,
  44. }"
  45. v-html="elementInfo.content"
  46. ></div>
  47. </div>
  48. </div>
  49. </div>
  50. </div>
  51. </template>
  52. <script lang="ts" setup>
  53. import { computed } from 'vue'
  54. import type { PPTTextElement } from '@/types/slides'
  55. import ElementOutline from '@/views/components/element/ElementOutline.vue'
  56. import useElementShadow from '@/views/components/element/hooks/useElementShadow'
  57. const props = defineProps<{
  58. elementInfo: PPTTextElement
  59. target?: string
  60. }>()
  61. const shadow = computed(() => props.elementInfo.shadow)
  62. const { shadowStyle } = useElementShadow(shadow)
  63. </script>
  64. <style lang="scss" scoped>
  65. .base-element-text {
  66. position: absolute;
  67. }
  68. .rotate-wrapper {
  69. width: 100%;
  70. height: 100%;
  71. }
  72. .element-content {
  73. position: relative;
  74. padding: 10px;
  75. line-height: 1.15;
  76. word-break: break-word;
  77. .text {
  78. position: relative;
  79. &.thumbnail {
  80. pointer-events: none;
  81. }
  82. }
  83. }
  84. .shape-text {
  85. width:100%;
  86. height:100%;
  87. position: absolute;
  88. top: 0;
  89. bottom: 0;
  90. left: 0;
  91. right: 0;
  92. display: flex;
  93. flex-direction: column;
  94. word-break: break-word;
  95. pointer-events: none;
  96. &.editable {
  97. pointer-events: all;
  98. }
  99. &.top {
  100. justify-content: space-around;
  101. }
  102. &.middle {
  103. justify-content: center;
  104. left: 50%;
  105. top: 50%;
  106. -webkit-transform: translate(-50%,-50%);
  107. transform: translate(-50%,-50%);
  108. }
  109. &.bottom {
  110. justify-content: flex-end;
  111. }
  112. }
  113. </style>