This commit is contained in:
pipipi-pikachu 2021-01-06 23:19:21 +08:00
parent f002b05cdc
commit ca36cbac52
10 changed files with 131 additions and 36 deletions

View File

@ -2,7 +2,6 @@
outline: 0;
border: 0;
font-size: 20px;
line-height: 1.5;
word-break: break-word;
font-family: '微软雅黑';

View File

@ -53,6 +53,7 @@ import ImageClipHandler from './ImageClipHandler.vue'
export default defineComponent({
name: 'image-element-operate',
inheritAttrs: false,
components: {
RotateHandler,
ResizeHandler,

View File

@ -25,6 +25,7 @@ import ResizeHandler from './ResizeHandler.vue'
export default defineComponent({
name: 'text-element-operate',
inheritAttrs: false,
components: {
ResizeHandler,
},

View File

@ -40,6 +40,7 @@ import BorderLine from './BorderLine.vue'
export default defineComponent({
name: 'text-element-operate',
inheritAttrs: false,
components: {
RotateHandler,
ResizeHandler,

View File

@ -40,6 +40,7 @@ import BorderLine from './BorderLine.vue'
export default defineComponent({
name: 'text-element-operate',
inheritAttrs: false,
components: {
RotateHandler,
ResizeHandler,

View File

@ -81,14 +81,14 @@
<div class="row">
<div style="flex: 2;">行间距</div>
<Select style="flex: 3;" :value="lineHeight">
<Select style="flex: 3;" :value="lineHeight" @change="value => updateLineHeight(value)">
<template #suffixIcon><ColumnHeightOutlined /></template>
<SelectOption v-for="item in lineHeightOptions" :key="item" :value="item">{{item}}</SelectOption>
</Select>
</div>
<div class="row">
<div style="flex: 2;">字间距</div>
<Select style="flex: 3;" :value="wordSpace">
<Select style="flex: 3;" :value="wordSpace" @change="value => updateWordSpace(value)">
<template #suffixIcon><ColumnWidthOutlined /></template>
<SelectOption v-for="item in wordSpaceOptions" :key="item" :value="item">{{item}}</SelectOption>
</Select>
@ -111,10 +111,11 @@
<script lang="ts">
import { computed, defineComponent, onUnmounted, Ref, ref, watch } from 'vue'
import { useStore } from 'vuex'
import { State } from '@/store'
import { MutationTypes, State } from '@/store'
import { PPTTextElement } from '@/types/slides'
import emitter, { EmitterEvents } from '@/utils/emitter'
import { TextAttrs } from '@/prosemirror/utils'
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
import ElementOpacity from '../common/ElementOpacity.vue'
import ElementOutline from '../common/ElementOutline.vue'
@ -215,6 +216,20 @@ export default defineComponent({
emitter.off(EmitterEvents.UPDATE_TEXT_STATE, attr => updateRichTextAttrs(attr))
})
const { addHistorySnapshot } = useHistorySnapshot()
const updateLineHeight = (value: number) => {
const props = { lineHeight: value }
store.commit(MutationTypes.UPDATE_ELEMENT, { id: handleElement.value.id, props })
addHistorySnapshot()
}
const updateWordSpace = (value: number) => {
const props = { wordSpace: value }
store.commit(MutationTypes.UPDATE_ELEMENT, { id: handleElement.value.id, props })
addHistorySnapshot()
}
return {
fill,
lineHeight,
@ -224,6 +239,8 @@ export default defineComponent({
fontSizeOptions,
lineHeightOptions,
wordSpaceOptions,
updateLineHeight,
updateWordSpace,
}
},
})

View File

@ -2,7 +2,14 @@
<div class="element-opacity">
<div class="row">
<div style="flex: 2;">不透明度</div>
<Slider :min="0" :max="1" :step="0.1" :value="opacity" style="flex: 3;" />
<Slider
:min="0"
:max="1"
:step="0.1"
:value="opacity"
style="flex: 3;"
@change="value => updateOpacity(value)"
/>
</div>
</div>
</template>
@ -10,8 +17,9 @@
<script lang="ts">
import { computed, defineComponent, Ref, ref, watch } from 'vue'
import { useStore } from 'vuex'
import { State } from '@/store'
import { MutationTypes, State } from '@/store'
import { PPTElement } from '@/types/slides'
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
import { Slider } from 'ant-design-vue'
@ -31,8 +39,17 @@ export default defineComponent({
opacity.value = 'opacity' in handleElement.value && handleElement.value.opacity || 1
}, { deep: true, immediate: true })
const { addHistorySnapshot } = useHistorySnapshot()
const updateOpacity = (value: number) => {
const props = { opacity: value }
store.commit(MutationTypes.UPDATE_ELEMENT, { id: handleElement.value.id, props })
addHistorySnapshot()
}
return {
opacity,
updateOpacity,
}
},
})

View File

@ -3,13 +3,20 @@
<div class="row">
<div style="flex: 2;">启用边框</div>
<div class="switch-wrapper" style="flex: 3;">
<Switch :checked="hasOutline" @change="checked => toggleOutline(checked)" />
<Switch
:checked="hasOutline"
@change="checked => toggleOutline(checked)"
/>
</div>
</div>
<template v-if="hasOutline">
<div class="row">
<div style="flex: 2;">边框样式</div>
<Select style="flex: 3;" :value="outline.style">
<Select
style="flex: 3;"
:value="outline.style"
@change="value => updateOutline({ style: value })"
>
<SelectOption value="solid">实线边框</SelectOption>
<SelectOption value="dashed">虚线边框</SelectOption>
</Select>
@ -18,7 +25,10 @@
<div style="flex: 2;">边框颜色</div>
<Popover trigger="click">
<template #content>
<ColorPicker v-model="outline.color" />
<ColorPicker
:modelValue="outline.color"
@update:modelValue="value => updateOutline({ color: value })"
/>
</template>
<Button class="color-btn" style="flex: 3;">
<div class="color-block" :style="{ backgroundColor: outline.color }"></div>
@ -28,7 +38,11 @@
</div>
<div class="row">
<div style="flex: 2;">边框粗细</div>
<InputNumber :value="outline.width" style="flex: 3;" />
<InputNumber
:value="outline.width"
@change="value => updateOutline({ width: value })"
style="flex: 3;"
/>
</div>
</template>
</div>
@ -37,8 +51,9 @@
<script lang="ts">
import { computed, defineComponent, Ref, ref, watch } from 'vue'
import { useStore } from 'vuex'
import { State } from '@/store'
import { MutationTypes, State } from '@/store'
import { PPTElement, PPTElementOutline } from '@/types/slides'
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
import ColorPicker from '@/components/ColorPicker/index.vue'
import { Select, Button, Popover, InputNumber, Switch } from 'ant-design-vue'
@ -69,21 +84,28 @@ export default defineComponent({
hasOutline.value = !!outline.value
}, { deep: true, immediate: true })
const { addHistorySnapshot } = useHistorySnapshot()
const updateOutline = (outlineProps: Partial<PPTElementOutline>) => {
const props = { outline: { ...outline.value, ...outlineProps } }
store.commit(MutationTypes.UPDATE_ELEMENT, { id: handleElement.value.id, props })
addHistorySnapshot()
}
const toggleOutline = (checked: boolean) => {
if(!checked) {
outline.value = undefined
hasOutline.value = false
}
else {
outline.value = { width: 2, color: '#000', style: 'solid' }
hasOutline.value = true
let props: { outline?: PPTElementOutline } = { outline: undefined }
if(checked) {
props = { outline: { width: 2, color: '#000', style: 'solid' } }
}
store.commit(MutationTypes.UPDATE_ELEMENT, { id: handleElement.value.id, props })
addHistorySnapshot()
}
return {
outline,
hasOutline,
toggleOutline,
updateOutline,
}
},
})

View File

@ -9,21 +9,45 @@
<template v-if="hasShadow">
<div class="row">
<div style="flex: 2;">水平阴影</div>
<Slider :min="1" :max="10" :step="1" :value="shadow.h" style="flex: 3;" />
<Slider
:min="1"
:max="10"
:step="1"
:value="shadow.h"
@change="value => updateShadow({ h: value })"
style="flex: 3;"
/>
</div>
<div class="row">
<div style="flex: 2;">垂直阴影</div>
<Slider :min="1" :max="10" :step="1" :value="shadow.v" style="flex: 3;" />
<Slider
:min="1"
:max="10"
:step="1"
:value="shadow.v"
@change="value => updateShadow({ v: value })"
style="flex: 3;"
/>
</div>
<div class="row">
<div style="flex: 2;">模糊距离</div>
<Slider :min="1" :max="20" :step="1" :value="shadow.blur" style="flex: 3;" />
<Slider
:min="1"
:max="20"
:step="1"
:value="shadow.blur"
@change="value => updateShadow({ blur: value })"
style="flex: 3;"
/>
</div>
<div class="row">
<div style="flex: 2;">阴影颜色</div>
<Popover trigger="click">
<template #content>
<ColorPicker v-model="shadow.color" />
<ColorPicker
:modelValue="shadow.color"
@update:modelValue="value => updateShadow({ color: value })"
/>
</template>
<Button class="color-btn" style="flex: 3;">
<div class="color-block"></div>
@ -38,8 +62,9 @@
<script lang="ts">
import { computed, defineComponent, Ref, ref, watch } from 'vue'
import { useStore } from 'vuex'
import { State } from '@/store'
import { MutationTypes, State } from '@/store'
import { PPTElement, PPTElementShadow } from '@/types/slides'
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
import ColorPicker from '@/components/ColorPicker/index.vue'
import { Slider, Button, Popover, Switch } from 'ant-design-vue'
@ -68,21 +93,28 @@ export default defineComponent({
hasShadow.value = !!shadow.value
}, { deep: true, immediate: true })
const { addHistorySnapshot } = useHistorySnapshot()
const updateShadow = (shadowProps: Partial<PPTElementShadow>) => {
const props = { shadow: { ...shadow.value, ...shadowProps } }
store.commit(MutationTypes.UPDATE_ELEMENT, { id: handleElement.value.id, props })
addHistorySnapshot()
}
const toggleShadow = (checked: boolean) => {
if(!checked) {
shadow.value = undefined
hasShadow.value = false
}
else {
shadow.value = { h: 1, v: 1, blur: 2, color: '#000' }
hasShadow.value = true
let props: { shadow?: PPTElementShadow } = { shadow: undefined }
if(checked) {
props = { shadow: { h: 1, v: 1, blur: 2, color: '#000' } }
}
store.commit(MutationTypes.UPDATE_ELEMENT, { id: handleElement.value.id, props })
addHistorySnapshot()
}
return {
shadow,
hasShadow,
toggleShadow,
updateShadow,
}
},
})

View File

@ -1,12 +1,16 @@
import { Ref } from 'vue'
import { ref, Ref, watchEffect } from 'vue'
import { PPTElementShadow } from '@/types/slides'
export default (shadow: Ref<PPTElementShadow | undefined>) => {
let shadowStyle = ''
const shadowStyle = ref('')
watchEffect(() => {
if(shadow.value) {
const { h, v, blur, color } = shadow.value
shadowStyle = `${h}px ${v}px ${blur}px ${color}`
shadowStyle.value = `${h}px ${v}px ${blur}px ${color}`
}
else shadowStyle.value = ''
})
return {
shadowStyle,