Kaynağa Gözat

主题相关界面

pipipi-pikachu 5 yıl önce
ebeveyn
işleme
a3e9146db0

+ 1 - 1
src/views/Editor/Toolbar/ElementStylePanel/ChartStylePanel/index.vue

@@ -160,7 +160,7 @@ export default defineComponent({
     const donut = ref(false)
 
     watch(handleElement, () => {
-      if(!handleElement.value) return
+      if(!handleElement.value || handleElement.value.type !== 'chart') return
       fill.value = handleElement.value.fill || '#000'
 
       if(handleElement.value.options) {

+ 1 - 1
src/views/Editor/Toolbar/ElementStylePanel/ImageStylePanel.vue

@@ -177,7 +177,7 @@ export default defineComponent({
     const filterOptions = ref<FilterOption[]>(JSON.parse(JSON.stringify(defaultFilters)))
 
     watch(handleElement, () => {
-      if(!handleElement.value) return
+      if(!handleElement.value || handleElement.value.type !== 'image') return
 
       if(handleElement.value.flip) {
         flip.value = {

+ 1 - 1
src/views/Editor/Toolbar/ElementStylePanel/ShapeStylePanel.vue

@@ -106,7 +106,7 @@ export default defineComponent({
     const fillType = ref('fill')
 
     watch(handleElement, () => {
-      if(!handleElement.value) return
+      if(!handleElement.value || handleElement.value.type !== 'shape') return
       fill.value = handleElement.value.fill || '#000'
 
       gradient.value = handleElement.value.gradient || { type: 'linear', rotate: 0, color: [fill.value, '#fff'] }

+ 5 - 3
src/views/Editor/Toolbar/ElementStylePanel/TableStylePanel.vue

@@ -228,7 +228,7 @@ export default defineComponent({
     const minColCount = ref(0)
 
     watch(handleElement, () => {
-      if(!handleElement.value) return
+      if(!handleElement.value || handleElement.value.type !== 'table') return
       
       theme.value = handleElement.value.theme
       hasTheme.value = !!theme.value
@@ -347,7 +347,8 @@ export default defineComponent({
       const value = +(e.target as HTMLInputElement).value
       const rowCount = handleElement.value.data.length
 
-      if(value <= rowCount) return message.warning('设置行数不能少于当前值')
+      if(value === rowCount) return
+      if(value < rowCount) return message.warning('设置行数不能少于当前值')
 
       const rowCells: TableCell[] = new Array(colCount.value).fill({ id: createRandomCode(), colspan: 1, rowspan: 1, text: '' })
       const newTableCells: TableCell[][] = new Array(value - rowCount).fill(rowCells)
@@ -364,7 +365,8 @@ export default defineComponent({
       const value = +(e.target as HTMLInputElement).value
       const colCount = handleElement.value.data[0].length
 
-      if(value <= colCount) return message.warning('设置列数不能少于当前值')
+      if(value === colCount) return
+      if(value < colCount) return message.warning('设置列数不能少于当前值')
 
       const tableCells = handleElement.value.data.map(item => {
         const cells: TableCell[] = new Array(value - colCount).fill({ id: createRandomCode(), colspan: 1, rowspan: 1, text: '' })

+ 2 - 1
src/views/Editor/Toolbar/ElementStylePanel/TextStylePanel.vue

@@ -227,7 +227,8 @@ export default defineComponent({
     const wordSpace = ref<number>()
 
     watch(handleElement, () => {
-      if(!handleElement.value) return
+      if(!handleElement.value || handleElement.value.type !== 'text') return
+
       fill.value = handleElement.value.fill || '#000'
       lineHeight.value = handleElement.value.lineHeight || 1.5
       wordSpace.value = handleElement.value.wordSpace || 0

+ 134 - 1
src/views/Editor/Toolbar/SlideStylePanel.vue

@@ -94,7 +94,72 @@
       </div>
     </div>
 
-    <div class="row"><Button style="flex: 1;" @click="applyAllSlide()">应用到全部</Button></div>
+    <div class="row"><Button style="flex: 1;" @click="applyAllSlide()">应用背景到全部</Button></div>
+
+    <Divider />
+
+    <div class="title">全局主题</div>
+    <div class="row">
+      <div style="flex: 2;">字体:</div>
+      <Select
+        style="flex: 3;"
+        value="微软雅黑"
+      >
+        <SelectOption v-for="font in availableFonts" :key="font.en" :value="font.en">
+          <span :style="{ fontFamily: font.en }">{{font.zh}}</span>
+        </SelectOption>
+      </Select>
+    </div>
+    <div class="row">
+      <div style="flex: 2;">字体颜色:</div>
+      <Popover trigger="click">
+        <template #content>
+          <ColorPicker
+            modelValue="#333"
+          />
+        </template>
+        <ColorButton color="#333" style="flex: 3;" />
+      </Popover>
+    </div>
+    <div class="row">
+      <div style="flex: 2;">背景颜色:</div>
+      <Popover trigger="click">
+        <template #content>
+          <ColorPicker
+            modelValue="#333"
+          />
+        </template>
+        <ColorButton color="#333" style="flex: 3;" />
+      </Popover>
+    </div>
+    <div class="row">
+      <div style="flex: 2;">主题色:</div>
+      <Popover trigger="click">
+        <template #content>
+          <ColorPicker
+            modelValue="#333"
+          />
+        </template>
+        <ColorButton color="#333" style="flex: 3;" />
+      </Popover>
+    </div>
+
+    <div class="title" style="margin-top: 20px;">预置主题:</div>
+    <div class="theme-list">
+      <div 
+        class="theme-item" 
+        v-for="(item, index) in themes" 
+        :key="index"
+        :style="{ backgroundColor: item.background }"
+      >
+        <div class="theme-item-content">
+          <div class="text" :style="{ color: item.text }">Aa</div>
+          <div class="color-block" :style="{ backgroundColor: item.color }"></div>
+        </div>
+      </div>
+    </div>
+
+    <div class="row"><Button style="flex: 1;" @click="applyAllSlide()">应用主题到全部</Button></div>
   </div>
 </template>
 
@@ -108,6 +173,37 @@ import useHistorySnapshot from '@/hooks/useHistorySnapshot'
 import ColorButton from './common/ColorButton.vue'
 import { getImageDataURL } from '@/utils/image'
 
+const themes = [
+  { color: '#42464b', background: '#fff', text: '#333' },
+  { color: '#5d82ba', background: '#fff', text: '#333' },
+  { color: '#005a6f', background: '#fff', text: '#333' },
+  { color: '#232d05', background: '#fff244', text: '#333' },
+  { color: '#d0614c', background: '#dfb044', text: '#333' },
+  { color: '#86a1ad', background: '#dfdbd4', text: '#333' },
+  { color: '#697586', background: '#d5c4a4', text: '#333' },
+  { color: '#333333', background: '#7acfa6', text: '#333' },
+  { color: '#42464b', background: '#415065', text: '#fff' },
+  { color: '#0c5999', background: '#35a2cd', text: '#fff' },
+  { color: '#c49a41', background: '#8c4357', text: '#fff' },
+  { color: '#dfaa00', background: '#2e4e7d', text: '#fff' },
+  { color: '#d1ad88', background: '#f99070', text: '#fff' },
+  { color: '#464d52', background: '#657984', text: '#fff' },
+  { color: '#ffcfb6', background: '#1e4c6f', text: '#fff' },
+  { color: '#c3a043', background: '#43292a', text: '#fff' },
+  { color: '#ffffff', background: '#171925', text: '#fff' },
+  { color: '#df9636', background: '#5b89a0', text: '#fff' },
+  { color: '#b898a4', background: '#93716b', text: '#fff' },
+  { color: '#c47a11', background: '#187db1', text: '#fff' },
+  { color: '#333333', background: '#759564', text: '#fff' },
+  { color: '#355b5e', background: '#424b50', text: '#fff' },
+  { color: '#d29090', background: '#942a32', text: '#fff' },
+  { color: '#00cfdf', background: '#3b434d', text: '#fff' },
+  { color: '#424246', background: '#c70042', text: '#fff' },
+  { color: '#2e4155', background: '#b35d44', text: '#fff' },
+  { color: '#11bfce', background: '#8f98aa', text: '#fff' },
+  { color: '#333333', background: '#549688', text: '#fff' },
+]
+
 export default defineComponent({
   name: 'slide-style-panel',
   components: {
@@ -117,6 +213,7 @@ export default defineComponent({
     const store = useStore<State>()
     const slides = computed(() => store.state.slides)
     const currentSlide = computed<Slide>(() => store.getters.currentSlide)
+    const availableFonts = computed(() => store.state.availableFonts)
 
     const background = computed(() => {
       if(!currentSlide.value.background) {
@@ -184,11 +281,13 @@ export default defineComponent({
     }
 
     return {
+      availableFonts,
       background,
       updateBackgroundType,
       updateBackground,
       uploadBackgroundImage,
       applyAllSlide,
+      themes,
     }
   },
 })
@@ -235,4 +334,38 @@ export default defineComponent({
     cursor: pointer;
   }
 }
+
+.theme-list {
+  @include grid-layout-wrapper();
+}
+.theme-item {
+  @include grid-layout-item(4, 22%);
+
+  padding-bottom: 22%;
+  border-radius: $borderRadius;
+  position: relative;
+  cursor: pointer;
+
+  .theme-item-content {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+  }
+
+  .text {
+    font-size: 16px;
+  }
+
+  .color-block {
+    width: 28px;
+    height: 10px;
+    margin-top: 5px;
+  }
+}
 </style>