mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
update
This commit is contained in:
parent
f100f2cd9e
commit
653bf033a7
@ -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>
|
@ -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,
|
||||||
}
|
}
|
@ -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 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user