This commit is contained in:
pipipi-pikachu 2020-12-26 14:28:09 +08:00
parent be74d0b9ca
commit 8bf5744e03
18 changed files with 124 additions and 49 deletions

View File

@ -58,6 +58,5 @@ a {
background-color: #fff; background-color: #fff;
} }
::-webkit-scrollbar-thumb { ::-webkit-scrollbar-thumb {
background-color: #e1e1e1; background-color: #c1c1c1;
border-radius: 5px;
} }

View File

@ -52,7 +52,7 @@ export default defineComponent({
<style lang="scss" scoped> <style lang="scss" scoped>
$menuWidth: 160px; $menuWidth: 160px;
$menuHeight: 32px; $menuHeight: 30px;
$subMenuWidth: 120px; $subMenuWidth: 120px;
.contextmenu-content { .contextmenu-content {
@ -107,22 +107,22 @@ $subMenuWidth: 120px;
&.has-sub-menu::before { &.has-sub-menu::before {
content: ''; content: '';
display: inline-block; display: inline-block;
width: 0; width: 8px;
height: 0; height: 8px;
border-top: 4px solid transparent; border-width: 1px;
border-left: 6px solid rgba($color: $themeColor, $alpha: .8); border-style: solid;
border-bottom: 4px solid transparent; border-color: #666 #666 transparent transparent;
position: absolute; position: absolute;
right: 0; right: 0;
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%) rotate(45deg);
} }
.sub-text { .sub-text {
opacity: 0.6; opacity: 0.6;
} }
.sub-menu { .sub-menu {
position: absolute; position: absolute;
top: -5px; top: -6px;
display: none; display: none;
width: $subMenuWidth; width: $subMenuWidth;
} }

View File

@ -28,7 +28,7 @@ import { ContextmenuItem, Axis } from './types'
import ContextmenuContent from './ContextmenuContent.vue' import ContextmenuContent from './ContextmenuContent.vue'
const MENU_WIDTH = 160 const MENU_WIDTH = 160
const MENU_HEIGHT = 32 const MENU_HEIGHT = 30
const DIVIDER_HEIGHT = 11 const DIVIDER_HEIGHT = 11
const SUB_MENU_WIDTH = 120 const SUB_MENU_WIDTH = 120

View File

@ -5,6 +5,7 @@ import { mutations } from './mutations'
import { MutationTypes, ActionTypes } from './constants' import { MutationTypes, ActionTypes } from './constants'
import { Slide } from '@/types/slides' import { Slide } from '@/types/slides'
import { ToolbarState } from '@/types/toolbar'
import { slides } from '@/mocks/index' import { slides } from '@/mocks/index'
import { FontName } from '@/configs/fontName' import { FontName } from '@/configs/fontName'
@ -20,7 +21,7 @@ export interface State {
disableHotkeys: boolean; disableHotkeys: boolean;
showGridLines: boolean; showGridLines: boolean;
availableFonts: FontName[]; availableFonts: FontName[];
toolbarState: string; toolbarState: ToolbarState;
slides: Slide[]; slides: Slide[];
slideIndex: number; slideIndex: number;
snapshotCursor: number; snapshotCursor: number;
@ -40,7 +41,7 @@ const state: State = {
disableHotkeys: false, disableHotkeys: false,
showGridLines: false, showGridLines: false,
availableFonts: [], availableFonts: [],
toolbarState: '', toolbarState: 'slideStyle',
slides: slides, slides: slides,
slideIndex: 0, slideIndex: 0,
snapshotCursor: -1, snapshotCursor: -1,

View File

@ -27,14 +27,7 @@ export enum OperateBorderLines {
R = 'right', R = 'right',
} }
export type OperateResizeHandler = 'left-top' | export type OperateResizeHandler = 'left-top' | 'top' | 'right-top' | 'left' | 'right' | 'left-bottom' | 'bottom' | 'right-bottom'
'top' |
'right-top' |
'left' |
'right' |
'left-bottom' |
'bottom' |
'right-bottom'
export enum OperateResizeHandlers { export enum OperateResizeHandlers {
LEFT_TOP = 'left-top', LEFT_TOP = 'left-top',

11
src/types/toolbar.ts Normal file
View File

@ -0,0 +1,11 @@
export type ToolbarState = 'elAnimation' | 'elStyle' | 'elPosition' | 'slideStyle' | 'slideAnimation' | 'multiPosition' | 'multiCommand'
export const ToolbarStates = {
EL_ANIMATION: 'elAnimation',
EL_STYLE: 'elStyle',
EL_POSITION: 'elPosition',
SLIDE_STYLE: 'slideStyle',
SLIDE_ANIMATION: 'slideAnimation',
MULTI_POSITION: 'multiPosition',
MULTI_COMMAND: 'multiCommand',
}

View File

@ -22,7 +22,7 @@
<div <div
class="animation-index" class="animation-index"
v-if="toolbarState === 'animation' && elementIndexInAnimation !== -1" v-if="toolbarState === 'elAnimation' && elementIndexInAnimation !== -1"
> >
{{elementIndexInAnimation + 1}} {{elementIndexInAnimation + 1}}
</div> </div>

View File

@ -10,8 +10,8 @@
<div <div
class="viewport-wrapper" class="viewport-wrapper"
:style="{ :style="{
width: viewportStyles.width + 'px', width: viewportStyles.width * canvasScale + 'px',
height: viewportStyles.height + 'px', height: viewportStyles.height * canvasScale + 'px',
left: viewportStyles.left + 'px', left: viewportStyles.left + 'px',
top: viewportStyles.top + 'px', top: viewportStyles.top + 'px',
}" }"
@ -40,12 +40,7 @@
:rotateElement="rotateElement" :rotateElement="rotateElement"
:scaleElement="scaleElement" :scaleElement="scaleElement"
/> />
<SlideBackground <SlideBackground />
:style="{
width: viewportStyles.width * canvasScale + 'px',
height: viewportStyles.height * canvasScale + 'px',
}"
/>
</div> </div>
<div <div

View File

@ -10,9 +10,6 @@
</div> </div>
<div class="right"> <div class="right">
<div class="menu-item">
<IconFont class="icon" type="icon-play-circle" />
</div>
<div class="menu-item icon"> <div class="menu-item icon">
<IconFont class="icon" type="icon-github-fill" /> <IconFont class="icon" type="icon-github-fill" />
</div> </div>
@ -50,6 +47,7 @@ export default defineComponent({
.icon { .icon {
font-size: 20px; font-size: 20px;
color: #666;
} }
} }
</style> </style>

View File

@ -4,9 +4,7 @@
@mousedown="() => setThumbnailsFocus(true)" @mousedown="() => setThumbnailsFocus(true)"
v-click-outside="() => setThumbnailsFocus(false)" v-click-outside="() => setThumbnailsFocus(false)"
> >
<div class="add-slide"> <div class="add-slide" @click="createSlide()">+ 添加幻灯片</div>
<span @click="createSlide()">+ 添加幻灯片</span>
</div>
<draggable <draggable
class="thumbnail-list" class="thumbnail-list"
:modelValue="slides" :modelValue="slides"
@ -145,7 +143,6 @@ export default defineComponent({
background-color: #fff; background-color: #fff;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: auto;
user-select: none; user-select: none;
} }
.add-slide { .add-slide {
@ -154,17 +151,14 @@ export default defineComponent({
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
flex-shrink: 0;
span { border-bottom: 1px solid #eee;
cursor: pointer; cursor: pointer;
padding: 5px;
&:hover {
border: 1px solid #eee;
}
}
} }
.thumbnail-list { .thumbnail-list {
padding: 5px 0; padding: 5px 0;
flex: 1;
overflow: auto;
} }
.thumbnail-wrapper { .thumbnail-wrapper {
display: flex; display: flex;
@ -173,7 +167,7 @@ export default defineComponent({
padding: 5px 0; padding: 5px 0;
.thumbnail { .thumbnail {
outline: 2px solid rgba($color: $themeColor, $alpha: .1); outline: 1px solid rgba($color: $themeColor, $alpha: .1);
} }
&.active { &.active {

View File

@ -1,14 +1,70 @@
<template> <template>
<div class="toolbar"> <div class="toolbar">
<div class="tabs">
<div
class="tab"
:class="{ 'active': tab.value === toolbarState }"
v-for="tab in currentTabs"
:key="tab.value"
@click="setToolbarState(tab.value)"
>{{tab.label}}</div>
</div>
<div class="content">
</div> </div>
</div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue' import { computed, defineComponent, watch } from 'vue'
import { useStore } from 'vuex'
import { MutationTypes, State } from '@/store'
import { ToolbarState, ToolbarStates } from '@/types/toolbar'
export default defineComponent({ export default defineComponent({
name: 'toolbar', name: 'toolbar',
setup() {
const store = useStore<State>()
const toolbarState = computed(() => store.state.toolbarState)
const elementTabs = [
{ label: '样式', value: ToolbarStates.EL_STYLE },
{ label: '位置', value: ToolbarStates.EL_POSITION },
{ label: '动画', value: ToolbarStates.EL_ANIMATION },
]
const slideTabs = [
{ label: '页面样式', value: ToolbarStates.SLIDE_STYLE },
{ label: '翻页动画', value: ToolbarStates.SLIDE_ANIMATION },
]
const multiSelectTabs = [
{ label: '位置', value: ToolbarStates.MULTI_POSITION },
{ label: '操作', value: ToolbarStates.MULTI_COMMAND },
]
const setToolbarState = (value: ToolbarState) => {
store.commit(MutationTypes.SET_TOOLBAR_STATE, value)
}
const activeElementIdList = computed(() => store.state.activeElementIdList)
const currentTabs = computed(() => {
if(!activeElementIdList.value.length) return slideTabs
else if(activeElementIdList.value.length > 1) return multiSelectTabs
return elementTabs
})
watch(currentTabs, () => {
const currentTabsValue = currentTabs.value.map(tab => tab.value)
if(!currentTabsValue.includes(toolbarState.value)) {
store.commit(MutationTypes.SET_TOOLBAR_STATE, currentTabsValue[0])
}
})
return {
toolbarState,
currentTabs,
setToolbarState,
}
},
}) })
</script> </script>
@ -16,7 +72,35 @@ export default defineComponent({
.toolbar { .toolbar {
border-left: solid 1px #eee; border-left: solid 1px #eee;
background-color: #fff; background-color: #fff;
display: flex;
flex-direction: column;
}
.tabs {
height: 40px;
font-size: 12px;
flex-shrink: 0;
display: flex;
}
.tab {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
background-color: #f9f9f9;
border-bottom: 1px solid #eee;
cursor: pointer;
&.active {
background-color: #fff;
border-bottom-color: #fff;
}
& + .tab {
border-left: 1px solid #eee;
}
}
.content {
padding: 5px;
overflow: auto; overflow: auto;
padding: 5px 0;
} }
</style> </style>