Jelajahi Sumber

目录结构调整

pipipi-pikachu 5 tahun lalu
induk
melakukan
e3f20147db

+ 1 - 52
src/App.vue

@@ -1,73 +1,32 @@
 <template>
   <Editor v-if="!screening" />
   <Screen v-else />
-
-  <div class="test">
-    <EditableTable 
-      :data="tableCells"
-      @change="data => updateTableCells(data)"
-    />
-  </div>
 </template>
 
 <script lang="ts">
-import { computed, defineComponent, onMounted, ref } from 'vue'
+import { computed, defineComponent, onMounted } from 'vue'
 import { useStore } from 'vuex'
 import { MutationTypes, ActionTypes, State } from '@/store'
-import { TableCell } from './types/slides'
 
 import Editor from './views/Editor/index.vue'
 import Screen from './views/Screen/index.vue'
-import EditableTable from '@/components/EditableTable.vue'
 
 export default defineComponent({
   name: 'app',
   components: {
     Editor,
     Screen,
-    EditableTable,
   },
   setup() {
     const store = useStore<State>()
     const screening = computed(() => store.state.screening)
 
-    const tableCells = ref<TableCell[][]>([
-      [
-        { id: '1', colspan: 1, rowspan: 1, text: '' },
-        { id: '2', colspan: 1, rowspan: 1, text: '' },
-        { id: '3', colspan: 1, rowspan: 1, text: '' },
-        { id: '4', colspan: 1, rowspan: 1, text: '' },
-        { id: '5', colspan: 1, rowspan: 1, text: '' },
-      ],
-      [
-        { id: '6', colspan: 1, rowspan: 1, text: '' },
-        { id: '7', colspan: 1, rowspan: 1, text: '' },
-        { id: '8', colspan: 1, rowspan: 1, text: '' },
-        { id: '9', colspan: 1, rowspan: 1, text: '' },
-        { id: '10', colspan: 1, rowspan: 1, text: '' },
-      ],
-      [
-        { id: '11', colspan: 1, rowspan: 1, text: '' },
-        { id: '12', colspan: 1, rowspan: 1, text: '' },
-        { id: '13', colspan: 1, rowspan: 1, text: '' },
-        { id: '14', colspan: 1, rowspan: 1, text: '' },
-        { id: '15', colspan: 1, rowspan: 1, text: '' },
-      ],
-    ])
-
-    const updateTableCells = (data: TableCell[][]) => {
-      console.log(data)
-      tableCells.value = data
-    }
-
     onMounted(() => {
       store.commit(MutationTypes.SET_AVAILABLE_FONTS)
       store.dispatch(ActionTypes.INIT_SNAPSHOT_DATABASE)
     })
 
     return {
-      tableCells,
-      updateTableCells,
       screening,
     }
   },
@@ -78,14 +37,4 @@ export default defineComponent({
 #app {
   height: 100%;
 }
-.test {
-  position: fixed;
-  top: 0;
-  bottom: 0;
-  left: 0;
-  right: 0;
-  background-color: #fff;
-  padding: 10px;
-  z-index: -1;
-}
 </style>

+ 31 - 2
src/mocks/index.ts

@@ -7,8 +7,8 @@ export const slides: Slide[] = [
       {
         id: 'sdasaxs',
         type: 'chart',
-        left: 600,
-        top: 100,
+        left: 680,
+        top: 20,
         width: 300,
         height: 300,
         chartType: 'line',
@@ -19,6 +19,35 @@ export const slides: Slide[] = [
           ],
         },
       },
+      {
+        id: '1213asa',
+        type: 'table',
+        left: 20,
+        top: 20,
+        width: 400,
+        height: 90,
+        colWidths: [0.25, 0.25, 0.25, 0.25],
+        data: [
+          [
+            { id: '1', colspan: 1, rowspan: 1, text: '' },
+            { id: '2', colspan: 1, rowspan: 1, text: '' },
+            { id: '3', colspan: 1, rowspan: 1, text: '' },
+            { id: '4', colspan: 1, rowspan: 1, text: '' },
+          ],
+          [
+            { id: '6', colspan: 1, rowspan: 1, text: '' },
+            { id: '7', colspan: 1, rowspan: 1, text: '' },
+            { id: '8', colspan: 1, rowspan: 1, text: '' },
+            { id: '9', colspan: 1, rowspan: 1, text: '' },
+          ],
+          [
+            { id: '11', colspan: 1, rowspan: 1, text: '' },
+            { id: '12', colspan: 1, rowspan: 1, text: '' },
+            { id: '13', colspan: 1, rowspan: 1, text: '' },
+            { id: '14', colspan: 1, rowspan: 1, text: '' },
+          ],
+        ],
+      },
     ],
   },
   {

+ 2 - 0
src/views/Editor/Canvas/EditableElement.vue

@@ -33,6 +33,7 @@ import TextElement from '@/views/components/element/TextElement/index.vue'
 import ShapeElement from '@/views/components/element/ShapeElement/index.vue'
 import LineElement from '@/views/components/element/LineElement/index.vue'
 import ChartElement from '@/views/components/element/ChartElement/index.vue'
+import TableElement from '@/views/components/element/TableElement/index.vue'
 
 export default defineComponent({
   name: 'editable-element',
@@ -62,6 +63,7 @@ export default defineComponent({
         [ElementTypes.SHAPE]: ShapeElement,
         [ElementTypes.LINE]: LineElement,
         [ElementTypes.CHART]: ChartElement,
+        [ElementTypes.TABLE]: TableElement,
       }
       return elementTypeMap[props.elementInfo.type] || null
     })

+ 76 - 0
src/views/Editor/Canvas/Operate/TableElementOperate.vue

@@ -0,0 +1,76 @@
+<template>
+  <div class="table-element-operate">
+    <BorderLine 
+      class="operate-border-line"
+      v-for="line in borderLines" 
+      :key="line.type" 
+      :type="line.type" 
+      :style="line.style"
+    />
+    <template v-if="!elementInfo.lock && (isActiveGroupElement || !isMultiSelect)">
+      <ResizeHandler
+        class="operate-resize-handler" 
+        v-for="point in textElementResizeHandlers"
+        :key="point.direction"
+        :type="point.direction"
+        :style="point.style"
+        @mousedown.stop="$event => scaleElement($event, elementInfo, point.direction)"
+      />
+    </template>
+  </div>
+</template>
+
+<script lang="ts">
+import { computed, defineComponent, PropType } from 'vue'
+import { useStore } from 'vuex'
+import { State } from '@/store'
+
+import { PPTTableElement } from '@/types/slides'
+import { OperateResizeHandler } from '@/types/edit'
+import useCommonOperate from '../hooks/useCommonOperate'
+
+import ResizeHandler from './ResizeHandler.vue'
+import BorderLine from './BorderLine.vue'
+
+export default defineComponent({
+  name: 'table-element-operate',
+  inheritAttrs: false,
+  components: {
+    ResizeHandler,
+    BorderLine,
+  },
+  props: {
+    elementInfo: {
+      type: Object as PropType<PPTTableElement>,
+      required: true,
+    },
+    isActiveGroupElement: {
+      type: Boolean,
+      required: true,
+    },
+    isMultiSelect: {
+      type: Boolean,
+      required: true,
+    },
+    scaleElement: {
+      type: Function as PropType<(e: MouseEvent, element: PPTTableElement, command: OperateResizeHandler) => void>,
+      required: true,
+    },
+  },
+  setup(props) {
+    const store = useStore<State>()
+    const canvasScale = computed(() => store.state.canvasScale)
+
+    const scaleWidth = computed(() => props.elementInfo.width * canvasScale.value)
+    const scaleHeight = computed(() => props.elementInfo.height * canvasScale.value)
+
+    const { textElementResizeHandlers, borderLines } = useCommonOperate(scaleWidth, scaleHeight)
+
+    return {
+      scaleWidth,
+      textElementResizeHandlers,
+      borderLines,
+    }
+  },
+})
+</script>

+ 2 - 0
src/views/Editor/Canvas/Operate/index.vue

@@ -41,6 +41,7 @@ import TextElementOperate from './TextElementOperate.vue'
 import ShapeElementOperate from './ShapeElementOperate.vue'
 import LineElementOperate from './LineElementOperate.vue'
 import ChartElementOperate from './ChartElementOperate.vue'
+import TableElementOperate from './TableElementOperate.vue'
 
 export default defineComponent({
   name: 'operate',
@@ -91,6 +92,7 @@ export default defineComponent({
         [ElementTypes.SHAPE]: ShapeElementOperate,
         [ElementTypes.LINE]: LineElementOperate,
         [ElementTypes.CHART]: ChartElementOperate,
+        [ElementTypes.TABLE]: TableElementOperate,
       }
       return elementTypeMap[props.elementInfo.type] || null
     })

src/components/Chart.vue → src/views/components/element/ChartElement/Chart.vue


+ 1 - 1
src/views/components/element/ChartElement/ScreenChartElement.vue

@@ -36,7 +36,7 @@ import { defineComponent, PropType } from 'vue'
 import { PPTChartElement } from '@/types/slides'
 
 import ElementOutline from '@/views/components/element/ElementOutline.vue'
-import Chart from '@/components/Chart.vue'
+import Chart from './Chart.vue'
 
 export default defineComponent({
   name: 'screen-element-chart',

+ 1 - 1
src/views/components/element/ChartElement/index.vue

@@ -40,7 +40,7 @@ import { PPTChartElement } from '@/types/slides'
 import { ContextmenuItem } from '@/components/Contextmenu/types'
 
 import ElementOutline from '@/views/components/element/ElementOutline.vue'
-import Chart from '@/components/Chart.vue'
+import Chart from './Chart.vue'
 
 export default defineComponent({
   name: 'editable-element-chart',

src/components/EditableDiv.vue → src/views/components/element/TableElement/EditableDiv.vue


+ 1 - 1
src/components/EditableTable.vue

@@ -56,8 +56,8 @@
 <script lang="ts">
 import { computed, defineComponent, nextTick, onMounted, onUnmounted, PropType, ref } from 'vue'
 import debounce from 'lodash/debounce'
-import { ContextmenuItem } from './Contextmenu/types'
 import { TableCell } from '@/types/slides'
+import { ContextmenuItem } from '@/components/Contextmenu/types'
 import { KEYS } from '@/configs/hotkey'
 import { createRandomCode } from '@/utils/common'
 

+ 84 - 0
src/views/components/element/TableElement/index.vue

@@ -0,0 +1,84 @@
+<template>
+  <div class="editable-element-shape"
+    :class="{ 'lock': elementInfo.lock }"
+    :style="{
+      top: elementInfo.top + 'px',
+      left: elementInfo.left + 'px',
+      width: elementInfo.width + 'px',
+    }"
+    @mousedown="$event => handleSelectElement($event)"
+  >
+    <div 
+      class="element-content" 
+      v-contextmenu="contextmenus"
+    >
+      <EditableTable 
+        :data="elementInfo.data"
+        :colWidths="elementInfo.colWidths"
+        @change="data => updateTableCells(data)"
+      />
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, PropType } from 'vue'
+import { PPTShapeElement, TableCell } from '@/types/slides'
+import { ContextmenuItem } from '@/components/Contextmenu/types'
+
+import EditableTable from './EditableTable.vue'
+
+export default defineComponent({
+  name: 'editable-element-shape',
+  components: {
+    EditableTable,
+  },
+  props: {
+    elementInfo: {
+      type: Object as PropType<PPTShapeElement>,
+      required: true,
+    },
+    selectElement: {
+      type: Function as PropType<(e: MouseEvent, element: PPTShapeElement, canMove?: boolean) => void>,
+      required: true,
+    },
+    contextmenus: {
+      type: Function as PropType<() => ContextmenuItem[]>,
+    },
+  },
+  setup(props) {
+    const handleSelectElement = (e: MouseEvent) => {
+      if(props.elementInfo.lock) return
+      e.stopPropagation()
+
+      props.selectElement(e, props.elementInfo)
+    }
+
+    const updateTableCells = (data: TableCell[][]) => {
+      console.log(data)
+    }
+
+    return {
+      handleSelectElement,
+      updateTableCells,
+    }
+  },
+})
+</script>
+
+<style lang="scss" scoped>
+.editable-element-shape {
+  position: absolute;
+  cursor: move;
+
+  &.lock .element-content {
+    cursor: default;
+  }
+}
+
+.element-content {
+  width: 100%;
+  height: 100%;
+  position: relative;
+}
+</style>