feat: 添加页面尺寸修改功能

This commit is contained in:
pipipi-pikachu 2021-03-27 16:43:15 +08:00
parent 5fd09ffc7b
commit 326c13c63e
16 changed files with 7361 additions and 5092 deletions

12329
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,7 @@
"dependencies": { "dependencies": {
"@icon-park/vue-next": "^1.2.6", "@icon-park/vue-next": "^1.2.6",
"animate.css": "^4.1.1", "animate.css": "^4.1.1",
"ant-design-vue": "^2.1.0", "ant-design-vue": "^2.0.0",
"chartist": "^0.11.4", "chartist": "^0.11.4",
"clipboard": "^2.0.6", "clipboard": "^2.0.6",
"core-js": "^3.6.5", "core-js": "^3.6.5",
@ -30,7 +30,7 @@
"prosemirror-state": "^1.3.3", "prosemirror-state": "^1.3.3",
"prosemirror-view": "^1.18.2", "prosemirror-view": "^1.18.2",
"tinycolor2": "^1.4.2", "tinycolor2": "^1.4.2",
"vue": "^3.0.7", "vue": "^3.0.0",
"vuedraggable": "^4.0.1", "vuedraggable": "^4.0.1",
"vuex": "^4.0.0" "vuex": "^4.0.0"
}, },
@ -59,7 +59,7 @@
"@vue/cli-plugin-unit-jest": "~4.5.0", "@vue/cli-plugin-unit-jest": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0", "@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0", "@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.7", "@vue/compiler-sfc": "^3.0.0",
"@vue/eslint-config-typescript": "^5.0.2", "@vue/eslint-config-typescript": "^5.0.2",
"@vue/test-utils": "^2.0.0-0", "@vue/test-utils": "^2.0.0-0",
"babel-plugin-import": "^1.13.3", "babel-plugin-import": "^1.13.3",

View File

@ -1,2 +1 @@
export const VIEWPORT_SIZE = 1000 export const VIEWPORT_SIZE = 1000
export const VIEWPORT_ASPECT_RATIO = 0.5625

View File

