File size: 3,970 Bytes
89ce340 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
<template>
<div class="element-outline">
<div class="row" v-if="!fixed">
<div style="width: 40%;">启用边框:</div>
<div class="switch-wrapper" style="width: 60%;">
<Switch
:value="hasOutline"
@update:value="value => toggleOutline(value)"
/>
</div>
</div>
<template v-if="hasOutline && outline">
<div class="row">
<div style="width: 40%;">边框样式:</div>
<SelectCustom style="width: 60%;">
<template #options>
<div class="option" v-for="item in lineStyleOptions" :key="item" @click="updateOutline({ style: item })">
<SVGLine :type="item" />
</div>
</template>
<template #label>
<SVGLine :type="outline.style" />
</template>
</SelectCustom>
</div>
<div class="row">
<div style="width: 40%;">边框颜色:</div>
<Popover trigger="click" style="width: 60%;">
<template #content>
<ColorPicker
:modelValue="outline.color"
@update:modelValue="value => updateOutline({ color: value })"
/>
</template>
<ColorButton :color="outline.color || '#000'" />
</Popover>
</div>
<div class="row">
<div style="width: 40%;">边框粗细:</div>
<NumberInput
:value="outline.width || 0"
@update:value="value => updateOutline({ width: value })"
style="width: 60%;"
/>
</div>
</template>
</div>
</template>
<script lang="ts" setup>
import { ref, watch } from 'vue'
import { storeToRefs } from 'pinia'
import { useMainStore, useSlidesStore } from '@/store'
import type { LineStyleType, PPTElementOutline } from '@/types/slides'
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
import SVGLine from '../common/SVGLine.vue'
import ColorButton from '@/components/ColorButton.vue'
import ColorPicker from '@/components/ColorPicker/index.vue'
import Switch from '@/components/Switch.vue'
import NumberInput from '@/components/NumberInput.vue'
import SelectCustom from '@/components/SelectCustom.vue'
import Popover from '@/components/Popover.vue'
withDefaults(defineProps<{
fixed?: boolean
}>(), {
fixed: false,
})
const slidesStore = useSlidesStore()
const { theme } = storeToRefs(slidesStore)
const { handleElement } = storeToRefs(useMainStore())
const outline = ref<PPTElementOutline>()
const hasOutline = ref(false)
const lineStyleOptions = ref<LineStyleType[]>(['solid', 'dashed', 'dotted'])
watch(handleElement, () => {
if (!handleElement.value) return
outline.value = 'outline' in handleElement.value ? handleElement.value.outline : undefined
hasOutline.value = !!outline.value
}, { deep: true, immediate: true })
const { addHistorySnapshot } = useHistorySnapshot()
const updateOutline = (outlineProps: Partial<PPTElementOutline>) => {
if (!handleElement.value) return
const props = { outline: { ...outline.value, ...outlineProps } }
slidesStore.updateElement({ id: handleElement.value.id, props })
addHistorySnapshot()
}
const toggleOutline = (checked: boolean) => {
if (!handleElement.value) return
if (checked) {
const _outline: PPTElementOutline = theme.value.outline
slidesStore.updateElement({ id: handleElement.value.id, props: { outline: _outline } })
}
else {
slidesStore.removeElementProps({ id: handleElement.value.id, propName: 'outline' })
}
addHistorySnapshot()
}
</script>
<style lang="scss" scoped>
.row {
width: 100%;
height: 30px;
display: flex;
align-items: center;
margin-bottom: 10px;
}
.switch-wrapper {
text-align: right;
}
.option {
height: 32px;
padding: 0 5px;
border-radius: $borderRadius;
&:not(.selected):hover {
background-color: rgba($color: $themeColor, $alpha: .05);
cursor: pointer;
}
&.selected {
color: $themeColor;
font-weight: 700;
}
}
</style> |