This commit is contained in:
pipipi-pikachu 2021-01-11 21:30:55 +08:00
parent f100f2cd9e
commit 653bf033a7
3 changed files with 540 additions and 560 deletions

View File

@ -1,24 +1,5 @@
<template> <template>
<div <div class="image-element-operate" :class="{ 'cliping': isCliping }">
class="clip-wrapper"
:style="{
width: elementInfo.width + 'px',
height: elementInfo.height + 'px',
}"
v-if="isCliping"
>
<ImageClipHandler
:src="elementInfo.src"
:clipData="elementInfo.clip"
:width="elementInfo.width"
:height="elementInfo.height"
:top="elementInfo.top"
:left="elementInfo.left"
:clipPath="clipShape.style"
@clip="range => clip(range)"
/>
</div>
<div class="image-element-operate" v-else>
<BorderLine <BorderLine
class="operate-border-line" class="operate-border-line"
v-for="line in borderLines" v-for="line in borderLines"
@ -47,16 +28,14 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, PropType } from 'vue' import { computed, defineComponent, PropType } from 'vue'
import { useStore } from 'vuex' import { useStore } from 'vuex'
import { MutationTypes, State } from '@/store' import { State } from '@/store'
import { PPTImageElement } from '@/types/slides' import { PPTImageElement } from '@/types/slides'
import { OperateResizeHandler, ImageClipedEmitData } from '@/types/edit' import { OperateResizeHandler } from '@/types/edit'
import { CLIPPATHS, ClipPathTypes } from '@/configs/imageClip'
import useCommonOperate from '../hooks/useCommonOperate' import useCommonOperate from '../hooks/useCommonOperate'
import RotateHandler from './RotateHandler.vue' import RotateHandler from './RotateHandler.vue'
import ResizeHandler from './ResizeHandler.vue' import ResizeHandler from './ResizeHandler.vue'
import BorderLine from './BorderLine.vue' import BorderLine from './BorderLine.vue'
import ImageClipHandler from './ImageClipHandler.vue'
export default defineComponent({ export default defineComponent({
name: 'image-element-operate', name: 'image-element-operate',
@ -65,7 +44,6 @@ export default defineComponent({
RotateHandler, RotateHandler,
ResizeHandler, ResizeHandler,
BorderLine, BorderLine,
ImageClipHandler,
}, },
props: { props: {
elementInfo: { elementInfo: {
@ -93,52 +71,24 @@ export default defineComponent({
const store = useStore<State>() const store = useStore<State>()
const canvasScale = computed(() => store.state.canvasScale) const canvasScale = computed(() => store.state.canvasScale)
const clipingImageElementId = computed(() => store.state.clipingImageElementId) const clipingImageElementId = computed(() => store.state.clipingImageElementId)
const isCliping = computed(() => clipingImageElementId.value === props.elementInfo.id)
const scaleWidth = computed(() => props.elementInfo.width * canvasScale.value) const scaleWidth = computed(() => props.elementInfo.width * canvasScale.value)
const scaleHeight = computed(() => props.elementInfo.height * canvasScale.value) const scaleHeight = computed(() => props.elementInfo.height * canvasScale.value)
const { resizeHandlers, borderLines } = useCommonOperate(scaleWidth, scaleHeight) const { resizeHandlers, borderLines } = useCommonOperate(scaleWidth, scaleHeight)
const clipShape = computed(() => {
if(!props.elementInfo || !props.elementInfo.clip) return CLIPPATHS.rect
const shape = props.elementInfo.clip.shape || ClipPathTypes.RECT
return CLIPPATHS[shape]
})
const isCliping = computed(() => clipingImageElementId.value === props.elementInfo.id)
const clip = (data: ImageClipedEmitData) => {
store.commit(MutationTypes.SET_CLIPING_IMAGE_ELEMENT_ID, '')
if(!data) return
const { range, position } = data
const originClip = props.elementInfo.clip || {}
const _props = {
clip: { ...originClip, range },
left: props.elementInfo.left + position.left,
top: props.elementInfo.top + position.top,
width: props.elementInfo.width + position.width,
height: props.elementInfo.height + position.height,
}
console.log(_props)
}
return { return {
clipShape, isCliping,
scaleWidth, scaleWidth,
resizeHandlers, resizeHandlers,
borderLines, borderLines,
isCliping,
clip,
} }
}, },
}) })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.clip-wrapper { .image-element-operate.cliping {
position: relative; visibility: hidden;
} }
</style> </style>

View File

@ -2,7 +2,7 @@
<div <div
class="image-clip-handler" class="image-clip-handler"
:style="clipWrapperPositionStyle" :style="clipWrapperPositionStyle"
v-click-outside="clip" v-click-outside="handleClip"
> >
<img <img
class="bottom-img" class="bottom-img"
@ -171,8 +171,10 @@ export default defineComponent({
clipWrapperPositionStyle.left = -left + '%' clipWrapperPositionStyle.left = -left + '%'
} }
const clip = () => { const handleClip = () => {
if(isSettingClipRange.value || !currentRange.value) { if(isSettingClipRange.value) return
if(!currentRange.value) {
emit('clip', null) emit('clip', null)
return return
} }
@ -195,7 +197,7 @@ export default defineComponent({
const keyboardClip = (e: KeyboardEvent) => { const keyboardClip = (e: KeyboardEvent) => {
const key = e.key.toUpperCase() const key = e.key.toUpperCase()
if(key === KEYS.ENTER) clip() if(key === KEYS.ENTER) handleClip()
} }
onMounted(() => { onMounted(() => {
@ -406,7 +408,7 @@ export default defineComponent({
bottomImgPositionStyle, bottomImgPositionStyle,
topImgWrapperPositionStyle, topImgWrapperPositionStyle,
topImgPositionStyle, topImgPositionStyle,
clip, handleClip,
moveClipRange, moveClipRange,
scaleClipRange, scaleClipRange,
} }

View File

@ -1,10 +1,7 @@
<template> <template>
<div <div
class="editable-element-image" class="editable-element-image"
:class="{ :class="{ 'lock': elementInfo.lock }"
'lock': elementInfo.lock,
'cliping': clipingImageElementId === elementInfo.id,
}"
:style="{ :style="{
top: elementInfo.top + 'px', top: elementInfo.top + 'px',
left: elementInfo.left + 'px', left: elementInfo.left + 'px',
@ -14,8 +11,20 @@
}" }"
@mousedown="$event => handleSelectElement($event)" @mousedown="$event => handleSelectElement($event)"
> >
<ImageClipHandler
v-if="isCliping"
:src="elementInfo.src"
:clipData="elementInfo.clip"
:width="elementInfo.width"
:height="elementInfo.height"
:top="elementInfo.top"
:left="elementInfo.left"
:clipPath="clipShape.style"
@clip="range => clip(range)"
/>
<div <div
class="element-content" class="element-content"
v-else
v-contextmenu="contextmenus" v-contextmenu="contextmenus"
:style="{ :style="{
filter: shadowStyle ? `drop-shadow(${shadowStyle})` : '', filter: shadowStyle ? `drop-shadow(${shadowStyle})` : '',
@ -64,7 +73,7 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, PropType } from 'vue' import { computed, defineComponent, PropType } from 'vue'
import { useStore } from 'vuex' import { useStore } from 'vuex'
import { State } from '@/store' import { MutationTypes, State } from '@/store'
import { PPTImageElement } from '@/types/slides' import { PPTImageElement } from '@/types/slides'
import { ContextmenuItem } from '@/components/Contextmenu/types' import { ContextmenuItem } from '@/components/Contextmenu/types'
import { CLIPPATHS, ClipPathTypes } from '@/configs/imageClip' import { CLIPPATHS, ClipPathTypes } from '@/configs/imageClip'
@ -73,7 +82,8 @@ import useElementShadow from '@/views/components/element/hooks/useElementShadow'
import ImageRectOutline from './ImageRectOutline.vue' import ImageRectOutline from './ImageRectOutline.vue'
import ImageEllipseOutline from './ImageEllipseOutline.vue' import ImageEllipseOutline from './ImageEllipseOutline.vue'
import ImagePolygonOutline from './ImagePolygonOutline.vue' import ImagePolygonOutline from './ImagePolygonOutline.vue'
import ImageClipHandler from './ImageClipHandler.vue'
import { ImageClipedEmitData } from '@/types/edit'
export default defineComponent({ export default defineComponent({
name: 'editable-element-image', name: 'editable-element-image',
@ -81,6 +91,7 @@ export default defineComponent({
ImageRectOutline, ImageRectOutline,
ImageEllipseOutline, ImageEllipseOutline,
ImagePolygonOutline, ImagePolygonOutline,
ImageClipHandler,
}, },
props: { props: {
elementInfo: { elementInfo: {
@ -98,6 +109,7 @@ export default defineComponent({
setup(props) { setup(props) {
const store = useStore<State>() const store = useStore<State>()
const clipingImageElementId = computed(() => store.state.clipingImageElementId) const clipingImageElementId = computed(() => store.state.clipingImageElementId)
const isCliping = computed(() => clipingImageElementId.value === props.elementInfo.id)
const shadow = computed(() => props.elementInfo.shadow) const shadow = computed(() => props.elementInfo.shadow)
const { shadowStyle } = useElementShadow(shadow) const { shadowStyle } = useElementShadow(shadow)
@ -157,7 +169,27 @@ export default defineComponent({
return '' return ''
}) })
const clip = (data: ImageClipedEmitData) => {
store.commit(MutationTypes.SET_CLIPING_IMAGE_ELEMENT_ID, '')
if(!data) return
const { range, position } = data
const originClip = props.elementInfo.clip || {}
const _props = {
clip: { ...originClip, range },
left: props.elementInfo.left + position.left,
top: props.elementInfo.top + position.top,
width: props.elementInfo.width + position.width,
height: props.elementInfo.height + position.height,
}
store.commit(MutationTypes.UPDATE_ELEMENT, { id: props.elementInfo.id, props: _props })
}
return { return {
isCliping,
clip,
clipingImageElementId, clipingImageElementId,
shadowStyle, shadowStyle,
handleSelectElement, handleSelectElement,
@ -177,10 +209,6 @@ export default defineComponent({
&.lock .element-content { &.lock .element-content {
cursor: default; cursor: default;
} }
&.cliping {
visibility: hidden;
}
} }
.element-content { .element-content {