@ -3,13 +3,14 @@ import { MutationTypes, useStore } from '@/store'
import { PPTElement, Slide } from '@/types/slides' import { PPTElement, Slide } from '@/types/slides'
import { ElementAlignCommand, ElementAlignCommands } from '@/types/edit' import { ElementAlignCommand, ElementAlignCommands } from '@/types/edit'
import { getElementListRange } from '@/utils/element' import { getElementListRange } from '@/utils/element'
import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas' import { VIEWPORT_SIZE } from '@/configs/canvas'
import useHistorySnapshot from './useHistorySnapshot' import useHistorySnapshot from './useHistorySnapshot'
export default () => { export default () => {
const store = useStore() const store = useStore()
const activeElementIdList = computed(() => store.state.activeElementIdList) const activeElementIdList = computed(() => store.state.activeElementIdList)
const viewportRatio = computed(() => store.state.viewportRatio)
const activeElementList = computed<PPTElement[]>(() => store.getters.activeElementList) const activeElementList = computed<PPTElement[]>(() => store.getters.activeElementList)
const currentSlide = computed<Slide>(() => store.getters.currentSlide) const currentSlide = computed<Slide>(() => store.getters.currentSlide)
@ -21,7 +22,7 @@ export default () => {
*/ */
const alignElementToCanvas = (command: ElementAlignCommand) => { const alignElementToCanvas = (command: ElementAlignCommand) => {
const viewportWidth = VIEWPORT_SIZE const viewportWidth = VIEWPORT_SIZE
const viewportHeight = VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO const viewportHeight = VIEWPORT_SIZE * viewportRatio.value
const { minX, maxX, minY, maxY } = getElementListRange(activeElementList.value) const { minX, maxX, minY, maxY } = getElementListRange(activeElementList.value)
const newElementList: PPTElement[] = JSON.parse(JSON.stringify(currentSlide.value.elements)) const newElementList: PPTElement[] = JSON.parse(JSON.stringify(currentSlide.value.elements))

View File

@ -2,7 +2,7 @@ import { computed } from 'vue'
import { MutationTypes, useStore } from '@/store' import { MutationTypes, useStore } from '@/store'
import { createRandomCode } from '@/utils/common' import { createRandomCode } from '@/utils/common'
import { getImageSize } from '@/utils/image' import { getImageSize } from '@/utils/image'
import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas' import { VIEWPORT_SIZE } from '@/configs/canvas'
import { PPTLineElement, ChartType, PPTElement, TableCell } from '@/types/slides' import { PPTLineElement, ChartType, PPTElement, TableCell } from '@/types/slides'
import { ShapePoolItem } from '@/configs/shapes' import { ShapePoolItem } from '@/configs/shapes'
import { LinePoolItem } from '@/configs/lines' import { LinePoolItem } from '@/configs/lines'
@ -26,6 +26,7 @@ export default () => {
const store = useStore() const store = useStore()
const themeColor = computed(() => store.state.theme.themeColor) const themeColor = computed(() => store.state.theme.themeColor)
const fontColor = computed(() => store.state.theme.fontColor) const fontColor = computed(() => store.state.theme.fontColor)
const viewportRatio = computed(() => store.state.viewportRatio)
const { addHistorySnapshot } = useHistorySnapshot() const { addHistorySnapshot } = useHistorySnapshot()
@ -44,12 +45,12 @@ export default () => {
getImageSize(src).then(({ width, height }) => { getImageSize(src).then(({ width, height }) => {
const scale = height / width const scale = height / width
if (scale < VIEWPORT_ASPECT_RATIO && width > VIEWPORT_SIZE) { if (scale < viewportRatio.value && width > VIEWPORT_SIZE) {
width = VIEWPORT_SIZE width = VIEWPORT_SIZE
height = width * scale height = width * scale
} }
else if (height > VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO) { else if (height > VIEWPORT_SIZE * viewportRatio.value) {
height = VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO height = VIEWPORT_SIZE * viewportRatio.value
width = height / scale width = height / scale
} }
@ -60,7 +61,7 @@ export default () => {
width, width,
height, height,
left: (VIEWPORT_SIZE - width) / 2, left: (VIEWPORT_SIZE - width) / 2,
top: (VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO - height) / 2, top: (VIEWPORT_SIZE * viewportRatio.value - height) / 2,
fixedRatio: true, fixedRatio: true,
}) })
}) })
@ -115,7 +116,7 @@ export default () => {
colWidths, colWidths,
data, data,
left: (VIEWPORT_SIZE - width) / 2, left: (VIEWPORT_SIZE - width) / 2,
top: (VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO - height) / 2, top: (VIEWPORT_SIZE * viewportRatio.value - height) / 2,
outline: { outline: {
width: 2, width: 2,
style: 'solid', style: 'solid',

View File

@ -16,6 +16,7 @@ export const enum MutationTypes {
// slides // slides
SET_THEME = 'setTheme', SET_THEME = 'setTheme',
SET_VIEWPORT_RATIO = 'setViewportRatio',
SET_SLIDES = 'setSlides', SET_SLIDES = 'setSlides',
ADD_SLIDE = 'addSlide', ADD_SLIDE = 'addSlide',
UPDATE_SLIDE = 'updateSlide', UPDATE_SLIDE = 'updateSlide',

View File

@ -78,6 +78,10 @@ export const mutations: MutationTree<State> = {
state.theme = { ...state.theme, ...themeProps } state.theme = { ...state.theme, ...themeProps }
}, },
[MutationTypes.SET_VIEWPORT_RATIO](state, viewportRatio: number) {
state.viewportRatio = viewportRatio
},
[MutationTypes.SET_SLIDES](state, slides: Slide[]) { [MutationTypes.SET_SLIDES](state, slides: Slide[]) {
state.slides = slides state.slides = slides
}, },

View File

@ -17,6 +17,7 @@ export interface State {
availableFonts: typeof SYS_FONTS; availableFonts: typeof SYS_FONTS;
toolbarState: ToolbarState; toolbarState: ToolbarState;
theme: SlideTheme; theme: SlideTheme;
viewportRatio: number;
slides: Slide[]; slides: Slide[];
slideIndex: number; slideIndex: number;
selectedSlidesIndex: number[]; selectedSlidesIndex: number[];
@ -46,6 +47,7 @@ export const state: State = {
fontName: '微软雅黑', fontName: '微软雅黑',
backgroundColor: '#fff', backgroundColor: '#fff',
}, },
viewportRatio: 0.5625,
slides: slides, slides: slides,
slideIndex: 0, slideIndex: 0,
selectedSlidesIndex: [], selectedSlidesIndex: [],

View File

@ -18,7 +18,7 @@
import { defineComponent, computed } from 'vue' import { defineComponent, computed } from 'vue'
import tinycolor from 'tinycolor2' import tinycolor from 'tinycolor2'
import { useStore } from '@/store' import { useStore } from '@/store'
import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas' import { VIEWPORT_SIZE } from '@/configs/canvas'
import { SlideBackground } from '@/types/slides' import { SlideBackground } from '@/types/slides'
export default defineComponent({ export default defineComponent({
@ -26,6 +26,7 @@ export default defineComponent({
setup() { setup() {
const store = useStore() const store = useStore()
const canvasScale = computed(() => store.state.canvasScale) const canvasScale = computed(() => store.state.canvasScale)
const viewportRatio = computed(() => store.state.viewportRatio)
const background = computed<SlideBackground | undefined>(() => store.getters.currentSlide?.background) const background = computed<SlideBackground | undefined>(() => store.getters.currentSlide?.background)
// 线 // 线
@ -47,7 +48,7 @@ export default defineComponent({
// //
const getPath = () => { const getPath = () => {
const maxX = VIEWPORT_SIZE const maxX = VIEWPORT_SIZE
const maxY = VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO const maxY = VIEWPORT_SIZE * viewportRatio.value
let path = '' let path = ''
for (let i = 0; i <= Math.floor(maxY / gridSize); i++) { for (let i = 0; i <= Math.floor(maxY / gridSize); i++) {
@ -63,7 +64,7 @@ export default defineComponent({
canvasScale, canvasScale,
gridColor, gridColor,
width: VIEWPORT_SIZE, width: VIEWPORT_SIZE,
height: VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO, height: VIEWPORT_SIZE * viewportRatio.value,
path: getPath(), path: getPath(),
} }
}, },

View File

@ -2,7 +2,7 @@ import { Ref, computed } from 'vue'
import { MutationTypes, useStore } from '@/store' import { MutationTypes, useStore } from '@/store'
import { PPTElement } from '@/types/slides' import { PPTElement } from '@/types/slides'
import { AlignmentLineProps } from '@/types/edit' import { AlignmentLineProps } from '@/types/edit'
import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas' import { VIEWPORT_SIZE } from '@/configs/canvas'
import { getRectRotatedRange, AlignLine, uniqAlignLines } from '@/utils/element' import { getRectRotatedRange, AlignLine, uniqAlignLines } from '@/utils/element'
import useHistorySnapshot from '@/hooks/useHistorySnapshot' import useHistorySnapshot from '@/hooks/useHistorySnapshot'
@ -14,6 +14,7 @@ export default (
const store = useStore() const store = useStore()
const activeElementIdList = computed(() => store.state.activeElementIdList) const activeElementIdList = computed(() => store.state.activeElementIdList)
const canvasScale = computed(() => store.state.canvasScale) const canvasScale = computed(() => store.state.canvasScale)
const viewportRatio = computed(() => store.state.viewportRatio)
const { addHistorySnapshot } = useHistorySnapshot() const { addHistorySnapshot } = useHistorySnapshot()
@ -22,7 +23,7 @@ export default (
let isMouseDown = true let isMouseDown = true
const edgeWidth = VIEWPORT_SIZE const edgeWidth = VIEWPORT_SIZE
const edgeHeight = VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO const edgeHeight = VIEWPORT_SIZE * viewportRatio.value
const sorptionRange = 5 const sorptionRange = 5

View File

@ -3,7 +3,7 @@ import { MutationTypes, useStore } from '@/store'
import { PPTElement, PPTImageElement, PPTLineElement, PPTShapeElement } from '@/types/slides' import { PPTElement, PPTImageElement, PPTLineElement, PPTShapeElement } from '@/types/slides'
import { OperateResizeHandlers, AlignmentLineProps, MultiSelectRange } from '@/types/edit' import { OperateResizeHandlers, AlignmentLineProps, MultiSelectRange } from '@/types/edit'
import emitter, { EmitterEvents } from '@/utils/emitter' import emitter, { EmitterEvents } from '@/utils/emitter'
import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas' import { VIEWPORT_SIZE } from '@/configs/canvas'
import { MIN_SIZE } from '@/configs/element' import { MIN_SIZE } from '@/configs/element'
import { AlignLine, uniqAlignLines } from '@/utils/element' import { AlignLine, uniqAlignLines } from '@/utils/element'
import useHistorySnapshot from '@/hooks/useHistorySnapshot' import useHistorySnapshot from '@/hooks/useHistorySnapshot'
@ -99,8 +99,9 @@ export default (
) => { ) => {
const store = useStore() const store = useStore()
const activeElementIdList = computed(() => store.state.activeElementIdList) const activeElementIdList = computed(() => store.state.activeElementIdList)
const ctrlOrShiftKeyActive = computed<boolean>(() => store.getters.ctrlOrShiftKeyActive)
const canvasScale = computed(() => store.state.canvasScale) const canvasScale = computed(() => store.state.canvasScale)
const viewportRatio = computed(() => store.state.viewportRatio)
const ctrlOrShiftKeyActive = computed<boolean>(() => store.getters.ctrlOrShiftKeyActive)
const { addHistorySnapshot } = useHistorySnapshot() const { addHistorySnapshot } = useHistorySnapshot()
@ -149,7 +150,7 @@ export default (
// 其中线条和被旋转过的元素不参与吸附对齐 // 其中线条和被旋转过的元素不参与吸附对齐
else { else {
const edgeWidth = VIEWPORT_SIZE const edgeWidth = VIEWPORT_SIZE
const edgeHeight = VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO const edgeHeight = VIEWPORT_SIZE * viewportRatio.value
const isActiveGroupElement = element.id === activeGroupElementId.value const isActiveGroupElement = element.id === activeGroupElementId.value
for (const el of elementList.value) { for (const el of elementList.value) {

View File

@ -1,6 +1,6 @@
import { ref, computed, onMounted, onUnmounted, Ref, watch } from 'vue' import { ref, computed, onMounted, onUnmounted, Ref, watch } from 'vue'
import { MutationTypes, useStore } from '@/store' import { MutationTypes, useStore } from '@/store'
import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas' import { VIEWPORT_SIZE } from '@/configs/canvas'
export default (canvasRef: Ref<HTMLElement | undefined>) => { export default (canvasRef: Ref<HTMLElement | undefined>) => {
const viewportLeft = ref(0) const viewportLeft = ref(0)
@ -8,6 +8,7 @@ export default (canvasRef: Ref<HTMLElement | undefined>) => {
const store = useStore() const store = useStore()
const canvasPercentage = computed(() => store.state.canvasPercentage) const canvasPercentage = computed(() => store.state.canvasPercentage)
const viewportRatio = computed(() => store.state.viewportRatio)
// 计算画布可视区域的位置 // 计算画布可视区域的位置
const setViewportPosition = () => { const setViewportPosition = () => {
@ -15,27 +16,27 @@ export default (canvasRef: Ref<HTMLElement | undefined>) => {
const canvasWidth = canvasRef.value.clientWidth const canvasWidth = canvasRef.value.clientWidth
const canvasHeight = canvasRef.value.clientHeight const canvasHeight = canvasRef.value.clientHeight
if (canvasHeight / canvasWidth > VIEWPORT_ASPECT_RATIO) { if (canvasHeight / canvasWidth > viewportRatio.value) {
const viewportActualWidth = canvasWidth * (canvasPercentage.value / 100) const viewportActualWidth = canvasWidth * (canvasPercentage.value / 100)
store.commit(MutationTypes.SET_CANVAS_SCALE, viewportActualWidth / VIEWPORT_SIZE) store.commit(MutationTypes.SET_CANVAS_SCALE, viewportActualWidth / VIEWPORT_SIZE)
viewportLeft.value = (canvasWidth - viewportActualWidth) / 2 viewportLeft.value = (canvasWidth - viewportActualWidth) / 2
viewportTop.value = (canvasHeight - viewportActualWidth * VIEWPORT_ASPECT_RATIO) / 2 viewportTop.value = (canvasHeight - viewportActualWidth * viewportRatio.value) / 2
} }
else { else {
const viewportActualHeight = canvasHeight * (canvasPercentage.value / 100) const viewportActualHeight = canvasHeight * (canvasPercentage.value / 100)
store.commit(MutationTypes.SET_CANVAS_SCALE, viewportActualHeight / (VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO)) store.commit(MutationTypes.SET_CANVAS_SCALE, viewportActualHeight / (VIEWPORT_SIZE * viewportRatio.value))
viewportLeft.value = (canvasWidth - viewportActualHeight / VIEWPORT_ASPECT_RATIO) / 2 viewportLeft.value = (canvasWidth - viewportActualHeight / viewportRatio.value) / 2
viewportTop.value = (canvasHeight - viewportActualHeight) / 2 viewportTop.value = (canvasHeight - viewportActualHeight) / 2
} }
} }
// 可视区域缩放时,更新可视区域的位置 // 可视区域缩放或比例变化时,更新可视区域的位置
watch(canvasPercentage, setViewportPosition) watch([canvasPercentage, viewportRatio], setViewportPosition)
// 画布可视区域位置和大小的样式 // 画布可视区域位置和大小的样式
const viewportStyles = computed(() => ({ const viewportStyles = computed(() => ({
width: VIEWPORT_SIZE, width: VIEWPORT_SIZE,
height: VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO, height: VIEWPORT_SIZE * viewportRatio.value,
left: viewportLeft.value, left: viewportLeft.value,
top: viewportTop.value, top: viewportTop.value,
})) }))

View File

@ -176,6 +176,17 @@
</div> </div>
<div class="row"><Button style="flex: 1;" @click="applyThemeAllSlide()">应用主题到全部</Button></div> <div class="row"><Button style="flex: 1;" @click="applyThemeAllSlide()">应用主题到全部</Button></div>
<Divider />
<div class="row">
<div style="flex: 2;">画布尺寸</div>
<Select style="flex: 3;" :value="viewportRatio" @change="value => updateViewportRatio(value)">
<SelectOption :value="0.5625">宽屏 16 : 9</SelectOption>
<SelectOption :value="0.625">宽屏 16 10</SelectOption>
<SelectOption :value="0.75">标准 4 3</SelectOption>
</Select>
</div>
</div> </div>
</template> </template>
@ -202,8 +213,9 @@ export default defineComponent({
const store = useStore() const store = useStore()
const slides = computed(() => store.state.slides) const slides = computed(() => store.state.slides)
const theme = computed(() => store.state.theme) const theme = computed(() => store.state.theme)
const currentSlide = computed<Slide>(() => store.getters.currentSlide)
const availableFonts = computed(() => store.state.availableFonts) const availableFonts = computed(() => store.state.availableFonts)
const viewportRatio = computed(() => store.state.viewportRatio)
const currentSlide = computed<Slide>(() => store.getters.currentSlide)
const background = computed(() => { const background = computed(() => {
if (!currentSlide.value.background) { if (!currentSlide.value.background) {
@ -313,6 +325,11 @@ export default defineComponent({
addHistorySnapshot() addHistorySnapshot()
} }
//
const updateViewportRatio = (value: number) => {
store.commit(MutationTypes.SET_VIEWPORT_RATIO, value)
}
return { return {
availableFonts, availableFonts,
background, background,
@ -325,6 +342,8 @@ export default defineComponent({
webFonts, webFonts,
updateTheme, updateTheme,
applyThemeAllSlide, applyThemeAllSlide,
viewportRatio,
updateViewportRatio,
} }
}, },
}) })

View File

@ -3,7 +3,7 @@
class="screen-slide" class="screen-slide"
:style="{ :style="{
width: VIEWPORT_SIZE + 'px', width: VIEWPORT_SIZE + 'px',
height: VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO + 'px', height: VIEWPORT_SIZE * viewportRatio + 'px',
transform: `scale(${scale})`, transform: `scale(${scale})`,
}" }"
> >
@ -21,8 +21,9 @@
<script lang="ts"> <script lang="ts">
import { computed, PropType, defineComponent } from 'vue' import { computed, PropType, defineComponent } from 'vue'
import { useStore } from '@/store'
import { Slide } from '@/types/slides' import { Slide } from '@/types/slides'
import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas' import { VIEWPORT_SIZE } from '@/configs/canvas'
import useSlideBackgroundStyle from '@/hooks/useSlideBackgroundStyle' import useSlideBackgroundStyle from '@/hooks/useSlideBackgroundStyle'
import ScreenElement from './ScreenElement.vue' import ScreenElement from './ScreenElement.vue'
@ -47,13 +48,16 @@ export default defineComponent({
}, },
}, },
setup(props) { setup(props) {
const store = useStore()
const viewportRatio = computed(() => store.state.viewportRatio)
const background = computed(() => props.slide.background) const background = computed(() => props.slide.background)
const { backgroundStyle } = useSlideBackgroundStyle(background) const { backgroundStyle } = useSlideBackgroundStyle(background)
return { return {
backgroundStyle, backgroundStyle,
VIEWPORT_SIZE, VIEWPORT_SIZE,
VIEWPORT_ASPECT_RATIO, viewportRatio,
} }
}, },
}) })

View File

@ -60,7 +60,7 @@ import { computed, defineComponent, onMounted, onUnmounted, provide, ref } from
import throttle from 'lodash/throttle' import throttle from 'lodash/throttle'
import { MutationTypes, useStore } from '@/store' import { MutationTypes, useStore } from '@/store'
import { Slide } from '@/types/slides' import { Slide } from '@/types/slides'
import { VIEWPORT_ASPECT_RATIO, VIEWPORT_SIZE } from '@/configs/canvas' import { VIEWPORT_SIZE } from '@/configs/canvas'
import { KEYS } from '@/configs/hotkey' import { KEYS } from '@/configs/hotkey'
import { ContextmenuItem } from '@/components/Contextmenu/types' import { ContextmenuItem } from '@/components/Contextmenu/types'
import { isFullscreen } from '@/utils/fullscreen' import { isFullscreen } from '@/utils/fullscreen'
@ -81,6 +81,7 @@ export default defineComponent({
const store = useStore() const store = useStore()
const slides = computed(() => store.state.slides) const slides = computed(() => store.state.slides)
const slideIndex = computed(() => store.state.slideIndex) const slideIndex = computed(() => store.state.slideIndex)
const viewportRatio = computed(() => store.state.viewportRatio)
const currentSlide = computed<Slide>(() => store.getters.currentSlide) const currentSlide = computed<Slide>(() => store.getters.currentSlide)
const slideWidth = ref(0) const slideWidth = ref(0)
@ -98,16 +99,16 @@ export default defineComponent({
const winHeight = document.body.clientHeight const winHeight = document.body.clientHeight
let width, height let width, height
if (winHeight / winWidth === VIEWPORT_ASPECT_RATIO) { if (winHeight / winWidth === viewportRatio.value) {
width = winWidth width = winWidth
height = winHeight height = winHeight
} }
else if (winHeight / winWidth > VIEWPORT_ASPECT_RATIO) { else if (winHeight / winWidth > viewportRatio.value) {
width = winWidth width = winWidth
height = winWidth * VIEWPORT_ASPECT_RATIO height = winWidth * viewportRatio.value
} }
else { else {
width = winHeight / VIEWPORT_ASPECT_RATIO width = winHeight / viewportRatio.value
height = winHeight height = winHeight
} }
slideWidth.value = width slideWidth.value = width

View File

@ -2,14 +2,14 @@
<div class="thumbnail-slide" <div class="thumbnail-slide"
:style="{ :style="{
width: size + 'px', width: size + 'px',
height: size * VIEWPORT_ASPECT_RATIO + 'px', height: size * viewportRatio + 'px',
}" }"
> >
<div <div
class="elements" class="elements"
:style="{ :style="{
width: VIEWPORT_SIZE + 'px', width: VIEWPORT_SIZE + 'px',
height: VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO + 'px', height: VIEWPORT_SIZE * viewportRatio + 'px',
transform: `scale(${scale})`, transform: `scale(${scale})`,
}" }"
> >
@ -26,8 +26,9 @@
<script lang="ts"> <script lang="ts">
import { computed, PropType, defineComponent } from 'vue' import { computed, PropType, defineComponent } from 'vue'
import { useStore } from '@/store'
import { Slide } from '@/types/slides' import { Slide } from '@/types/slides'
import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas' import { VIEWPORT_SIZE } from '@/configs/canvas'
import useSlideBackgroundStyle from '@/hooks/useSlideBackgroundStyle' import useSlideBackgroundStyle from '@/hooks/useSlideBackgroundStyle'
import ThumbnailElement from './ThumbnailElement.vue' import ThumbnailElement from './ThumbnailElement.vue'
@ -48,6 +49,9 @@ export default defineComponent({
}, },
}, },
setup(props) { setup(props) {
const store = useStore()
const viewportRatio = computed(() => store.state.viewportRatio)
const background = computed(() => props.slide.background) const background = computed(() => props.slide.background)
const { backgroundStyle } = useSlideBackgroundStyle(background) const { backgroundStyle } = useSlideBackgroundStyle(background)
@ -57,7 +61,7 @@ export default defineComponent({
scale, scale,
backgroundStyle, backgroundStyle,
VIEWPORT_SIZE, VIEWPORT_SIZE,
VIEWPORT_ASPECT_RATIO, viewportRatio,
} }
}, },
}) })