From 2838426ca9031e47ce354d2fbc63f3c8eeb086df Mon Sep 17 00:00:00 2001 From: pipipi-pikachu Date: Tue, 9 Feb 2021 15:30:55 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=BD=A2=E7=8A=B6?= =?UTF-8?q?=E7=BF=BB=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + src/types/slides.ts | 7 +- .../ElementStylePanel/ImageStylePanel.vue | 40 ++--------- .../ElementStylePanel/ShapeStylePanel.vue | 3 + .../Editor/Toolbar/common/ElementFlip.vue | 70 +++++++++++++++++++ .../element/ImageElement/BaseImageElement.vue | 17 ++--- .../components/element/ImageElement/index.vue | 17 ++--- .../element/ShapeElement/BaseShapeElement.vue | 6 ++ .../components/element/ShapeElement/index.vue | 6 ++ .../element/hooks/useElementFlip.ts | 21 ++++++ 10 files changed, 130 insertions(+), 58 deletions(-) create mode 100644 src/views/Editor/Toolbar/common/ElementFlip.vue create mode 100644 src/views/components/element/hooks/useElementFlip.ts diff --git a/README.md b/README.md index ff6acbe7..4fe917f2 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ npm run serve - 边框 - 阴影 - 透明度 +- 翻转 ### 线条 - 颜色 - 宽度 diff --git a/src/types/slides.ts b/src/types/slides.ts index 78209721..0542b16f 100644 --- a/src/types/slides.ts +++ b/src/types/slides.ts @@ -41,6 +41,10 @@ export interface PPTTextElement { shadow?: PPTElementShadow; } +export interface ImageOrShapeFlip { + x?: number; + y?: number; +} export interface ImageElementFilters { 'blur'?: string; 'brightness'?: string; @@ -68,7 +72,7 @@ export interface PPTImageElement { range: [[number, number], [number, number]]; shape: 'rect' | 'roundRect' | 'ellipse' | 'triangle' | 'pentagon' | 'rhombus' | 'star'; }; - flip?: { x?: number; y?: number }; + flip?: ImageOrShapeFlip; shadow?: PPTElementShadow; } @@ -94,6 +98,7 @@ export interface PPTShapeElement { rotate?: number; outline?: PPTElementOutline; opacity?: number; + flip?: ImageOrShapeFlip; shadow?: PPTElementShadow; } diff --git a/src/views/Editor/Toolbar/ElementStylePanel/ImageStylePanel.vue b/src/views/Editor/Toolbar/ElementStylePanel/ImageStylePanel.vue index 490fe81b..a174cf9a 100644 --- a/src/views/Editor/Toolbar/ElementStylePanel/ImageStylePanel.vue +++ b/src/views/Editor/Toolbar/ElementStylePanel/ImageStylePanel.vue @@ -58,20 +58,8 @@ - - - 水平翻转 - 垂直翻转 - - + + @@ -96,6 +84,7 @@ import useHistorySnapshot from '@/hooks/useHistorySnapshot' import ElementOutline from '../common/ElementOutline.vue' import ElementShadow from '../common/ElementShadow.vue' +import ElementFlip from '../common/ElementFlip.vue' interface FilterOption { label: string; @@ -156,6 +145,7 @@ export default defineComponent({ components: { ElementOutline, ElementShadow, + ElementFlip, }, setup() { const store = useStore() @@ -164,24 +154,11 @@ export default defineComponent({ const clipPanelVisible = ref(false) - const flip = ref({ - x: 0, - y: 0, - }) - const filterOptions = ref(JSON.parse(JSON.stringify(defaultFilters))) watch(handleElement, () => { if (!handleElement.value || handleElement.value.type !== 'image') return - - if (handleElement.value.flip) { - flip.value = { - x: handleElement.value.flip.x || 0, - y: handleElement.value.flip.y || 0, - } - } - else flip.value = { x: 0, y: 0 } - + const filters = handleElement.value.filters if (filters) { filterOptions.value = defaultFilters.map(item => { @@ -194,11 +171,6 @@ export default defineComponent({ const { addHistorySnapshot } = useHistorySnapshot() - const updateImage = (props: Partial) => { - store.commit(MutationTypes.UPDATE_ELEMENT, { id: handleElement.value.id, props }) - addHistorySnapshot() - } - const updateFilter = (filter: FilterOption, value: number) => { const originFilters = handleElement.value.filters || {} const filters = { ...originFilters, [filter.key]: `${value}${filter.unit}` } @@ -337,9 +309,7 @@ export default defineComponent({ shapeClipPathOptions, ratioClipOptions, filterOptions, - flip, handleElement, - updateImage, updateFilter, clipImage, presetImageClip, diff --git a/src/views/Editor/Toolbar/ElementStylePanel/ShapeStylePanel.vue b/src/views/Editor/Toolbar/ElementStylePanel/ShapeStylePanel.vue index 5098a6e7..8c6e2068 100644 --- a/src/views/Editor/Toolbar/ElementStylePanel/ShapeStylePanel.vue +++ b/src/views/Editor/Toolbar/ElementStylePanel/ShapeStylePanel.vue @@ -68,6 +68,7 @@ + @@ -86,6 +87,7 @@ import useHistorySnapshot from '@/hooks/useHistorySnapshot' import ElementOpacity from '../common/ElementOpacity.vue' import ElementOutline from '../common/ElementOutline.vue' import ElementShadow from '../common/ElementShadow.vue' +import ElementFlip from '../common/ElementFlip.vue' import ColorButton from '../common/ColorButton.vue' export default defineComponent({ @@ -94,6 +96,7 @@ export default defineComponent({ ElementOpacity, ElementOutline, ElementShadow, + ElementFlip, ColorButton, }, setup() { diff --git a/src/views/Editor/Toolbar/common/ElementFlip.vue b/src/views/Editor/Toolbar/common/ElementFlip.vue new file mode 100644 index 00000000..12c71d31 --- /dev/null +++ b/src/views/Editor/Toolbar/common/ElementFlip.vue @@ -0,0 +1,70 @@ + + + + + \ No newline at end of file diff --git a/src/views/components/element/ImageElement/BaseImageElement.vue b/src/views/components/element/ImageElement/BaseImageElement.vue index 9392fe69..70b0b108 100644 --- a/src/views/components/element/ImageElement/BaseImageElement.vue +++ b/src/views/components/element/ImageElement/BaseImageElement.vue @@ -13,7 +13,7 @@ class="element-content" :style="{ filter: shadowStyle ? `drop-shadow(${shadowStyle})` : '', - transform: flip, + transform: flipStyle, }" > { - if (!props.elementInfo.flip) return '' - const { x, y } = props.elementInfo.flip - if (x && y) return `rotateX(${x}deg) rotateY(${y}deg)` - else if (x) return `rotateX(${x}deg)` - else if (y) return `rotateY(${y}deg)` - return '' - }) - const shadow = computed(() => props.elementInfo.shadow) const { shadowStyle } = useElementShadow(shadow) + const flip = computed(() => props.elementInfo.flip) + const { flipStyle } = useElementFlip(flip) + return { imgPosition, clipShape, filter, - flip, + flipStyle, shadowStyle, } }, diff --git a/src/views/components/element/ImageElement/index.vue b/src/views/components/element/ImageElement/index.vue index cd0eb6f3..fb8eb984 100644 --- a/src/views/components/element/ImageElement/index.vue +++ b/src/views/components/element/ImageElement/index.vue @@ -28,7 +28,7 @@ v-contextmenu="contextmenus" :style="{ filter: shadowStyle ? `drop-shadow(${shadowStyle})` : '', - transform: flip, + transform: flipStyle, }" > props.elementInfo.shadow) const { shadowStyle } = useElementShadow(shadow) + const flip = computed(() => props.elementInfo.flip) + const { flipStyle } = useElementFlip(flip) + const handleSelectElement = (e: MouseEvent) => { if (props.elementInfo.lock) return e.stopPropagation() @@ -159,15 +163,6 @@ export default defineComponent({ return filter }) - const flip = computed(() => { - if (!props.elementInfo.flip) return '' - const { x, y } = props.elementInfo.flip - if (x && y) return `rotateX(${x}deg) rotateY(${y}deg)` - else if (x) return `rotateX(${x}deg)` - else if (y) return `rotateY(${y}deg)` - return '' - }) - const clip = (data: ImageClipedEmitData) => { store.commit(MutationTypes.SET_CLIPING_IMAGE_ELEMENT_ID, '') @@ -195,7 +190,7 @@ export default defineComponent({ clipShape, imgPosition, filter, - flip, + flipStyle, } }, }) diff --git a/src/views/components/element/ShapeElement/BaseShapeElement.vue b/src/views/components/element/ShapeElement/BaseShapeElement.vue index 0ffcca93..f6fb3c31 100644 --- a/src/views/components/element/ShapeElement/BaseShapeElement.vue +++ b/src/views/components/element/ShapeElement/BaseShapeElement.vue @@ -14,6 +14,7 @@ :style="{ opacity: elementInfo.opacity, filter: shadowStyle ? `drop-shadow(${shadowStyle})` : '', + transform: flipStyle, }" > props.elementInfo.shadow) const { shadowStyle } = useElementShadow(shadow) + const flip = computed(() => props.elementInfo.flip) + const { flipStyle } = useElementFlip(flip) + return { shadowStyle, outlineWidth, outlineStyle, outlineColor, + flipStyle, } }, }) diff --git a/src/views/components/element/ShapeElement/index.vue b/src/views/components/element/ShapeElement/index.vue index 9258bb2d..72c64a8f 100644 --- a/src/views/components/element/ShapeElement/index.vue +++ b/src/views/components/element/ShapeElement/index.vue @@ -17,6 +17,7 @@ :style="{ opacity: elementInfo.opacity, filter: shadowStyle ? `drop-shadow(${shadowStyle})` : '', + transform: flipStyle, }" > props.elementInfo.shadow) const { shadowStyle } = useElementShadow(shadow) + const flip = computed(() => props.elementInfo.flip) + const { flipStyle } = useElementFlip(flip) + return { handleSelectElement, shadowStyle, outlineWidth, outlineStyle, outlineColor, + flipStyle, } }, }) diff --git a/src/views/components/element/hooks/useElementFlip.ts b/src/views/components/element/hooks/useElementFlip.ts new file mode 100644 index 00000000..0e9826bc --- /dev/null +++ b/src/views/components/element/hooks/useElementFlip.ts @@ -0,0 +1,21 @@ +import { ref, Ref, watchEffect } from 'vue' +import { ImageOrShapeFlip } from '@/types/slides' + +export default (flip: Ref) => { + const flipStyle = ref('') + + watchEffect(() => { + if (flip.value) { + const { x, y } = flip.value + if (x && y) flipStyle.value = `rotateX(${x}deg) rotateY(${y}deg)` + else if (x) flipStyle.value = `rotateX(${x}deg)` + else if (y) flipStyle.value = `rotateY(${y}deg)` + else flipStyle.value = '' + } + else flipStyle.value = '' + }) + + return { + flipStyle, + } +} \ No newline at end of file