mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
feat: 添加特殊符号输入面板
This commit is contained in:
parent
71253cecfc
commit
e14d37e617
59
src/configs/symbol.ts
Normal file
59
src/configs/symbol.ts
Normal file
@ -0,0 +1,59 @@
|
||||
export const SYMBOL_LIST = [
|
||||
{
|
||||
key: 'letter',
|
||||
label: '字母',
|
||||
children: [
|
||||
'α', 'β', 'γ', 'δ', 'ϵ', 'ε', 'ζ', 'η', 'θ', 'ϑ', 'ι', 'κ', 'λ', 'μ', 'ν', 'ξ', 'π', 'ϖ', 'ρ', 'ϱ', 'σ', 'ς', 'τ', 'υ', 'ϕ', 'φ', 'χ', 'ψ', 'ω',
|
||||
'Γ', 'Δ', 'Θ', 'Λ', 'Ξ', 'Π', 'Σ', 'Υ', 'Φ', 'Ψ', 'Ω',
|
||||
'𝐀', '𝐁', '𝐂', '𝐃', '𝐄', '𝐅', '𝐆', '𝐇', '𝐈', '𝐉', '𝐊', '𝐋', '𝐌', '𝐍', '𝐎', '𝐏', '𝐐', '𝐑', '𝐒', '𝐓', '𝐔', '𝐕', '𝐖', '𝐗', '𝐘', '𝐙',
|
||||
'𝐚', '𝐛', '𝐜', '𝐝', '𝐞', '𝐟', '𝐠', '𝐡', '𝐢', '𝐣', '𝐤', '𝐥', '𝐦', '𝐧', '𝐨', '𝐩', '𝐪', '𝐫', '𝐬', '𝐭', '𝐮', '𝐯', '𝐰', '𝐱', '𝐲', '𝐳',
|
||||
'𝓐', '𝓑', '𝓒', '𝓓', '𝓔', '𝓕', '𝓖', '𝓗', '𝓘', '𝓙', '𝓚', '𝓛', '𝓜', '𝓝', '𝓞', '𝓟', '𝓠', '𝓡', '𝓢', '𝓣', '𝓤', '𝓥', '𝓦', '𝓧', '𝓨', '𝓩',
|
||||
'𝓪', '𝓫', '𝓬', '𝓭', '𝓮', '𝓯', '𝓰', '𝓱', '𝓲', '𝓳', '𝓴', '𝓵', '𝓶', '𝓷', '𝓸', '𝓹', '𝓺', '𝓻', '𝓼', '𝓽', '𝓾', '𝓿', '𝔀', '𝔁', '𝔂', '𝔃',
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'number',
|
||||
label: '序号',
|
||||
children: [
|
||||
'①', '②', '③', '④', '⑤', '⑥', '⑦', '⑧', '⑨', '⑩', '⑪', '⑫', '⑬', '⑭', '⑮', '⑯', '⑰', '⑱', '⑲', '⑳',
|
||||
'⑴', '⑵', '⑶', '⑷', '⑸', '⑹', '⑺', '⑻', '⑼', '⑽', '⑾', '⑿', '⒀', '⒁', '⒂', '⒃', '⒄', '⒅', '⒆', '⒇',
|
||||
'º', '¹', '²', '³', '⁴', '⁵', '⁶', '⁷', '⁸', '⁹', '₀', '₁', '₂', '₃', '₄', '₅', '₆', '₇', '₈', '₉',
|
||||
'Ⅰ', 'Ⅱ', 'Ⅲ', 'Ⅳ', 'Ⅴ', 'Ⅵ', 'Ⅶ', 'Ⅷ', 'Ⅸ', 'Ⅹ', 'Ⅺ', 'Ⅻ', 'Ⅼ', 'Ⅽ', 'Ⅾ', 'Ⅿ',
|
||||
'ⅰ', 'ⅱ', 'ⅲ', 'ⅳ', 'ⅴ', 'ⅵ', 'ⅶ', 'ⅷ', 'ⅸ', 'ⅹ', 'ⅺ', 'ⅻ', 'ⅼ', 'ⅽ', 'ⅾ', 'ⅿ', 'ↀ', 'ↁ', 'ↂ',
|
||||
'㊀', '㊁', '㊂', '㊃', '㊄', '㊅', '㊆', '㊇', '㊈', '㊉', '㈠', '㈡', '㈢', '㈣', '㈤', '㈥', '㈦', '㈧', '㈨', '㈩',
|
||||
'𝟘', '𝟙', '𝟚', '𝟛', '𝟜', '𝟝', '𝟞', '𝟟', '𝟠', '𝟡',
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'math',
|
||||
label: '数学',
|
||||
children: [
|
||||
'+', '-', '×', '÷', '=', '~', '¬', '±', '%', '°', 'ǃ', '‰', '‱', '½', '⅓', '⅔', '¼', '¾',
|
||||
'<', '>', 'l', 'o', 'g', 'l', 'g', 'l', 'n', '⨂', '⨁', '⨄', '⨃', '⨅', '⨆', '√', '∛', '∜', '∝', '∞',
|
||||
'∟', '∠', '∡', '∢', '∧', '∨', '∩', '∪', '∫', '∬', '∭', '∮', '∯', '∰', '∱', '∲', '∳',
|
||||
'∴', '∵', '∼', '∽', '∾', '∿', '≃', '≄', '≅', '≆', '≇', '≈', '≊', '≋', '≌', '≍', '≎', '≏', '≐', '≑', '≒', '≓', '≔', '≕',
|
||||
'≤', '≥', '≦', '≧', '≨', '≩', '≪', '≫', '≺', '≻', '≼', '≽', '≾', '≿', '⊀', '⊁', '⊂', '⊃', '⊄', '⊅', '⊆', '⊇', '⊈', '⊉', '⊊', '⊋', '⊏', '⊐', '⊑', '⊒',
|
||||
'⊓', '⊔', '⊢', '⊣', '⊤', '⊥', '⊦', '⊧', '⊨', '⊩', '⊪', '⊫', '⊬', '⊭', '⊮', '⊯', '⊲', '⊳', '⊴', '⊵', '⋀', '⋁', '⋂', '⋃', '⋉', '⋊',
|
||||
'⋋', '⋌', '⟨', '⟩', '⟪', '⟫', '⟮', '⟯', '⧼', '⧽', '⦰',
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'arrow',
|
||||
label: '箭头',
|
||||
children: [
|
||||
'←', '↑', '→', '↓', '↔', '↕', '↖', '↗', '↘', '↙', '↚', '↛', '↜', '↝', '↞', '↟', '↠', '↡', '↢', '↣', '↤', '↥', '↦', '↧', '↨',
|
||||
'↫', '↬', '↭', '↮', '↯', '↰', '↱', '↲', '↳', '↴', '↵', '↶', '↷', '↸', '↹', '↺', '↻', '↼', '↽', '↾', '↿', '⇀', '⇁', '⇂', '⇃',
|
||||
'⇄', '⇅', '⇆', '⇇', '⇈', '⇉', '⇊', '⇋', '⇌', '⇍', '⇎', '⇏', '⇐', '⇑', '⇒', '⇓', '⇔', '⇕', '⇖', '⇗', '⇘', '⇙', '⇚', '⇛',
|
||||
'⇜', '⇝', '⇞', '⇟', '⇠', '⇡', '⇢', '⇣', '⇤', '⇥', '⇦', '⇧', '⇨', '⇩', '⇪', '⇫', '⇬', '⇭', '⇮', '⇯', '⇰', '⇱', '⇲', '⇳', '⇴', '⇵',
|
||||
'⇶', '⇷', '⇸', '⇹', '⇺', '⇻', '⇼', '⇽', '⇾', '⇿',
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'graph',
|
||||
label: '图形',
|
||||
children: [
|
||||
'▢', '▣', '▤', '▥', '▦', '▧', '▨', '▩', '▭', '▮', '▯', '▰', '▱', '▲', '▷', '▼', '◁',
|
||||
'◈', '◉', '◍', '◐', '◑', '◒', '◓', '◔', '◕', '◧', '◨', '◩', '◪', '◫', '◬', '◭', '◮',
|
||||
],
|
||||
},
|
||||
]
|
@ -1,6 +1,7 @@
|
||||
export type ToolbarState = 'elAnimation' | 'elStyle' | 'elPosition' | 'slideDesign' | 'slideAnimation' | 'multiPosition'
|
||||
export type ToolbarState = 'symbol' | 'elAnimation' | 'elStyle' | 'elPosition' | 'slideDesign' | 'slideAnimation' | 'multiPosition'
|
||||
|
||||
export const ToolbarStates = {
|
||||
SYMBOL: 'symbol',
|
||||
EL_ANIMATION: 'elAnimation',
|
||||
EL_STYLE: 'elStyle',
|
||||
EL_POSITION: 'elPosition',
|
||||
|
104
src/views/Editor/Toolbar/SymbolPanel.vue
Normal file
104
src/views/Editor/Toolbar/SymbolPanel.vue
Normal file
@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<div class="symbol-panel">
|
||||
<div class="tabs">
|
||||
<div
|
||||
class="tab"
|
||||
:class="{ 'active': selectedSymbolKey === item.key }"
|
||||
v-for="item in symbolPoolList"
|
||||
:key="item.key"
|
||||
@click="selectedSymbolKey = item.key"
|
||||
>{{item.label}}</div>
|
||||
</div>
|
||||
<div class="pool">
|
||||
<div class="symbol-item" v-for="(item, index) in symbolPool" :key="index" @click="selectSymbol(item)">
|
||||
<div class="symbol">{{item}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, ref } from 'vue'
|
||||
import { SYMBOL_LIST } from '@/configs/symbol'
|
||||
import emitter, { EmitterEvents } from '@/utils/emitter'
|
||||
|
||||
const symbolPoolList = SYMBOL_LIST
|
||||
|
||||
export default defineComponent({
|
||||
name: 'symbol-panel',
|
||||
setup() {
|
||||
const selectedSymbolKey = ref(symbolPoolList[0].key)
|
||||
const symbolPool = computed(() => {
|
||||
const selectedSymbol = symbolPoolList.find(item => item.key === selectedSymbolKey.value)
|
||||
return selectedSymbol?.children || []
|
||||
})
|
||||
|
||||
const selectSymbol = (item: string) => {
|
||||
emitter.emit(EmitterEvents.RICH_TEXT_COMMAND, { command: 'insert', value: item })
|
||||
}
|
||||
|
||||
return {
|
||||
symbolPoolList,
|
||||
symbolPool,
|
||||
selectedSymbolKey,
|
||||
selectSymbol,
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.symbol-panel {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.tabs {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid $borderColor;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.tab {
|
||||
padding: 6px 10px;
|
||||
border-bottom: 2px solid transparent;
|
||||
cursor: pointer;
|
||||
|
||||
&.active {
|
||||
border-bottom: 2px solid $themeColor;
|
||||
}
|
||||
}
|
||||
.pool {
|
||||
padding: 5px 12px;
|
||||
margin: 0 -12px;
|
||||
flex: 1;
|
||||
font-size: 18px;
|
||||
|
||||
@include overflow-overlay();
|
||||
@include flex-grid-layout();
|
||||
}
|
||||
.symbol-item {
|
||||
@include flex-grid-layout-children(5, 18%);
|
||||
|
||||
height: 0;
|
||||
padding-bottom: 18%;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
border: 1px solid $borderColor;
|
||||
|
||||
&:hover {
|
||||
color: $themeColor;
|
||||
}
|
||||
|
||||
.symbol {
|
||||
@include absolute-0();
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -18,6 +18,7 @@
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, watch } from 'vue'
|
||||
import { MutationTypes, useStore } from '@/store'
|
||||
import { PPTElement } from '@/types/slides'
|
||||
import { ToolbarState, ToolbarStates } from '@/types/toolbar'
|
||||
|
||||
import ElementStylePanel from './ElementStylePanel/index.vue'
|
||||
@ -26,18 +27,30 @@ import ElementAnimationPanel from './ElementAnimationPanel.vue'
|
||||
import SlideDesignPanel from './SlideDesignPanel.vue'
|
||||
import SlideAnimationPanel from './SlideAnimationPanel.vue'
|
||||
import MultiPositionPanel from './MultiPositionPanel.vue'
|
||||
import SymbolPanel from './SymbolPanel.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'toolbar',
|
||||
setup() {
|
||||
const store = useStore()
|
||||
const toolbarState = computed(() => store.state.toolbarState)
|
||||
const handleElement = computed<PPTElement>(() => store.getters.handleElement)
|
||||
|
||||
const elementTabs = [
|
||||
const elementTabs = computed(() => {
|
||||
if (handleElement.value.type === 'text') {
|
||||
return [
|
||||
{ label: '样式', value: ToolbarStates.EL_STYLE },
|
||||
{ label: '符号', value: ToolbarStates.SYMBOL },
|
||||
{ label: '位置', value: ToolbarStates.EL_POSITION },
|
||||
{ label: '动画', value: ToolbarStates.EL_ANIMATION },
|
||||
]
|
||||
}
|
||||
return [
|
||||
{ label: '样式', value: ToolbarStates.EL_STYLE },
|
||||
{ label: '位置', value: ToolbarStates.EL_POSITION },
|
||||
{ label: '动画', value: ToolbarStates.EL_ANIMATION },
|
||||
]
|
||||
})
|
||||
const slideTabs = [
|
||||
{ label: '设计', value: ToolbarStates.SLIDE_DESIGN },
|
||||
{ label: '切换', value: ToolbarStates.SLIDE_ANIMATION },
|
||||
@ -56,7 +69,7 @@ export default defineComponent({
|
||||
const currentTabs = computed(() => {
|
||||
if (!activeElementIdList.value.length) return slideTabs
|
||||
else if (activeElementIdList.value.length > 1) return multiSelectTabs
|
||||
return elementTabs
|
||||
return elementTabs.value
|
||||
})
|
||||
|
||||
watch(currentTabs, () => {
|
||||
@ -74,6 +87,7 @@ export default defineComponent({
|
||||
[ToolbarStates.SLIDE_DESIGN]: SlideDesignPanel,
|
||||
[ToolbarStates.SLIDE_ANIMATION]: SlideAnimationPanel,
|
||||
[ToolbarStates.MULTI_POSITION]: MultiPositionPanel,
|
||||
[ToolbarStates.SYMBOL]: SymbolPanel,
|
||||
}
|
||||
return panelMap[toolbarState.value] || null
|
||||
})
|
||||
|
@ -204,6 +204,9 @@ export default defineComponent({
|
||||
const { $from, $to } = editorView.state.selection
|
||||
editorView.dispatch(editorView.state.tr.removeMark($from.pos, $to.pos))
|
||||
}
|
||||
else if (item.command === 'insert' && item.value) {
|
||||
editorView.dispatch(editorView.state.tr.insertText(item.value))
|
||||
}
|
||||
}
|
||||
|
||||
editorView.focus()
|
||||
|
Loading…
x
Reference in New Issue
Block a user