LatexStylePanel.vue 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. <template>
  2. <div class="latex-style-panel">
  3. <div class="row">
  4. <Button style="flex: 1;" @click="latexEditorVisible = true">编辑 LaTeX</Button>
  5. </div>
  6. <Divider />
  7. <div class="row">
  8. <div style="width: 40%;">颜色:</div>
  9. <Popover trigger="click" style="width: 60%;">
  10. <template #content>
  11. <ColorPicker
  12. :modelValue="handleLatexElement.color"
  13. @update:modelValue="value => updateLatex({ color: value })"
  14. />
  15. </template>
  16. <ColorButton :color="handleLatexElement.color" />
  17. </Popover>
  18. </div>
  19. <div class="row">
  20. <div style="width: 40%;">粗细:</div>
  21. <NumberInput
  22. :min="1"
  23. :max="3"
  24. :value="handleLatexElement.strokeWidth"
  25. @update:value="value => updateLatex({ strokeWidth: value })"
  26. style="width: 60%;"
  27. />
  28. </div>
  29. <Modal
  30. v-model:visible="latexEditorVisible"
  31. :width="880"
  32. >
  33. <LaTeXEditor
  34. :value="handleLatexElement.latex"
  35. @close="latexEditorVisible = false"
  36. @update="data => { updateLatexData(data); latexEditorVisible = false }"
  37. />
  38. </Modal>
  39. </div>
  40. </template>
  41. <script lang="ts" setup>
  42. import { onUnmounted, ref, type Ref } from 'vue'
  43. import { storeToRefs } from 'pinia'
  44. import { useMainStore, useSlidesStore } from '@/store'
  45. import type { PPTLatexElement } from '@/types/slides'
  46. import emitter, { EmitterEvents } from '@/utils/emitter'
  47. import useHistorySnapshot from '@/hooks/useHistorySnapshot'
  48. import ColorButton from '@/components/ColorButton.vue'
  49. import LaTeXEditor from '@/components/LaTeXEditor/index.vue'
  50. import ColorPicker from '@/components/ColorPicker/index.vue'
  51. import Modal from '@/components/Modal.vue'
  52. import Divider from '@/components/Divider.vue'
  53. import Button from '@/components/Button.vue'
  54. import NumberInput from '@/components/NumberInput.vue'
  55. import Popover from '@/components/Popover.vue'
  56. const slidesStore = useSlidesStore()
  57. const { handleElement } = storeToRefs(useMainStore())
  58. const handleLatexElement = handleElement as Ref<PPTLatexElement>
  59. const latexEditorVisible = ref(false)
  60. const { addHistorySnapshot } = useHistorySnapshot()
  61. const updateLatex = (props: Partial<PPTLatexElement>) => {
  62. if (!handleElement.value) return
  63. slidesStore.updateElement({ id: handleElement.value.id, props })
  64. addHistorySnapshot()
  65. }
  66. const updateLatexData = (data: { path: string; latex: string; w: number; h: number; }) => {
  67. updateLatex({
  68. path: data.path,
  69. latex: data.latex,
  70. width: data.w,
  71. height: data.h,
  72. viewBox: [data.w, data.h],
  73. })
  74. }
  75. const openLatexEditor = () => latexEditorVisible.value = true
  76. emitter.on(EmitterEvents.OPEN_LATEX_EDITOR, openLatexEditor)
  77. onUnmounted(() => {
  78. emitter.off(EmitterEvents.OPEN_LATEX_EDITOR, openLatexEditor)
  79. })
  80. </script>
  81. <style lang="scss" scoped>
  82. .row {
  83. width: 100%;
  84. display: flex;
  85. align-items: center;
  86. margin-bottom: 10px;
  87. }
  88. </style>