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; outline: 0;
border: 0; border: 0;
font-size: 20px; font-size: 20px;
line-height: 1.5;
word-break: break-word; word-break: break-word;
font-family: '微软雅黑'; font-family: '微软雅黑';

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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