mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
update
This commit is contained in:
parent
395df00bd2
commit
045f361e14
@ -17,6 +17,9 @@
|
||||
.ant-radio-group {
|
||||
font-size: 13px !important;
|
||||
}
|
||||
.ant-select-selection-item {
|
||||
font-size: 13px;
|
||||
}
|
||||
.ant-select-item-option-content {
|
||||
font-size: 13px !important;
|
||||
}
|
||||
|
@ -12,10 +12,12 @@ export default (background: Ref<SlideBackground | undefined>) => {
|
||||
return {
|
||||
backgroundImage: `url(${value}`,
|
||||
backgroundRepeat: 'repeat',
|
||||
backgroundSize: 'initial',
|
||||
}
|
||||
}
|
||||
return {
|
||||
backgroundImage: `url(${value}`,
|
||||
backgroundRepeat: 'no-repeat',
|
||||
backgroundSize: size,
|
||||
}
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ export interface PPTAnimation {
|
||||
export interface SlideBackground {
|
||||
type: 'solid' | 'image';
|
||||
value: string;
|
||||
size?: 'cover' | 'contain' | 'repeat';
|
||||
size?: 'cover' | 'contain' | 'repeat' | 'initial';
|
||||
}
|
||||
|
||||
export interface Slide {
|
||||
|
@ -43,7 +43,6 @@ export default defineComponent({
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,29 +1,45 @@
|
||||
<template>
|
||||
<div class="canvas-tool">
|
||||
<div class="left-handler">
|
||||
<IconFont type="icon-undo" class="handler-item" :class="{ 'disable': !canUndo }" @click="undo()" />
|
||||
<IconFont type="icon-redo" class="handler-item" :class="{ 'disable': !canRedo }" @click="redo()" />
|
||||
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="撤销">
|
||||
<IconFont type="icon-undo" class="handler-item" :class="{ 'disable': !canUndo }" @click="undo()" />
|
||||
</Tooltip>
|
||||
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="重做">
|
||||
<IconFont type="icon-redo" class="handler-item" :class="{ 'disable': !canRedo }" @click="redo()" />
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<div class="add-element-handler">
|
||||
<IconFont type="icon-font-size" class="handler-item" @click="drawText()" />
|
||||
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="插入文字">
|
||||
<IconFont type="icon-font-size" class="handler-item" @click="drawText()" />
|
||||
</Tooltip>
|
||||
<FileInput @change="files => insertImageElement(files)">
|
||||
<IconFont type="icon-image" class="handler-item" />
|
||||
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="插入图片">
|
||||
<IconFont type="icon-image" class="handler-item" />
|
||||
</Tooltip>
|
||||
</FileInput>
|
||||
<Popover trigger="click" v-model:visible="isOpenShapePool">
|
||||
<template #content>
|
||||
<ShapePool @select="shape => drawShape(shape)" />
|
||||
</template>
|
||||
<IconFont type="icon-star" class="handler-item" />
|
||||
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="插入形状">
|
||||
<IconFont type="icon-star" class="handler-item" />
|
||||
</Tooltip>
|
||||
</Popover>
|
||||
<Popover trigger="click" v-model:visible="isOpenLinePool">
|
||||
<template #content>
|
||||
<LinePool @select="line => drawLine(line)" />
|
||||
</template>
|
||||
<IconFont type="icon-line" class="handler-item" />
|
||||
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="插入线条">
|
||||
<IconFont type="icon-line" class="handler-item" />
|
||||
</Tooltip>
|
||||
</Popover>
|
||||
<IconFont type="icon-table" class="handler-item" />
|
||||
<IconFont type="icon-piechart" class="handler-item" />
|
||||
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="插入表格">
|
||||
<IconFont type="icon-table" class="handler-item" />
|
||||
</Tooltip>
|
||||
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="插入图表">
|
||||
<IconFont type="icon-piechart" class="handler-item" />
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<div class="right-handler">
|
||||
|
@ -4,7 +4,6 @@
|
||||
<div class="menu-item">文件</div>
|
||||
<div class="menu-item">编辑</div>
|
||||
<div class="menu-item">设置</div>
|
||||
<div class="menu-item">素材</div>
|
||||
<div class="menu-item">演示</div>
|
||||
<div class="menu-item">帮助</div>
|
||||
</div>
|
||||
|
@ -26,8 +26,8 @@
|
||||
<Divider />
|
||||
|
||||
<ButtonGroup class="row">
|
||||
<Button :disabled="!canCombine" @click="combineElements()" style="flex: 1;">组合</Button>
|
||||
<Button :disabled="canCombine" @click="uncombineElements()" style="flex: 1;">取消组合</Button>
|
||||
<Button :disabled="!canCombine" @click="combineElements()" style="flex: 1;"><IconFont type="icon-group" />组合</Button>
|
||||
<Button :disabled="canCombine" @click="uncombineElements()" style="flex: 1;"><IconFont type="icon-ungroup" />取消组合</Button>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -1,13 +1,178 @@
|
||||
<template>
|
||||
<div class="slide-style-panel">
|
||||
<div>背景填充</div>
|
||||
<div class="title">背景填充</div>
|
||||
<div class="row">
|
||||
<Select
|
||||
style="flex: 10;"
|
||||
:value="background.type"
|
||||
@change="value => updateBackgroundType(value)"
|
||||
>
|
||||
<SelectOption value="solid">纯色填充</SelectOption>
|
||||
<SelectOption value="image">图片填充</SelectOption>
|
||||
</Select>
|
||||
<div style="flex: 1;"></div>
|
||||
<Popover trigger="click" v-if="background.type === 'solid'">
|
||||
<template #content>
|
||||
<ColorPicker
|
||||
:modelValue="background.value"
|
||||
@update:modelValue="value => updateBackground({ value })"
|
||||
/>
|
||||
</template>
|
||||
<ColorButton :color="background.value" style="flex: 10;" />
|
||||
</Popover>
|
||||
<Select
|
||||
style="flex: 10;"
|
||||
:value="background.size || 'cover'"
|
||||
@change="value => updateBackground({ size: value })"
|
||||
v-else
|
||||
>
|
||||
<SelectOption value="initial">原始大小</SelectOption>
|
||||
<SelectOption value="contain">缩放</SelectOption>
|
||||
<SelectOption value="repeat">拼贴</SelectOption>
|
||||
<SelectOption value="cover">缩放铺满</SelectOption>
|
||||
</Select>
|
||||
</div>
|
||||
<div class="background-image-wrapper" v-if="background.type === 'image'">
|
||||
<FileInput @change="files => uploadBackgroundImage(files)">
|
||||
<div class="background-image">
|
||||
<div
|
||||
class="content"
|
||||
:style="backgroundStyle"
|
||||
>
|
||||
<IconFont type="icon-plus" />
|
||||
</div>
|
||||
</div>
|
||||
</FileInput>
|
||||
</div>
|
||||
<div class="row"><Button style="flex: 1;" @click="applyAllSlide()">应用到全部</Button></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import { computed, defineComponent, Ref } from 'vue'
|
||||
import { useStore } from 'vuex'
|
||||
import { MutationTypes, State } from '@/store'
|
||||
import { Slide, SlideBackground } from '@/types/slides'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
|
||||
import ColorButton from './common/ColorButton.vue'
|
||||
import { getImageDataURL } from '@/utils/image'
|
||||
import useSlideBackgroundStyle from '@/hooks/useSlideBackgroundStyle'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'slide-style-panel',
|
||||
components: {
|
||||
ColorButton,
|
||||
},
|
||||
setup() {
|
||||
const store = useStore<State>()
|
||||
const slides = computed(() => store.state.slides)
|
||||
const currentSlide: Ref<Slide> = computed(() => store.getters.currentSlide)
|
||||
|
||||
const background = computed(() => {
|
||||
if(!currentSlide.value.background) {
|
||||
return {
|
||||
type: 'solid',
|
||||
value: '#fff',
|
||||
} as SlideBackground
|
||||
}
|
||||
return currentSlide.value.background
|
||||
})
|
||||
|
||||
const { backgroundStyle } = useSlideBackgroundStyle(background)
|
||||
|
||||
const { addHistorySnapshot } = useHistorySnapshot()
|
||||
|
||||
const updateBackgroundType = (type: 'solid' | 'image') => {
|
||||
if(type === 'solid') {
|
||||
const background: SlideBackground = {
|
||||
type: 'solid',
|
||||
value: '#fff',
|
||||
}
|
||||
store.commit(MutationTypes.UPDATE_SLIDE, { background })
|
||||
}
|
||||
else {
|
||||
const background: SlideBackground = {
|
||||
type: 'image',
|
||||
value: '',
|
||||
size: 'cover',
|
||||
}
|
||||
store.commit(MutationTypes.UPDATE_SLIDE, { background })
|
||||
}
|
||||
addHistorySnapshot()
|
||||
}
|
||||
|
||||
const updateBackground = (props: Partial<SlideBackground>) => {
|
||||
store.commit(MutationTypes.UPDATE_SLIDE, { background: { ...background.value, ...props } })
|
||||
addHistorySnapshot()
|
||||
}
|
||||
|
||||
const uploadBackgroundImage = (files: File[]) => {
|
||||
const imageFile = files[0]
|
||||
if(!imageFile) return
|
||||
getImageDataURL(imageFile).then(dataURL => updateBackground({ value: dataURL }))
|
||||
}
|
||||
|
||||
const applyAllSlide = () => {
|
||||
const newSlides = slides.value.map(slide => {
|
||||
return {
|
||||
...slide,
|
||||
background: currentSlide.value.background,
|
||||
}
|
||||
})
|
||||
store.commit(MutationTypes.SET_SLIDES, newSlides)
|
||||
addHistorySnapshot()
|
||||
}
|
||||
|
||||
return {
|
||||
background,
|
||||
backgroundStyle,
|
||||
updateBackgroundType,
|
||||
updateBackground,
|
||||
uploadBackgroundImage,
|
||||
applyAllSlide,
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.row {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.title {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.background-image-wrapper {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.background-image {
|
||||
height: 0;
|
||||
padding-bottom: 56.25%;
|
||||
border: 1px dashed $borderColor;
|
||||
border-radius: $borderRadius;
|
||||
position: relative;
|
||||
transition: all .2s;
|
||||
|
||||
&:hover {
|
||||
border-color: $themeColor;
|
||||
color: $themeColor;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-position: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
38
src/views/Editor/Toolbar/common/ColorButton.vue
Normal file
38
src/views/Editor/Toolbar/common/ColorButton.vue
Normal file
@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<Button class="color-btn">
|
||||
<div class="color-block" :style="{ backgroundColor: color }"></div>
|
||||
<IconFont type="icon-down" class="color-btn-icon" />
|
||||
</Button>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'color-button',
|
||||
props: {
|
||||
color: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.color-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 !important;
|
||||
}
|
||||
.color-block {
|
||||
height: 20px;
|
||||
margin-left: 8px;
|
||||
flex: 1;
|
||||
}
|
||||
.color-btn-icon {
|
||||
width: 30px;
|
||||
font-size: 12px;
|
||||
margin-top: 2px;
|
||||
color: #bfbfbf;
|
||||
}
|
||||
</style>
|
@ -30,10 +30,7 @@
|
||||
@update:modelValue="value => updateOutline({ color: value })"
|
||||
/>
|
||||
</template>
|
||||
<Button class="color-btn" style="flex: 3;">
|
||||
<div class="color-block" :style="{ backgroundColor: outline.color }"></div>
|
||||
<IconFont type="icon-down" class="color-btn-icon" />
|
||||
</Button>
|
||||
<ColorButton :color="outline.color" style="flex: 3;" />
|
||||
</Popover>
|
||||
</div>
|
||||
<div class="row">
|
||||
@ -55,8 +52,13 @@ import { MutationTypes, State } from '@/store'
|
||||
import { PPTElement, PPTElementOutline } from '@/types/slides'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
|
||||
import ColorButton from './ColorButton.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'element-outline',
|
||||
components: {
|
||||
ColorButton,
|
||||
},
|
||||
setup() {
|
||||
const store = useStore<State>()
|
||||
const handleElement: Ref<PPTElement> = computed(() => store.getters.handleElement)
|
||||
@ -104,22 +106,6 @@ export default defineComponent({
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.color-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 !important;
|
||||
}
|
||||
.color-block {
|
||||
width: 100px;
|
||||
height: 20px;
|
||||
background-color: #777;
|
||||
margin: 0 8px;
|
||||
}
|
||||
.color-btn-icon {
|
||||
font-size: 12px;
|
||||
margin-top: 2px;
|
||||
color: #bfbfbf;
|
||||
}
|
||||
.switch-wrapper {
|
||||
text-align: right;
|
||||
}
|
||||
|
@ -49,10 +49,7 @@
|
||||
@update:modelValue="value => updateShadow({ color: value })"
|
||||
/>
|
||||
</template>
|
||||
<Button class="color-btn" style="flex: 3;">
|
||||
<div class="color-block"></div>
|
||||
<IconFont type="icon-down" class="color-btn-icon" />
|
||||
</Button>
|
||||
<ColorButton :color="shadow.color" style="flex: 3;" />
|
||||
</Popover>
|
||||
</div>
|
||||
</template>
|
||||
@ -66,8 +63,13 @@ import { MutationTypes, State } from '@/store'
|
||||
import { PPTElement, PPTElementShadow } from '@/types/slides'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
|
||||
import ColorButton from './ColorButton.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'element-shadow',
|
||||
components: {
|
||||
ColorButton,
|
||||
},
|
||||
setup() {
|
||||
const store = useStore<State>()
|
||||
const handleElement: Ref<PPTElement> = computed(() => store.getters.handleElement)
|
||||
@ -115,22 +117,6 @@ export default defineComponent({
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.color-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 !important;
|
||||
}
|
||||
.color-block {
|
||||
width: 100px;
|
||||
height: 20px;
|
||||
background-color: #777;
|
||||
margin: 0 8px;
|
||||
}
|
||||
.color-btn-icon {
|
||||
font-size: 12px;
|
||||
margin-top: 2px;
|
||||
color: #bfbfbf;
|
||||
}
|
||||
.switch-wrapper {
|
||||
text-align: right;
|
||||
}
|
||||
|
@ -67,8 +67,9 @@ export default defineComponent({
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
.background {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
@ -69,8 +69,9 @@ export default defineComponent({
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
.background {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
Loading…
x
Reference in New Issue
Block a user