2021-01-26 22:52:51 +08:00

164 lines
4.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="shape-style-panel">
<div class="row">
<Select
style="flex: 10;"
:value="fillType"
@change="value => updateFillType(value)"
>
<SelectOption value="fill">纯色填充</SelectOption>
<SelectOption value="gradient">渐变填充</SelectOption>
</Select>
<div style="flex: 1;"></div>
<Popover trigger="click" v-if="fillType === 'fill'">
<template #content>
<ColorPicker
:modelValue="fill"
@update:modelValue="value => updateFill(value)"
/>
</template>
<ColorButton :color="fill" style="flex: 10;" />
</Popover>
<Select
style="flex: 10;"
:value="gradient.type"
@change="value => updateGradient({ type: value })"
v-else
>
<SelectOption value="linear">线性渐变</SelectOption>
<SelectOption value="radial">径向渐变</SelectOption>
</Select>
</div>
<template v-if="fillType === 'gradient'">
<div class="row">
<div style="flex: 2;">起点颜色</div>
<Popover trigger="click">
<template #content>
<ColorPicker
:modelValue="gradient.color[0]"
@update:modelValue="value => updateGradient({ color: [value, gradient.color[1]] })"
/>
</template>
<ColorButton :color="gradient.color[0]" style="flex: 3;" />
</Popover>
</div>
<div class="row">
<div style="flex: 2;">终点颜色</div>
<Popover trigger="click">
<template #content>
<ColorPicker
:modelValue="gradient.color[1]"
@update:modelValue="value => updateGradient({ color: [gradient.color[0], value] })"
/>
</template>
<ColorButton :color="gradient.color[1]" style="flex: 3;" />
</Popover>
</div>
<div class="row" v-if="gradient.type === 'linear'">
<div style="flex: 2;">渐变角度</div>
<Slider
:min="0"
:max="360"
:step="15"
:value="gradient.rotate"
style="flex: 3;"
@change="value => updateGradient({ rotate: value })"
/>
</div>
</template>
<Divider />
<ElementOutline />
<Divider />
<ElementShadow />
<Divider />
<ElementOpacity />
</div>
</template>
<script lang="ts">
import { computed, defineComponent, ref, watch } from 'vue'
import { useStore } from 'vuex'
import { MutationTypes, State } from '@/store'
import { PPTShapeElement, ShapeGradient } from '@/types/slides'
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
import ElementOpacity from '../common/ElementOpacity.vue'
import ElementOutline from '../common/ElementOutline.vue'
import ElementShadow from '../common/ElementShadow.vue'
import ColorButton from '../common/ColorButton.vue'
export default defineComponent({
name: 'shape-style-panel',
components: {
ElementOpacity,
ElementOutline,
ElementShadow,
ColorButton,
},
setup() {
const store = useStore<State>()
const handleElement = computed<PPTShapeElement>(() => store.getters.handleElement)
const fill = ref<string>()
const gradient = ref<ShapeGradient>()
const fillType = ref('fill')
watch(handleElement, () => {
if(!handleElement.value || handleElement.value.type !== 'shape') return
fill.value = handleElement.value.fill || '#000'
gradient.value = handleElement.value.gradient || { type: 'linear', rotate: 0, color: [fill.value, '#fff'] }
fillType.value = handleElement.value.gradient ? 'gradient' : 'fill'
}, { deep: true, immediate: true })
const { addHistorySnapshot } = useHistorySnapshot()
const updateFillType = (type: 'gradient' | 'fill') => {
if(type === 'fill') {
store.commit(MutationTypes.REMOVE_ELEMENT_PROPS, {
id: handleElement.value.id,
propName: 'gradient',
})
}
else {
const props = { gradient: gradient.value }
store.commit(MutationTypes.UPDATE_ELEMENT, { id: handleElement.value.id, props })
}
addHistorySnapshot()
}
const updateGradient = (gradientProps: Partial<ShapeGradient>) => {
const props = { gradient: { ...gradient.value, ...gradientProps } }
store.commit(MutationTypes.UPDATE_ELEMENT, { id: handleElement.value.id, props })
addHistorySnapshot()
}
const updateFill = (value: string) => {
const props = { fill: value }
store.commit(MutationTypes.UPDATE_ELEMENT, { id: handleElement.value.id, props })
addHistorySnapshot()
}
return {
fill,
gradient,
fillType,
updateFillType,
updateFill,
updateGradient,
}
},
})
</script>
<style lang="scss" scoped>
.row {
width: 100%;
display: flex;
align-items: center;
margin-bottom: 10px;
}
</style>