mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
refactor: 为线条以外的元素都补充旋转角度属性
This commit is contained in:
parent
f7e3c6cef1
commit
8a8a597208
@ -90,6 +90,7 @@ export default () => {
|
||||
top: 81.25,
|
||||
width: 400,
|
||||
height: 400,
|
||||
rotate: 0,
|
||||
themeColor: [themeColor.value],
|
||||
gridColor: fontColor.value,
|
||||
data: {
|
||||
@ -135,6 +136,7 @@ export default () => {
|
||||
width,
|
||||
height,
|
||||
colWidths,
|
||||
rotate: 0,
|
||||
data,
|
||||
left: (VIEWPORT_SIZE - width) / 2,
|
||||
top: (VIEWPORT_SIZE * viewportRatio.value - height) / 2,
|
||||
@ -233,6 +235,7 @@ export default () => {
|
||||
id: createRandomCode(),
|
||||
width: data.w,
|
||||
height: data.h,
|
||||
rotate: 0,
|
||||
left: (VIEWPORT_SIZE - data.w) / 2,
|
||||
top: (VIEWPORT_SIZE * viewportRatio.value - data.h) / 2,
|
||||
path: data.path,
|
||||
@ -254,6 +257,7 @@ export default () => {
|
||||
id: createRandomCode(),
|
||||
width: 500,
|
||||
height: 300,
|
||||
rotate: 0,
|
||||
left: (VIEWPORT_SIZE - 500) / 2,
|
||||
top: (VIEWPORT_SIZE * viewportRatio.value - 300) / 2,
|
||||
src,
|
||||
|
@ -62,6 +62,8 @@ export interface PPTElementOutline {
|
||||
*
|
||||
* height: 元素高度
|
||||
*
|
||||
* rotate: 旋转角度
|
||||
*
|
||||
* link?: 超链接地址
|
||||
*/
|
||||
interface PPTBaseElement {
|
||||
@ -72,6 +74,7 @@ interface PPTBaseElement {
|
||||
groupId?: string;
|
||||
width: number;
|
||||
height: number;
|
||||
rotate: number;
|
||||
link?: string;
|
||||
}
|
||||
|
||||
@ -83,8 +86,6 @@ interface PPTBaseElement {
|
||||
*
|
||||
* content: 文本内容(HTML字符串)
|
||||
*
|
||||
* rotate: 旋转角度
|
||||
*
|
||||
* defaultFontName: 默认字体(会被文本内容中的HTML内联样式覆盖)
|
||||
*
|
||||
* defaultColor: 默认颜色(会被文本内容中的HTML内联样式覆盖)
|
||||
@ -104,7 +105,6 @@ interface PPTBaseElement {
|
||||
export interface PPTTextElement extends PPTBaseElement {
|
||||
type: 'text';
|
||||
content: string;
|
||||
rotate: number;
|
||||
defaultFontName: string;
|
||||
defaultColor: string;
|
||||
outline?: PPTElementOutline;
|
||||
@ -178,8 +178,6 @@ export interface ImageElementClip {
|
||||
*
|
||||
* src: 图片地址
|
||||
*
|
||||
* rotate: 旋转角度
|
||||
*
|
||||
* outline?: 边框
|
||||
*
|
||||
* filters?: 图片滤镜
|
||||
@ -196,7 +194,6 @@ export interface PPTImageElement extends PPTBaseElement {
|
||||
type: 'image';
|
||||
fixedRatio: boolean;
|
||||
src: string;
|
||||
rotate: number;
|
||||
outline?: PPTElementOutline;
|
||||
filters?: ImageElementFilters;
|
||||
clip?: ImageElementClip;
|
||||
@ -254,8 +251,6 @@ export interface ShapeText {
|
||||
*
|
||||
* gradient?: 渐变,该属性存在时将优先作为填充
|
||||
*
|
||||
* rotate: 旋转角度
|
||||
*
|
||||
* outline?: 边框
|
||||
*
|
||||
* opacity?: 不透明度
|
||||
@ -277,7 +272,6 @@ export interface PPTShapeElement extends PPTBaseElement {
|
||||
fixedRatio: boolean;
|
||||
fill: string;
|
||||
gradient?: ShapeGradient;
|
||||
rotate: number;
|
||||
outline?: PPTElementOutline;
|
||||
opacity?: number;
|
||||
flipH?: boolean;
|
||||
@ -311,7 +305,7 @@ export type LinePoint = '' | 'arrow' | 'dot'
|
||||
*
|
||||
* curve?: 曲线中点位置([x, y])
|
||||
*/
|
||||
export interface PPTLineElement extends Omit<PPTBaseElement, 'height'> {
|
||||
export interface PPTLineElement extends Omit<PPTBaseElement, 'height' | 'rotate'> {
|
||||
type: 'line';
|
||||
start: [number, number];
|
||||
end: [number, number];
|
||||
|
@ -7,15 +7,21 @@
|
||||
:type="line.type"
|
||||
:style="line.style"
|
||||
/>
|
||||
<template v-if="!elementInfo.lock && (isActiveGroupElement || !isMultiSelect)">
|
||||
<template v-if="handlerVisible">
|
||||
<ResizeHandler
|
||||
class="operate-resize-handler"
|
||||
v-for="point in resizeHandlers"
|
||||
:key="point.direction"
|
||||
:type="point.direction"
|
||||
:rotate="elementInfo.rotate"
|
||||
:style="point.style"
|
||||
@mousedown.stop="$event => scaleElement($event, elementInfo, point.direction)"
|
||||
/>
|
||||
<RotateHandler
|
||||
class="operate-rotate-handler"
|
||||
:style="{ left: scaleWidth / 2 + 'px' }"
|
||||
@mousedown.stop="rotateElement(elementInfo)"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
@ -28,31 +34,35 @@ import { PPTShapeElement, PPTVideoElement, PPTLatexElement } from '@/types/slide
|
||||
import { OperateResizeHandler } from '@/types/edit'
|
||||
import useCommonOperate from '../hooks/useCommonOperate'
|
||||
|
||||
import RotateHandler from './RotateHandler.vue'
|
||||
import ResizeHandler from './ResizeHandler.vue'
|
||||
import BorderLine from './BorderLine.vue'
|
||||
|
||||
type PPTElement = PPTShapeElement | PPTVideoElement | PPTLatexElement
|
||||
|
||||
export default defineComponent({
|
||||
name: 'common-element-operate',
|
||||
inheritAttrs: false,
|
||||
components: {
|
||||
RotateHandler,
|
||||
ResizeHandler,
|
||||
BorderLine,
|
||||
},
|
||||
props: {
|
||||
elementInfo: {
|
||||
type: Object as PropType<PPTShapeElement | PPTVideoElement | PPTLatexElement>,
|
||||
type: Object as PropType<PPTElement>,
|
||||
required: true,
|
||||
},
|
||||
isActiveGroupElement: {
|
||||
handlerVisible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
isMultiSelect: {
|
||||
type: Boolean,
|
||||
rotateElement: {
|
||||
type: Function as PropType<(element: PPTElement) => void>,
|
||||
required: true,
|
||||
},
|
||||
scaleElement: {
|
||||
type: Function as PropType<(e: MouseEvent, element: PPTShapeElement, command: OperateResizeHandler) => void>,
|
||||
type: Function as PropType<(e: MouseEvent, element: PPTElement, command: OperateResizeHandler) => void>,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
@ -7,7 +7,7 @@
|
||||
:type="line.type"
|
||||
:style="line.style"
|
||||
/>
|
||||
<template v-if="!elementInfo.lock && (isActiveGroupElement || !isMultiSelect)">
|
||||
<template v-if="handlerVisible">
|
||||
<ResizeHandler
|
||||
class="operate-resize-handler"
|
||||
v-for="point in resizeHandlers"
|
||||
@ -50,11 +50,7 @@ export default defineComponent({
|
||||
type: Object as PropType<PPTImageElement>,
|
||||
required: true,
|
||||
},
|
||||
isActiveGroupElement: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
isMultiSelect: {
|
||||
handlerVisible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="text-element-operate">
|
||||
<template v-if="!elementInfo.lock && (isActiveGroupElement || !isMultiSelect)">
|
||||
<template v-if="handlerVisible">
|
||||
<ResizeHandler
|
||||
class="operate-resize-handler"
|
||||
v-for="point in resizeHandlers"
|
||||
@ -33,11 +33,7 @@ export default defineComponent({
|
||||
type: Object as PropType<PPTLineElement>,
|
||||
required: true,
|
||||
},
|
||||
isActiveGroupElement: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
isMultiSelect: {
|
||||
handlerVisible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
|
@ -7,7 +7,7 @@
|
||||
:type="line.type"
|
||||
:style="line.style"
|
||||
/>
|
||||
<template v-if="!elementInfo.lock && (isActiveGroupElement || !isMultiSelect)">
|
||||
<template v-if="handlerVisible">
|
||||
<ResizeHandler
|
||||
class="operate-resize-handler"
|
||||
v-for="point in resizeHandlers"
|
||||
@ -51,11 +51,7 @@ export default defineComponent({
|
||||
type: Object as PropType<PPTShapeElement>,
|
||||
required: true,
|
||||
},
|
||||
isActiveGroupElement: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
isMultiSelect: {
|
||||
handlerVisible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
|
@ -7,15 +7,21 @@
|
||||
:type="line.type"
|
||||
:style="line.style"
|
||||
/>
|
||||
<template v-if="!elementInfo.lock && (isActiveGroupElement || !isMultiSelect)">
|
||||
<template v-if="handlerVisible">
|
||||
<ResizeHandler
|
||||
class="operate-resize-handler"
|
||||
v-for="point in textElementResizeHandlers"
|
||||
:key="point.direction"
|
||||
:type="point.direction"
|
||||
:rotate="elementInfo.rotate"
|
||||
:style="point.style"
|
||||
@mousedown.stop="$event => scaleElement($event, elementInfo, point.direction)"
|
||||
/>
|
||||
<RotateHandler
|
||||
class="operate-rotate-handler"
|
||||
:style="{ left: scaleWidth / 2 + 'px' }"
|
||||
@mousedown.stop="rotateElement(elementInfo)"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
@ -28,6 +34,7 @@ import { PPTTableElement } from '@/types/slides'
|
||||
import { OperateResizeHandler } from '@/types/edit'
|
||||
import useCommonOperate from '../hooks/useCommonOperate'
|
||||
|
||||
import RotateHandler from './RotateHandler.vue'
|
||||
import ResizeHandler from './ResizeHandler.vue'
|
||||
import BorderLine from './BorderLine.vue'
|
||||
|
||||
@ -35,6 +42,7 @@ export default defineComponent({
|
||||
name: 'table-element-operate',
|
||||
inheritAttrs: false,
|
||||
components: {
|
||||
RotateHandler,
|
||||
ResizeHandler,
|
||||
BorderLine,
|
||||
},
|
||||
@ -43,12 +51,12 @@ export default defineComponent({
|
||||
type: Object as PropType<PPTTableElement>,
|
||||
required: true,
|
||||
},
|
||||
isActiveGroupElement: {
|
||||
handlerVisible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
isMultiSelect: {
|
||||
type: Boolean,
|
||||
rotateElement: {
|
||||
type: Function as PropType<(element: PPTTableElement) => void>,
|
||||
required: true,
|
||||
},
|
||||
scaleElement: {
|
||||
|
@ -7,7 +7,7 @@
|
||||
:type="line.type"
|
||||
:style="line.style"
|
||||
/>
|
||||
<template v-if="!elementInfo.lock && (isActiveGroupElement || !isMultiSelect)">
|
||||
<template v-if="handlerVisible">
|
||||
<ResizeHandler
|
||||
class="operate-resize-handler"
|
||||
v-for="point in textElementResizeHandlers"
|
||||
@ -51,11 +51,7 @@ export default defineComponent({
|
||||
type: Object as PropType<PPTTextElement>,
|
||||
required: true,
|
||||
},
|
||||
isActiveGroupElement: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
isMultiSelect: {
|
||||
handlerVisible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
|
@ -13,8 +13,7 @@
|
||||
v-if="isSelected"
|
||||
:is="currentOperateComponent"
|
||||
:elementInfo="elementInfo"
|
||||
:isActiveGroupElement="isActiveGroupElement"
|
||||
:isMultiSelect="isMultiSelect"
|
||||
:handlerVisible="!elementInfo.lock && (isActiveGroupElement || !isMultiSelect)"
|
||||
:rotateElement="rotateElement"
|
||||
:scaleElement="scaleElement"
|
||||
:dragLineElement="dragLineElement"
|
||||
|
@ -29,7 +29,7 @@ export default (elementList: Ref<PPTElement[]>) => {
|
||||
// 获取所有线条以外的未旋转的元素的8个缩放点作为吸附位置
|
||||
for (let i = 0; i < elementList.value.length; i++) {
|
||||
const _element = elementList.value[i]
|
||||
if (_element.type === 'line' || ('rotate' in _element && _element.rotate)) continue
|
||||
if (_element.type === 'line' || _element.rotate) continue
|
||||
|
||||
const left = _element.left
|
||||
const top = _element.top
|
||||
|
@ -99,7 +99,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-if="['text', 'image', 'shape'].includes(handleElement.type)">
|
||||
<template v-if="handleElement.type !== 'line'">
|
||||
<Divider />
|
||||
|
||||
<div class="row">
|
||||
|
@ -6,6 +6,10 @@
|
||||
width: elementInfo.width + 'px',
|
||||
height: elementInfo.height + 'px',
|
||||
}"
|
||||
>
|
||||
<div
|
||||
class="rotate-wrapper"
|
||||
:style="{ transform: `rotate(${elementInfo.rotate}deg)` }"
|
||||
>
|
||||
<div
|
||||
class="element-content"
|
||||
@ -32,6 +36,7 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@ -70,6 +75,10 @@ export default defineComponent({
|
||||
.base-element-chart {
|
||||
position: absolute;
|
||||
}
|
||||
.rotate-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.element-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -7,6 +7,10 @@
|
||||
width: elementInfo.width + 'px',
|
||||
height: elementInfo.height + 'px',
|
||||
}"
|
||||
>
|
||||
<div
|
||||
class="rotate-wrapper"
|
||||
:style="{ transform: `rotate(${elementInfo.rotate}deg)` }"
|
||||
>
|
||||
<div
|
||||
class="element-content"
|
||||
@ -35,6 +39,7 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@ -93,7 +98,10 @@ export default defineComponent({
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
.rotate-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.element-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -6,6 +6,10 @@
|
||||
left: elementInfo.left + 'px',
|
||||
width: elementInfo.width + 'px',
|
||||
}"
|
||||
>
|
||||
<div
|
||||
class="rotate-wrapper"
|
||||
:style="{ transform: `rotate(${elementInfo.rotate}deg)` }"
|
||||
>
|
||||
<div class="element-content">
|
||||
<StaticTable
|
||||
@ -17,6 +21,7 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@ -43,7 +48,10 @@ export default defineComponent({
|
||||
.base-element-table {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.rotate-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.element-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -8,6 +8,10 @@
|
||||
left: elementInfo.left + 'px',
|
||||
width: elementInfo.width + 'px',
|
||||
}"
|
||||
>
|
||||
<div
|
||||
class="rotate-wrapper"
|
||||
:style="{ transform: `rotate(${elementInfo.rotate}deg)` }"
|
||||
>
|
||||
<div
|
||||
class="element-content"
|
||||
@ -36,6 +40,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@ -190,7 +195,10 @@ export default defineComponent({
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
.rotate-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.element-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -6,22 +6,27 @@
|
||||
width: elementInfo.width + 'px',
|
||||
height: elementInfo.height + 'px',
|
||||
}"
|
||||
>
|
||||
<div
|
||||
class="rotate-wrapper"
|
||||
:style="{ transform: `rotate(${elementInfo.rotate}deg)` }"
|
||||
>
|
||||
<div class="element-content" :style="{ backgroundImage: `url(${elementInfo.poster})` }">
|
||||
<IconPlayOne class="icon" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType } from 'vue'
|
||||
import { PPTTableElement } from '@/types/slides'
|
||||
import { PPTVideoElement } from '@/types/slides'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'base-element-video',
|
||||
props: {
|
||||
elementInfo: {
|
||||
type: Object as PropType<PPTTableElement>,
|
||||
type: Object as PropType<PPTVideoElement>,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
@ -32,7 +37,10 @@ export default defineComponent({
|
||||
.base-element-video {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.rotate-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.element-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -6,6 +6,10 @@
|
||||
width: elementInfo.width + 'px',
|
||||
height: elementInfo.height + 'px',
|
||||
}"
|
||||
>
|
||||
<div
|
||||
class="rotate-wrapper"
|
||||
:style="{ transform: `rotate(${elementInfo.rotate}deg)` }"
|
||||
>
|
||||
<div class="element-content">
|
||||
<VideoPlayer
|
||||
@ -17,11 +21,12 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, inject, PropType, Ref, ref } from 'vue'
|
||||
import { PPTTableElement } from '@/types/slides'
|
||||
import { PPTVideoElement } from '@/types/slides'
|
||||
|
||||
import VideoPlayer from './VideoPlayer/index.vue'
|
||||
|
||||
@ -32,7 +37,7 @@ export default defineComponent({
|
||||
},
|
||||
props: {
|
||||
elementInfo: {
|
||||
type: Object as PropType<PPTTableElement>,
|
||||
type: Object as PropType<PPTVideoElement>,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
@ -50,7 +55,10 @@ export default defineComponent({
|
||||
.screen-element-video {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.rotate-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.element-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -7,6 +7,10 @@
|
||||
width: elementInfo.width + 'px',
|
||||
height: elementInfo.height + 'px',
|
||||
}"
|
||||
>
|
||||
<div
|
||||
class="rotate-wrapper"
|
||||
:style="{ transform: `rotate(${elementInfo.rotate}deg)` }"
|
||||
>
|
||||
<div
|
||||
class="element-content"
|
||||
@ -28,12 +32,13 @@
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, PropType } from 'vue'
|
||||
import { useStore } from '@/store'
|
||||
import { PPTTableElement } from '@/types/slides'
|
||||
import { PPTVideoElement } from '@/types/slides'
|
||||
import { ContextmenuItem } from '@/components/Contextmenu/types'
|
||||
|
||||
import VideoPlayer from './VideoPlayer/index.vue'
|
||||
@ -45,11 +50,11 @@ export default defineComponent({
|
||||
},
|
||||
props: {
|
||||
elementInfo: {
|
||||
type: Object as PropType<PPTTableElement>,
|
||||
type: Object as PropType<PPTVideoElement>,
|
||||
required: true,
|
||||
},
|
||||
selectElement: {
|
||||
type: Function as PropType<(e: MouseEvent, element: PPTTableElement, canMove?: boolean) => void>,
|
||||
type: Function as PropType<(e: MouseEvent, element: PPTVideoElement, canMove?: boolean) => void>,
|
||||
required: true,
|
||||
},
|
||||
contextmenus: {
|
||||
@ -83,7 +88,10 @@ export default defineComponent({
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
.rotate-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.element-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -14,7 +14,6 @@
|
||||
"baseUrl": ".",
|
||||
"types": [
|
||||
"webpack-env",
|
||||
"jest",
|
||||
"resize-observer-browser"
|
||||
],
|
||||
"paths": {
|
||||
|
Loading…
x
Reference in New Issue
Block a user