添加主题相关数据字段

This commit is contained in:
pipipi-pikachu 2021-01-27 18:01:56 +08:00
parent a3e9146db0
commit 90d878e9a3
6 changed files with 92 additions and 45 deletions

30
src/configs/theme.ts Normal file
View File

@ -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' },
]

View File

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

View File

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

View File

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

View File

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

View File

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