Преглед на файлове

添加主题相关数据字段

pipipi-pikachu преди 5 години
родител
ревизия
90d878e9a3
променени са 6 файла, в които са добавени 92 реда и са изтрити 45 реда
  1. 30 0
      src/configs/theme.ts
  2. 1 0
      src/store/constants.ts
  3. 8 1
      src/store/index.ts
  4. 5 1
      src/store/mutations.ts
  5. 7 0
      src/types/slides.ts
  6. 41 43
      src/views/Editor/Toolbar/SlideStylePanel.vue

+ 30 - 0
src/configs/theme.ts

@@ -0,0 +1,30 @@
+export const PRESET_THEMES = [
+  { color: '#42464b', background: '#ffffff', text: '#333' },
+  { color: '#5d82ba', background: '#ffffff', text: '#333' },
+  { color: '#005a6f', background: '#ffffff', 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' },
+]

+ 1 - 0
src/store/constants.ts

@@ -15,6 +15,7 @@ export enum MutationTypes {
   SET_CLIPING_IMAGE_ELEMENT_ID = 'setClipingImageElementId',
 
   // slides
+  SET_THEME = 'setTheme',
   SET_SLIDES = 'setSlides',
   ADD_SLIDE = 'addSlide',
   UPDATE_SLIDE = 'updateSlide',

+ 8 - 1
src/store/index.ts

@@ -4,7 +4,7 @@ import { actions } from './actions'
 import { mutations } from './mutations'
 import { MutationTypes, ActionTypes } from './constants'
 
-import { Slide } from '@/types/slides'
+import { Slide, SlideTheme } from '@/types/slides'
 import { CreatingElement } from '@/types/edit'
 import { ToolbarState } from '@/types/toolbar'
 import { slides } from '@/mocks/index'
@@ -24,6 +24,7 @@ export interface State {
   creatingElement: CreatingElement | null;
   availableFonts: FontName[];
   toolbarState: ToolbarState;
+  theme: SlideTheme;
   slides: Slide[];
   slideIndex: number;
   snapshotCursor: number;
@@ -46,6 +47,12 @@ const state: State = {
   creatingElement: null,
   availableFonts: [],
   toolbarState: 'slideStyle',
+  theme: {
+    themeColor: '#d14424',
+    fontColor: '#333',
+    fontName: '微软雅黑',
+    backgroundColor: '#fff',
+  },
   slides: slides,
   slideIndex: 0,
   snapshotCursor: -1,

+ 5 - 1
src/store/mutations.ts

@@ -2,7 +2,7 @@ import { MutationTree } from 'vuex'
 import omit from 'lodash/omit'
 import { MutationTypes } from './constants'
 import { State } from './index'
-import { Slide, PPTElement } from '@/types/slides'
+import { Slide, PPTElement, SlideTheme } from '@/types/slides'
 import { CreatingElement } from '@/types/edit'
 import { FONT_NAMES } from '@/configs/fontName'
 import { isSupportFontFamily } from '@/utils/fontFamily'
@@ -74,6 +74,10 @@ export const mutations: MutationTree<State> = {
 
   // slides
 
+  [MutationTypes.SET_THEME](state, themeProps: Partial<SlideTheme>) {
+    state.theme = { ...state.theme, ...themeProps }
+  },
+
   [MutationTypes.SET_SLIDES](state, slides: Slide[]) {
     state.slides = slides
   },

+ 7 - 0
src/types/slides.ts

@@ -200,4 +200,11 @@ export interface Slide {
   background?: SlideBackground;
   animations?: PPTAnimation[];
   turningMode?: 'no' | 'fade' | 'slideX' | 'slideY';
+}
+
+export interface SlideTheme {
+  backgroundColor: string;
+  themeColor: string;
+  fontColor: string;
+  fontName: string;
 }

+ 41 - 43
src/views/Editor/Toolbar/SlideStylePanel.vue

@@ -94,7 +94,7 @@
       </div>
     </div>
 
-    <div class="row"><Button style="flex: 1;" @click="applyAllSlide()">应用背景到全部</Button></div>
+    <div class="row"><Button style="flex: 1;" @click="applyBackgroundAllSlide()">应用背景到全部</Button></div>
 
     <Divider />
 
@@ -103,7 +103,8 @@
       <div style="flex: 2;">字体:</div>
       <Select
         style="flex: 3;"
-        value="微软雅黑"
+        :value="theme.fontName"
+        @change="value => updateTheme({ fontName: value })"
       >
         <SelectOption v-for="font in availableFonts" :key="font.en" :value="font.en">
           <span :style="{ fontFamily: font.en }">{{font.zh}}</span>
@@ -115,10 +116,11 @@
       <Popover trigger="click">
         <template #content>
           <ColorPicker
-            modelValue="#333"
+            :modelValue="theme.fontColor"
+            @update:modelValue="value => updateTheme({ fontColor: value })"
           />
         </template>
-        <ColorButton color="#333" style="flex: 3;" />
+        <ColorButton :color="theme.fontColor" style="flex: 3;" />
       </Popover>
     </div>
     <div class="row">
@@ -126,10 +128,11 @@
       <Popover trigger="click">
         <template #content>
           <ColorPicker
-            modelValue="#333"
+            :modelValue="theme.backgroundColor"
+            @update:modelValue="value => updateTheme({ backgroundColor: value })"
           />
         </template>
-        <ColorButton color="#333" style="flex: 3;" />
+        <ColorButton :color="theme.backgroundColor" style="flex: 3;" />
       </Popover>
     </div>
     <div class="row">
@@ -137,20 +140,26 @@
       <Popover trigger="click">
         <template #content>
           <ColorPicker
-            modelValue="#333"
+            :modelValue="theme.themeColor"
+            @update:modelValue="value => updateTheme({ themeColor: value })"
           />
         </template>
-        <ColorButton color="#333" style="flex: 3;" />
+        <ColorButton :color="theme.themeColor" style="flex: 3;" />
       </Popover>
     </div>
 
-    <div class="title" style="margin-top: 20px;">预置主题:</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 }"
+        @click="updateTheme({
+          fontColor: item.text,
+          backgroundColor: item.background,
+          themeColor: item.color,
+        })"
       >
         <div class="theme-item-content">
           <div class="text" :style="{ color: item.text }">Aa</div>
@@ -159,7 +168,7 @@
       </div>
     </div>
 
-    <div class="row"><Button style="flex: 1;" @click="applyAllSlide()">应用主题到全部</Button></div>
+    <div class="row"><Button style="flex: 1;" @click="applyThemeAllSlide()">应用主题到全部</Button></div>
   </div>
 </template>
 
@@ -167,42 +176,14 @@
 import { computed, defineComponent } from 'vue'
 import { useStore } from 'vuex'
 import { MutationTypes, State } from '@/store'
-import { Slide, SlideBackground } from '@/types/slides'
+import { Slide, SlideBackground, SlideTheme } from '@/types/slides'
+import { PRESET_THEMES } from '@/configs/theme'
 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' },
-]
+const themes = PRESET_THEMES
 
 export default defineComponent({
   name: 'slide-style-panel',
@@ -212,6 +193,7 @@ export default defineComponent({
   setup() {
     const store = useStore<State>()
     const slides = computed(() => store.state.slides)
+    const theme = computed(() => store.state.theme)
     const currentSlide = computed<Slide>(() => store.getters.currentSlide)
     const availableFonts = computed(() => store.state.availableFonts)
 
@@ -269,7 +251,7 @@ export default defineComponent({
       getImageDataURL(imageFile).then(dataURL => updateBackground({ image: dataURL }))
     }
 
-    const applyAllSlide = () => {
+    const applyBackgroundAllSlide = () => {
       const newSlides = slides.value.map(slide => {
         return {
           ...slide,
@@ -280,14 +262,25 @@ export default defineComponent({
       addHistorySnapshot()
     }
 
+    const updateTheme = (themeProps: Partial<SlideTheme>) => {
+      store.commit(MutationTypes.SET_THEME, themeProps)
+    }
+
+    const applyThemeAllSlide = () => {
+      console.log('applyThemeAllSlide')
+    }
+
     return {
       availableFonts,
       background,
       updateBackgroundType,
       updateBackground,
       uploadBackgroundImage,
-      applyAllSlide,
+      applyBackgroundAllSlide,
       themes,
+      theme,
+      updateTheme,
+      applyThemeAllSlide,
     }
   },
 })
@@ -356,6 +349,11 @@ export default defineComponent({
     flex-direction: column;
     justify-content: center;
     align-items: center;
+    transition: box-shadow .2s;
+
+    &:hover {
+      box-shadow: 0 0 4px #888;
+    }
   }
 
   .text {