Quellcode durchsuchen

添加插入表格

pipipi-pikachu vor 5 Jahren
Ursprung
Commit
bfaf126fd8

+ 13 - 8
src/configs/element.ts

@@ -1,3 +1,5 @@
+import { PPTElementOutline } from '@/types/slides'
+
 const DEFAULT_COLOR = '#d14424'
 
 export const ELEMENT_TYPE = {
@@ -43,21 +45,24 @@ export const DEFAULT_CHART = {
   },
 }
 
+const tableOutline: PPTElementOutline = {
+  width: 2,
+  style: 'solid',
+  color: '#eeece1',
+}
 export const DEFAULT_TABLE = {
   left: 0,
   top: 0,
-  outline: {
-    width: 2,
-    style: 'solid',
+  outline: tableOutline,
+  theme: {
     color: DEFAULT_COLOR,
+    rowHeader: true,
+    rowFooter: false,
+    colHeader: false,
+    colFooter: false,
   },
 }
 
-export const DEFAULT_FORMULA = {
-  left: 0,
-  top: 0,
-}
-
 export const MIN_SIZE = {
   text: 20,
   image: 20,

+ 20 - 3
src/hooks/useCreateElement.ts

@@ -3,7 +3,7 @@ import { MutationTypes } from '@/store'
 import { createRandomCode } from '@/utils/common'
 import { getImageSize } from '@/utils/image'
 import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas'
-import { ChartType, PPTElement } from '@/types/slides'
+import { ChartType, PPTElement, TableCell } from '@/types/slides'
 import { ShapePoolItem } from '@/configs/shapes'
 import { LinePoolItem } from '@/configs/lines'
 import {
@@ -12,6 +12,7 @@ import {
   DEFAULT_SHAPE,
   DEFAULT_LINE,
   DEFAULT_CHART,
+  DEFAULT_TABLE,
 } from '@/configs/element'
 import useHistorySnapshot from '@/hooks/useHistorySnapshot'
 
@@ -75,8 +76,24 @@ export default () => {
     })
   }
   
-  const createTableElement = (rowCount: number, colCount: number) => {
-    console.log(rowCount, colCount)
+  const createTableElement = (row: number, col: number) => {
+    const rowCells: TableCell[] = new Array(col).fill({ id: createRandomCode(), colspan: 1, rowspan: 1, text: '' })
+    const data: TableCell[][] = new Array(row).fill(rowCells)
+
+    const DEFAULT_CELL_WIDTH = 100
+    const DEFAULT_CELL_HEIGHT = 40
+
+    const colWidths: number[] = new Array(col).fill(1 / col)
+
+    createElement({
+      ...DEFAULT_TABLE,
+      type: 'table',
+      id: createRandomCode(),
+      width: col * DEFAULT_CELL_WIDTH,
+      height: row * DEFAULT_CELL_HEIGHT,
+      colWidths,
+      data,
+    })
   }
   
   const createTextElement = (position: CommonElementPosition) => {

+ 163 - 0
src/views/Editor/CanvasTool/TableGenerator.vue

@@ -0,0 +1,163 @@
+<template>
+  <div class="table-generator">
+    <div class="title">
+      <div class="lef">插入表格 {{endCell.length ? `${endCell[0]} x ${endCell[1]}` : ''}}</div>
+      <div class="right" @click="isCustom = !isCustom">{{ isCustom ? '返回' : '自定义'}}</div>
+    </div>
+    <table 
+      @mouseleave="endCell = []" 
+      @click="handleClickTable()" 
+      v-if="!isCustom"
+    >
+      <tbody>
+        <tr v-for="row in 10" :key="row">
+          <td 
+            @mouseenter="endCell = [row, col]"
+            v-for="col in 10" :key="col"
+          >
+            <div 
+              class="cell" 
+              :class="{ 'active': endCell.length && row <= endCell[0] && col <= endCell[1] }"
+            ></div>
+          </td>
+        </tr>
+      </tbody>
+    </table>
+
+    <div class="custom" v-else>
+      <div class="row">
+        <div class="label" style="flex: 1;">行数:</div>
+        <InputNumber
+          :min="1"
+          :max="20"
+          v-model:value="customRow"
+          style="flex: 3;"
+        />
+      </div>
+      <div class="row">
+        <div class="label" style="flex: 1;">列数:</div>
+        <InputNumber
+          :min="1"
+          :max="20"
+          v-model:value="customCol"
+          style="flex: 3;"
+        />
+      </div>
+      <div class="btns">
+        <Button class="btn" @click="close()">取消</Button>
+        <Button class="btn" type="primary" @click="insertCustomTable()">确认</Button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, ref } from 'vue'
+
+import { message } from 'ant-design-vue'
+
+export default defineComponent({
+  name: 'table-generator',
+  setup(props, { emit }) {
+    const endCell = ref<number[]>([])
+    const customRow = ref(3)
+    const customCol = ref(3)
+    const isCustom = ref(false)
+
+    const handleClickTable = () => {
+      if(!endCell.value.length) return
+      const [row, col] = endCell.value
+      emit('insert', { row, col })
+    }
+
+    const insertCustomTable = () => {
+      if(customRow.value < 1 || customRow.value > 20) return message.warning('行数/列数必须在0~20之间!')
+      if(customCol.value < 1 || customCol.value > 20) return message.warning('行数/列数必须在0~20之间!')
+      emit('insert', { row: customRow.value, col: customCol.value })
+      isCustom.value = false
+    }
+
+    const close = () => {
+      emit('close')
+      isCustom.value = false
+    }
+
+    return {
+      endCell,
+      customRow,
+      customCol,
+      handleClickTable,
+      insertCustomTable,
+      isCustom,
+      close,
+    }
+  },
+})
+</script>
+
+<style lang="scss" scoped>
+.table-generator {
+  width: 100%;
+  margin-top: -12px;
+}
+.title {
+  height: 28px;
+  line-height: 28px;
+  background-color: #ededed;
+  margin: 0 -12px 12px -12px;
+  padding: 0 14px;
+  font-size: 12px;
+  display: flex;
+  justify-content: space-between;
+
+  .right {
+    cursor: pointer;
+
+    &:hover {
+      color: $themeColor;
+    }
+  }
+}
+table {
+  border-collapse: separate;
+}
+td {
+  width: 23px;
+  height: 23px;
+  line-height: 23px;
+  border: 2px solid #fff;
+  background-color: #f7f7f7;
+}
+.cell {
+  width: 100%;
+  height: 100%;
+  border: 1px solid #dcdcdc;
+
+  &.active {
+    background-color: rgba($color: $themeColor, $alpha: .1);
+    border-color: $themeColor;
+  }
+}
+
+.custom {
+  width: 230px;
+
+  .row {
+    display: flex;
+    align-items: center;
+
+    & + .row {
+      margin-top: 10px;
+    }
+  }
+}
+
+.btns {
+  margin-top: 10px;
+  text-align: right;
+
+  .btn {
+    margin-left: 10px;
+  }
+}
+</style>

+ 17 - 4
src/views/Editor/CanvasTool/index.vue

@@ -42,9 +42,17 @@
           <IconChartProportion class="handler-item" />
         </Tooltip>
       </Popover>
-      <Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="插入表格">
-        <IconInsertTable class="handler-item" />
-      </Tooltip>
+      <Popover trigger="click" v-model:visible="tableGeneratorVisible">
+        <template #content>
+          <TableGenerator
+            @close="tableGeneratorVisible = false"
+            @insert="({ row, col }) => { createTableElement(row, col); tableGeneratorVisible = false }"
+          />
+        </template>
+        <Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="插入表格">
+          <IconInsertTable class="handler-item" />
+        </Tooltip>
+      </Popover>
     </div>
 
     <div class="right-handler">
@@ -72,6 +80,7 @@ import useCreateElement from '@/hooks/useCreateElement'
 import ShapePool from './ShapePool.vue'
 import LinePool from './LinePool.vue'
 import ChartPool from './ChartPool.vue'
+import TableGenerator from './TableGenerator.vue'
 
 export default defineComponent({
   name: 'canvas-tool',
@@ -79,6 +88,7 @@ export default defineComponent({
     ShapePool,
     LinePool,
     ChartPool,
+    TableGenerator,
   },
   setup() {
     const store = useStore<State>()
@@ -91,7 +101,7 @@ export default defineComponent({
     const { scaleCanvas, setCanvasPercentage } = useScaleCanvas()
     const { redo, undo } = useHistorySnapshot()
 
-    const { createImageElement, createChartElement } = useCreateElement()
+    const { createImageElement, createChartElement, createTableElement } = useCreateElement()
 
     const insertImageElement = (files: File[]) => {
       const imageFile = files[0]
@@ -102,6 +112,7 @@ export default defineComponent({
     const shapePoolVisible = ref(false)
     const linePoolVisible = ref(false)
     const chartPoolVisible = ref(false)
+    const tableGeneratorVisible = ref(false)
 
     const drawText = () => {
       store.commit(MutationTypes.SET_CREATING_ELEMENT, {
@@ -136,10 +147,12 @@ export default defineComponent({
       shapePoolVisible,
       linePoolVisible,
       chartPoolVisible,
+      tableGeneratorVisible,
       drawText,
       drawShape,
       drawLine,
       createChartElement,
+      createTableElement,
     }
   },
 })