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;
}
::-webkit-scrollbar-thumb {
background-color: #e1e1e1;
border-radius: 5px;
background-color: #c1c1c1;
}

View File

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

View File

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

View File

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

View File

@ -27,14 +27,7 @@ export enum OperateBorderLines {
R = 'right',
}
export type OperateResizeHandler = 'left-top' |
'top' |
'right-top' |
'left' |
'right' |
'left-bottom' |
'bottom' |
'right-bottom'
export type OperateResizeHandler = 'left-top' | 'top' | 'right-top' | 'left' | 'right' | 'left-bottom' | 'bottom' | 'right-bottom'
export enum OperateResizeHandlers {
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
class="animation-index"
v-if="toolbarState === 'animation' && elementIndexInAnimation !== -1"
v-if="toolbarState === 'elAnimation' && elementIndexInAnimation !== -1"
>
{{elementIndexInAnimation + 1}}
</div>

View File

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

View File

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

View File

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

View File

@ -1,14 +1,70 @@
<template>
<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>
</template>
<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({
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>
@ -16,7 +72,35 @@ export default defineComponent({
.toolbar {
border-left: solid 1px #eee;
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;
padding: 5px 0;
}
</style>