refactor: viewport_size可修改

This commit is contained in:
zxc 2024-09-02 22:48:05 +08:00
parent 0471237fe6
commit 8f8825327f
16 changed files with 70 additions and 76 deletions

View File

@ -1 +0,0 @@
export const VIEWPORT_SIZE = 1000

View File

@ -3,12 +3,11 @@ import { useMainStore, useSlidesStore } from '@/store'
import type { PPTElement } from '@/types/slides'
import { ElementAlignCommands } from '@/types/edit'
import { getElementListRange } from '@/utils/element'
import { VIEWPORT_SIZE } from '@/configs/canvas'
import useHistorySnapshot from './useHistorySnapshot'
export default () => {
const slidesStore = useSlidesStore()
const { activeElementIdList, activeElementList } = storeToRefs(useMainStore())
const { activeElementIdList, activeElementList, viewportSize } = storeToRefs(useMainStore())
const { currentSlide, viewportRatio } = storeToRefs(slidesStore)
const { addHistorySnapshot } = useHistorySnapshot()
@ -18,8 +17,8 @@ export default () => {
* @param command
*/
const alignElementToCanvas = (command: ElementAlignCommands) => {
const viewportWidth = VIEWPORT_SIZE
const viewportHeight = VIEWPORT_SIZE * viewportRatio.value
const viewportWidth = viewportSize.value
const viewportHeight = viewportSize.value * viewportRatio.value
const { minX, maxX, minY, maxY } = getElementListRange(activeElementList.value)
const newElementList: PPTElement[] = JSON.parse(JSON.stringify(currentSlide.value.elements))

View File

@ -2,7 +2,6 @@ import { storeToRefs } from 'pinia'
import { nanoid } from 'nanoid'
import { useMainStore, useSlidesStore } from '@/store'
import { getImageSize } from '@/utils/image'
import { VIEWPORT_SIZE } from '@/configs/canvas'
import type { PPTLineElement, PPTElement, TableCell, TableCellStyle, PPTShapeElement, PPTChartElement, ChartOptions, PresetChartType } from '@/types/slides'
import { type ShapePoolItem, SHAPE_PATH_FORMULAS } from '@/configs/shapes'
import type { LinePoolItem } from '@/configs/lines'
@ -31,7 +30,7 @@ interface CreateTextData {
export default () => {
const mainStore = useMainStore()
const slidesStore = useSlidesStore()
const { creatingElement } = storeToRefs(mainStore)
const { creatingElement, viewportSize } = storeToRefs(mainStore)
const { theme, viewportRatio } = storeToRefs(slidesStore)
const { addHistorySnapshot } = useHistorySnapshot()
@ -60,12 +59,12 @@ export default () => {
getImageSize(src).then(({ width, height }) => {
const scale = height / width
if (scale < viewportRatio.value && width > VIEWPORT_SIZE) {
width = VIEWPORT_SIZE
if (scale < viewportRatio.value && width > viewportSize.value) {
width = viewportSize.value
height = width * scale
}
else if (height > VIEWPORT_SIZE * viewportRatio.value) {
height = VIEWPORT_SIZE * viewportRatio.value
else if (height > viewportSize.value * viewportRatio.value) {
height = viewportSize.value * viewportRatio.value
width = height / scale
}
@ -75,8 +74,8 @@ export default () => {
src,
width,
height,
left: (VIEWPORT_SIZE - width) / 2,
top: (VIEWPORT_SIZE * viewportRatio.value - height) / 2,
left: (viewportSize.value - width) / 2,
top: (viewportSize.value * viewportRatio.value - height) / 2,
fixedRatio: true,
rotate: 0,
})
@ -159,8 +158,8 @@ export default () => {
colWidths,
rotate: 0,
data,
left: (VIEWPORT_SIZE - width) / 2,
top: (VIEWPORT_SIZE * viewportRatio.value - height) / 2,
left: (viewportSize.value - width) / 2,
top: (viewportSize.value * viewportRatio.value - height) / 2,
outline: {
width: 2,
style: 'solid',
@ -282,8 +281,8 @@ export default () => {
width: data.w,
height: data.h,
rotate: 0,
left: (VIEWPORT_SIZE - data.w) / 2,
top: (VIEWPORT_SIZE * viewportRatio.value - data.h) / 2,
left: (viewportSize.value - data.w) / 2,
top: (viewportSize.value * viewportRatio.value - data.h) / 2,
path: data.path,
latex: data.latex,
color: theme.value.fontColor,
@ -304,8 +303,8 @@ export default () => {
width: 500,
height: 300,
rotate: 0,
left: (VIEWPORT_SIZE - 500) / 2,
top: (VIEWPORT_SIZE * viewportRatio.value - 300) / 2,
left: (viewportSize.value - 500) / 2,
top: (viewportSize.value * viewportRatio.value - 300) / 2,
src,
autoplay: false,
})
@ -322,8 +321,8 @@ export default () => {
width: 50,
height: 50,
rotate: 0,
left: (VIEWPORT_SIZE - 50) / 2,
top: (VIEWPORT_SIZE * viewportRatio.value - 50) / 2,
left: (viewportSize.value - 50) / 2,
top: (viewportSize.value * viewportRatio.value - 50) / 2,
loop: false,
autoplay: false,
fixedRatio: true,

View File

@ -2,10 +2,9 @@ import { ref } from 'vue'
import { storeToRefs } from 'pinia'
import { parse, type Shape, type Element, type ChartItem } from 'pptxtojson'
import { nanoid } from 'nanoid'
import { useSlidesStore } from '@/store'
import { useMainStore, useSlidesStore } from '@/store'
import { decrypt } from '@/utils/crypto'
import { type ShapePoolItem, SHAPE_LIST, SHAPE_PATH_FORMULAS } from '@/configs/shapes'
import { VIEWPORT_SIZE } from '@/configs/canvas'
import useAddSlidesOrElements from '@/hooks/useAddSlidesOrElements'
import useSlideHandler from '@/hooks/useSlideHandler'
import message from '@/utils/message'
@ -32,6 +31,8 @@ export default () => {
const slidesStore = useSlidesStore()
const { theme } = storeToRefs(useSlidesStore())
const { viewportSize } = storeToRefs(useMainStore())
const { addSlidesFromData } = useAddSlidesOrElements()
const { isEmptySlide } = useSlideHandler()
@ -108,7 +109,7 @@ export default () => {
const ratioForPt2Px = 96 / 72
const width = json.size.width
const ratio = VIEWPORT_SIZE / width
const ratio = viewportSize.value / width
const slides: Slide[] = []
for (const item of json.slides) {

View File

@ -14,6 +14,7 @@ export interface MainState {
handleElementId: string
activeGroupElementId: string
hiddenElementIdList: string[]
viewportSize: number
canvasPercentage: number
canvasScale: number
canvasDragged: boolean
@ -49,6 +50,7 @@ export const useMainStore = defineStore('main', {
handleElementId: '', // 正在操作的元素ID
activeGroupElementId: '', // 组合元素成员中被选中可独立操作的元素ID
hiddenElementIdList: [], // 被隐藏的元素ID集合
viewportSize: 1000, // 可视区域宽度基数
canvasPercentage: 90, // 画布可视区域百分比
canvasScale: 1, // 画布缩放比例基于宽度1000px
canvasDragged: false, // 画布被拖拽移动

View File

@ -18,10 +18,9 @@ import { computed } from 'vue'
import tinycolor from 'tinycolor2'
import { storeToRefs } from 'pinia'
import { useMainStore, useSlidesStore } from '@/store'
import { VIEWPORT_SIZE } from '@/configs/canvas'
import type { SlideBackground } from '@/types/slides'
const { canvasScale, gridLineSize } = storeToRefs(useMainStore())
const { canvasScale, gridLineSize, viewportSize } = storeToRefs(useMainStore())
const { currentSlide, viewportRatio } = storeToRefs(useSlidesStore())
const background = computed<SlideBackground | undefined>(() => currentSlide.value?.background)
@ -35,8 +34,8 @@ const gridColor = computed(() => {
//
const path = computed(() => {
const maxX = VIEWPORT_SIZE
const maxY = VIEWPORT_SIZE * viewportRatio.value
const maxX = viewportSize.value
const maxY = viewportSize.value * viewportRatio.value
let p = ''
for (let i = 0; i <= Math.floor(maxY / gridLineSize.value); i++) {

View File

@ -3,7 +3,6 @@ import { storeToRefs } from 'pinia'
import { useMainStore, useSlidesStore, useKeyboardStore } from '@/store'
import type { PPTElement } from '@/types/slides'
import type { AlignmentLineProps } from '@/types/edit'
import { VIEWPORT_SIZE } from '@/configs/canvas'
import { getRectRotatedRange, uniqAlignLines, type AlignLine } from '@/utils/element'
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
@ -13,7 +12,7 @@ export default (
canvasScale: Ref<number>,
) => {
const slidesStore = useSlidesStore()
const { activeElementIdList, activeGroupElementId } = storeToRefs(useMainStore())
const { activeElementIdList, activeGroupElementId, viewportSize } = storeToRefs(useMainStore())
const { shiftKeyState } = storeToRefs(useKeyboardStore())
const { viewportRatio } = storeToRefs(slidesStore)
@ -26,8 +25,8 @@ export default (
if (!activeElementIdList.value.includes(element.id)) return
let isMouseDown = true
const edgeWidth = VIEWPORT_SIZE
const edgeHeight = VIEWPORT_SIZE * viewportRatio.value
const edgeWidth = viewportSize.value
const edgeHeight = viewportSize.value * viewportRatio.value
const sorptionRange = 5

View File

@ -3,7 +3,6 @@ import { storeToRefs } from 'pinia'
import { useMainStore, useSlidesStore, useKeyboardStore } from '@/store'
import type { PPTElement, PPTImageElement, PPTLineElement, PPTShapeElement } from '@/types/slides'
import { OperateResizeHandlers, type AlignmentLineProps, type MultiSelectRange } from '@/types/edit'
import { VIEWPORT_SIZE } from '@/configs/canvas'
import { MIN_SIZE } from '@/configs/element'
import { SHAPE_PATH_FORMULAS } from '@/configs/shapes'
import { type AlignLine, uniqAlignLines } from '@/utils/element'
@ -100,7 +99,7 @@ export default (
) => {
const mainStore = useMainStore()
const slidesStore = useSlidesStore()
const { activeElementIdList, activeGroupElementId } = storeToRefs(mainStore)
const { activeElementIdList, activeGroupElementId, viewportSize } = storeToRefs(mainStore)
const { viewportRatio } = storeToRefs(slidesStore)
const { ctrlOrShiftKeyActive } = storeToRefs(useKeyboardStore())
@ -155,8 +154,8 @@ export default (
// 包括页面内除目标元素外的其他元素在画布中的各个可吸附对齐位置:上下左右四边
// 其中线条和被旋转过的元素不参与吸附对齐
else {
const edgeWidth = VIEWPORT_SIZE
const edgeHeight = VIEWPORT_SIZE * viewportRatio.value
const edgeWidth = viewportSize.value
const edgeHeight = viewportSize.value * viewportRatio.value
const isActiveGroupElement = element.id === activeGroupElementId.value
for (const el of elementList.value) {

View File

@ -1,14 +1,13 @@
import { ref, computed, onMounted, onUnmounted, watch, type Ref } from 'vue'
import { storeToRefs } from 'pinia'
import { useMainStore, useSlidesStore } from '@/store'
import { VIEWPORT_SIZE } from '@/configs/canvas'
export default (canvasRef: Ref<HTMLElement | undefined>) => {
const viewportLeft = ref(0)
const viewportTop = ref(0)
const mainStore = useMainStore()
const { canvasPercentage, canvasDragged } = storeToRefs(mainStore)
const { canvasPercentage, canvasDragged, viewportSize } = storeToRefs(mainStore)
const { viewportRatio } = storeToRefs(useSlidesStore())
// 初始化画布可视区域的位置
@ -19,13 +18,13 @@ export default (canvasRef: Ref<HTMLElement | undefined>) => {
if (canvasHeight / canvasWidth > viewportRatio.value) {
const viewportActualWidth = canvasWidth * (canvasPercentage.value / 100)
mainStore.setCanvasScale(viewportActualWidth / VIEWPORT_SIZE)
mainStore.setCanvasScale(viewportActualWidth / viewportSize.value)
viewportLeft.value = (canvasWidth - viewportActualWidth) / 2
viewportTop.value = (canvasHeight - viewportActualWidth * viewportRatio.value) / 2
}
else {
const viewportActualHeight = canvasHeight * (canvasPercentage.value / 100)
mainStore.setCanvasScale(viewportActualHeight / (VIEWPORT_SIZE * viewportRatio.value))
mainStore.setCanvasScale(viewportActualHeight / (viewportSize.value * viewportRatio.value))
viewportLeft.value = (canvasWidth - viewportActualHeight / viewportRatio.value) / 2
viewportTop.value = (canvasHeight - viewportActualHeight) / 2
}
@ -43,7 +42,7 @@ export default (canvasRef: Ref<HTMLElement | undefined>) => {
const newViewportActualHeight = newViewportActualWidth * viewportRatio.value
const oldViewportActualHeight = oldViewportActualWidth * viewportRatio.value
mainStore.setCanvasScale(newViewportActualWidth / VIEWPORT_SIZE)
mainStore.setCanvasScale(newViewportActualWidth / viewportSize.value)
viewportLeft.value = viewportLeft.value - (newViewportActualWidth - oldViewportActualWidth) / 2
viewportTop.value = viewportTop.value - (newViewportActualHeight - oldViewportActualHeight) / 2
@ -54,7 +53,7 @@ export default (canvasRef: Ref<HTMLElement | undefined>) => {
const newViewportActualWidth = newViewportActualHeight / viewportRatio.value
const oldViewportActualWidth = oldViewportActualHeight / viewportRatio.value
mainStore.setCanvasScale(newViewportActualHeight / (VIEWPORT_SIZE * viewportRatio.value))
mainStore.setCanvasScale(newViewportActualHeight / (viewportSize.value * viewportRatio.value))
viewportLeft.value = viewportLeft.value - (newViewportActualWidth - oldViewportActualWidth) / 2
viewportTop.value = viewportTop.value - (newViewportActualHeight - oldViewportActualHeight) / 2
@ -72,8 +71,8 @@ export default (canvasRef: Ref<HTMLElement | undefined>) => {
// 画布可视区域位置和大小的样式
const viewportStyles = computed(() => ({
width: VIEWPORT_SIZE,
height: VIEWPORT_SIZE * viewportRatio.value,
width: viewportSize.value,
height: viewportSize.value * viewportRatio.value,
left: viewportLeft.value,
top: viewportTop.value,
}))

View File

@ -32,12 +32,11 @@
<script lang="ts" setup>
import { computed } from 'vue'
import { storeToRefs } from 'pinia'
import { useSlidesStore } from '@/store'
import { useMainStore, useSlidesStore } from '@/store'
import useSlideHandler from '@/hooks/useSlideHandler'
import useCreateElement from '@/hooks/useCreateElement'
import { getImageDataURL } from '@/utils/image'
import type { ShapePoolItem } from '@/configs/shapes'
import { VIEWPORT_SIZE } from '@/configs/canvas'
import MobileThumbnails from '../MobileThumbnails.vue'
import FileInput from '@/components/FileInput.vue'
@ -46,6 +45,7 @@ import ButtonGroup from '@/components/ButtonGroup.vue'
const slidesStore = useSlidesStore()
const { viewportRatio, currentSlide } = storeToRefs(slidesStore)
const { viewportSize } = storeToRefs(useMainStore())
const { createSlide, copyAndPasteSlide, deleteSlide, } = useSlideHandler()
const { createTextElement, createImageElement, createShapeElement } = useCreateElement()
@ -55,8 +55,8 @@ const insertTextElement = () => {
const height = 56
createTextElement({
left: (VIEWPORT_SIZE - width) / 2,
top: (VIEWPORT_SIZE * viewportRatio.value - height) / 2,
left: (viewportSize.value - width) / 2,
top: (viewportSize.value * viewportRatio.value - height) / 2,
width,
height,
}, { content: '<p>新添加文本</p>' })
@ -81,8 +81,8 @@ const insertShapeElement = (type: 'square' | 'round') => {
const size = 200
createShapeElement({
left: (VIEWPORT_SIZE - size) / 2,
top: (VIEWPORT_SIZE * viewportRatio.value - size) / 2,
left: (viewportSize.value - size) / 2,
top: (viewportSize.value * viewportRatio.value - size) / 2,
width: size,
height: size,
}, shape[type])

View File

@ -47,7 +47,6 @@ import { useMainStore, useSlidesStore } from '@/store'
import type { PPTElement } from '@/types/slides'
import type { AlignmentLineProps } from '@/types/edit'
import type { Mode } from '@/types/mobile'
import { VIEWPORT_SIZE } from '@/configs/canvas'
import useSlideBackgroundStyle from '@/hooks/useSlideBackgroundStyle'
import useDragElement from '@/views/Editor/Canvas/hooks/useDragElement'
import useScaleElement from '@/views/Editor/Canvas/hooks/useScaleElement'
@ -67,7 +66,7 @@ defineProps<{
const slidesStore = useSlidesStore()
const mainStore = useMainStore()
const { slideIndex, currentSlide, viewportRatio } = storeToRefs(slidesStore)
const { activeElementIdList, handleElement } = storeToRefs(mainStore)
const { activeElementIdList, handleElement, viewportSize } = storeToRefs(mainStore)
const contentRef = ref<HTMLElement>()
const viewportRef = ref<HTMLElement>()
@ -83,8 +82,8 @@ const canvasScale = computed(() => {
const contentheight = contentRef.value.clientHeight
const contentRatio = contentheight / contentWidth
if (contentRatio >= viewportRatio.value) return (contentWidth - 20) / VIEWPORT_SIZE
return (contentheight - 20) / viewportRatio.value / VIEWPORT_SIZE
if (contentRatio >= viewportRatio.value) return (contentWidth - 20) / viewportSize.value
return (contentheight - 20) / viewportRatio.value / viewportSize.value
})
onMounted(() => {
@ -93,8 +92,8 @@ onMounted(() => {
})
const viewportStyles = computed(() => ({
width: VIEWPORT_SIZE * canvasScale.value + 'px',
height: VIEWPORT_SIZE * viewportRatio.value * canvasScale.value + 'px',
width: viewportSize.value * canvasScale.value + 'px',
height: viewportSize.value * viewportRatio.value * canvasScale.value + 'px',
}))
const elementList = ref<PPTElement[]>([])

View File

@ -2,8 +2,8 @@
<div
class="screen-slide"
:style="{
width: VIEWPORT_SIZE + 'px',
height: VIEWPORT_SIZE * viewportRatio + 'px',
width: viewportSize + 'px',
height: viewportSize * viewportRatio + 'px',
transform: `scale(${scale})`,
}"
>
@ -23,10 +23,9 @@
<script lang="ts" setup>
import { computed, provide } from 'vue'
import { storeToRefs } from 'pinia'
import { useSlidesStore } from '@/store'
import { useMainStore, useSlidesStore } from '@/store'
import type { Slide } from '@/types/slides'
import { injectKeySlideId } from '@/types/injectKey'
import { VIEWPORT_SIZE } from '@/configs/canvas'
import useSlideBackgroundStyle from '@/hooks/useSlideBackgroundStyle'
import ScreenElement from './ScreenElement.vue'
@ -40,6 +39,7 @@ const props = defineProps<{
}>()
const { viewportRatio } = storeToRefs(useSlidesStore())
const { viewportSize } = storeToRefs(useMainStore())
const background = computed(() => props.slide.background)
const { backgroundStyle } = useSlideBackgroundStyle(background)

View File

@ -37,9 +37,8 @@
<script lang="ts" setup>
import { computed, provide } from 'vue'
import { storeToRefs } from 'pinia'
import { useSlidesStore } from '@/store'
import { useMainStore, useSlidesStore } from '@/store'
import { injectKeySlideScale } from '@/types/injectKey'
import { VIEWPORT_SIZE } from '@/configs/canvas'
import { SLIDE_ANIMATIONS } from '@/configs/animation'
import ScreenSlide from './ScreenSlide.vue'
@ -53,6 +52,7 @@ const props = defineProps<{
}>()
const { slides, slideIndex } = storeToRefs(useSlidesStore())
const { viewportSize } = storeToRefs(useMainStore())
const slidesWithTurningMode = computed(() => {
return slides.value.map(slide => {
@ -69,7 +69,7 @@ const slidesWithTurningMode = computed(() => {
})
})
const scale = computed(() => props.slideWidth / VIEWPORT_SIZE)
const scale = computed(() => props.slideWidth / viewportSize.value)
provide(injectKeySlideScale, scale)
</script>

View File

@ -8,8 +8,8 @@
<div
class="elements"
:style="{
width: VIEWPORT_SIZE + 'px',
height: VIEWPORT_SIZE * viewportRatio + 'px',
width: viewportSize + 'px',
height: viewportSize * viewportRatio + 'px',
transform: `scale(${scale})`,
}"
v-if="visible"
@ -29,10 +29,9 @@
<script lang="ts" setup>
import { computed, provide } from 'vue'
import { storeToRefs } from 'pinia'
import { useSlidesStore } from '@/store'
import { useMainStore, useSlidesStore } from '@/store'
import type { Slide } from '@/types/slides'
import { injectKeySlideScale } from '@/types/injectKey'
import { VIEWPORT_SIZE } from '@/configs/canvas'
import useSlideBackgroundStyle from '@/hooks/useSlideBackgroundStyle'
import ThumbnailElement from './ThumbnailElement.vue'
@ -46,11 +45,12 @@ const props = withDefaults(defineProps<{
})
const { viewportRatio } = storeToRefs(useSlidesStore())
const { viewportSize } = storeToRefs(useMainStore())
const background = computed(() => props.slide.background)
const { backgroundStyle } = useSlideBackgroundStyle(background)
const scale = computed(() => props.size / VIEWPORT_SIZE)
const scale = computed(() => props.size / viewportSize.value)
provide(injectKeySlideScale, scale)
</script>

View File

@ -38,10 +38,9 @@
<script lang="ts" setup>
import { computed, inject, ref } from 'vue'
import { storeToRefs } from 'pinia'
import { useSlidesStore } from '@/store'
import { useMainStore, useSlidesStore } from '@/store'
import type { PPTAudioElement } from '@/types/slides'
import { injectKeySlideId, injectKeySlideScale } from '@/types/injectKey'
import { VIEWPORT_SIZE } from '@/configs/canvas'
import AudioPlayer from './AudioPlayer.vue'
@ -50,6 +49,7 @@ const props = defineProps<{
}>()
const { viewportRatio, currentSlide } = storeToRefs(useSlidesStore())
const { viewportSize } = storeToRefs(useMainStore())
const scale = inject(injectKeySlideScale) || ref(1)
const slideId = inject(injectKeySlideId) || ref('')
@ -60,8 +60,8 @@ const audioIconSize = computed(() => {
return Math.min(props.elementInfo.width, props.elementInfo.height) + 'px'
})
const audioPlayerPosition = computed(() => {
const canvasWidth = VIEWPORT_SIZE
const canvasHeight = VIEWPORT_SIZE * viewportRatio.value
const canvasWidth = viewportSize.value
const canvasHeight = viewportSize.value * viewportRatio.value
const audioWidth = 280 / scale.value
const audioHeight = 50 / scale.value

View File

@ -45,7 +45,6 @@ import { storeToRefs } from 'pinia'
import { useMainStore, useSlidesStore } from '@/store'
import type { PPTAudioElement } from '@/types/slides'
import type { ContextmenuItem } from '@/components/Contextmenu/types'
import { VIEWPORT_SIZE } from '@/configs/canvas'
import AudioPlayer from './AudioPlayer.vue'
@ -55,15 +54,15 @@ const props = defineProps<{
contextmenus: () => ContextmenuItem[] | null
}>()
const { canvasScale, handleElementId } = storeToRefs(useMainStore())
const { canvasScale, handleElementId, viewportSize } = storeToRefs(useMainStore())
const { viewportRatio } = storeToRefs(useSlidesStore())
const audioIconSize = computed(() => {
return Math.min(props.elementInfo.width, props.elementInfo.height) + 'px'
})
const audioPlayerPosition = computed(() => {
const canvasWidth = VIEWPORT_SIZE
const canvasHeight = VIEWPORT_SIZE * viewportRatio.value
const canvasWidth = viewportSize.value
const canvasHeight = viewportSize.value * viewportRatio.value
const audioWidth = 280 / canvasScale.value
const audioHeight = 50 / canvasScale.value