diff --git a/src/hooks/usePreviewScale.hook.ts b/src/hooks/usePreviewScale.hook.ts index 066f6b66..9d8bcb78 100644 --- a/src/hooks/usePreviewScale.hook.ts +++ b/src/hooks/usePreviewScale.hook.ts @@ -1,218 +1,218 @@ -import throttle from 'lodash/throttle' - -// 拆出来是为了更好的分离单独复用 - -// * 屏幕缩放适配(两边留白) -export const usePreviewFitScale = ( - width: number, - height: number, - scaleDom: HTMLElement | null, - callback?: (scale: { - width: number; - height: number; - }) => void -) => { - // * 画布尺寸(px) - const baseWidth = width - const baseHeight = height - - // * 默认缩放值 - const scale = { - width: 1, - height: 1, - } - - // * 需保持的比例 - const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5)) - const calcRate = () => { - // 当前屏幕宽高比 - const currentRate = parseFloat( - (window.innerWidth / window.innerHeight).toFixed(5) - ) - if (scaleDom) { - if (currentRate > baseProportion) { - // 表示更宽 - scale.width = parseFloat(((window.innerHeight * baseProportion) / baseWidth).toFixed(5)) - scale.height = parseFloat((window.innerHeight / baseHeight).toFixed(5)) - scaleDom.style.transform = `scale(${scale.width}, ${scale.height})` - } else { - // 表示更高 - scale.height = parseFloat(((window.innerWidth / baseProportion) / baseHeight).toFixed(5)) - scale.width = parseFloat((window.innerWidth / baseWidth).toFixed(5)) - scaleDom.style.transform = `scale(${scale.width}, ${scale.height})` - } - if (callback) callback(scale) - } - } - - const resize = throttle(() => { - calcRate() - }, 200) - - // * 改变窗口大小重新绘制 - const windowResize = () => { - window.addEventListener('resize', resize) - } - - // * 改变窗口大小重新绘制 - const unWindowResize = () => { - window.removeEventListener('resize', resize) - } - - return { - calcRate, - windowResize, - unWindowResize, - } -} - -// * X轴撑满,Y轴滚动条 -export const usePreviewScrollYScale = ( - width: number, - height: number, - scaleDom: HTMLElement | null, - callback?: (scale: { - width: number; - height: number; - }) => void -) => { - // * 画布尺寸(px) - const baseWidth = width - const baseHeight = height - - // * 默认缩放值 - const scale = { - width: 1, - height: 1, - } - - // * 需保持的比例 - const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5)) - const calcRate = () => { - if (scaleDom) { - scale.height = parseFloat(((window.innerWidth / baseProportion) / baseHeight).toFixed(5)) - scale.width = parseFloat((window.innerWidth / baseWidth).toFixed(5)) - scaleDom.style.transform = `scale(${scale.width}, ${scale.height})` - if (callback) callback(scale) - } - } - - const resize = throttle(() => { - calcRate() - }, 200) - - // * 改变窗口大小重新绘制 - const windowResize = () => { - window.addEventListener('resize', resize) - } - - // * 改变窗口大小重新绘制 - const unWindowResize = () => { - window.removeEventListener('resize', resize) - } - - return { - calcRate, - windowResize, - unWindowResize, - } -} - -// * Y轴撑满,X轴滚动条 -export const usePreviewScrollXScale = ( - width: number, - height: number, - scaleDom: HTMLElement | null, - callback?: (scale: { - width: number; - height: number; - }) => void -) => { - // * 画布尺寸(px) - const baseWidth = width - const baseHeight = height - - // * 默认缩放值 - const scale = { - height: 1, - width: 1, - } - - // * 需保持的比例 - const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5)) - const calcRate = () => { - if (scaleDom) { - scale.width = parseFloat(((window.innerHeight * baseProportion) / baseWidth).toFixed(5)) - scale.height = parseFloat((window.innerHeight / baseHeight).toFixed(5)) - scaleDom.style.transform = `scale(${scale.width}, ${scale.height})` - if (callback) callback(scale) - } - } - - const resize = throttle(() => { - calcRate() - }, 200) - - // * 改变窗口大小重新绘制 - const windowResize = () => { - window.addEventListener('resize', resize) - } - - // * 改变窗口大小重新绘制 - const unWindowResize = () => { - window.removeEventListener('resize', resize) - } - - return { - calcRate, - windowResize, - unWindowResize, - } -} - -// * 变形内容,宽高铺满 -export const usePreviewFullScale = ( - width: number, - height: number, - scaleDom: HTMLElement | null, - callback?: (scale: { - width: number; - height: number; - }) => void -) => { - - // * 默认缩放值 - const scale = { - width: 1, - height: 1, - } - - const calcRate = () => { - if (scaleDom) { - scale.width = parseFloat((window.innerWidth / width).toFixed(5)) - scale.height = parseFloat((window.innerHeight / height).toFixed(5)) - scaleDom.style.transform = `scale(${scale.width}, ${scale.height})` - if (callback) callback(scale) - } - } - - const resize = throttle(() => { - calcRate() - }, 200) - - // * 改变窗口大小重新绘制 - const windowResize = () => { - window.addEventListener('resize', resize) - } - - // * 改变窗口大小重新绘制 - const unWindowResize = () => { - window.removeEventListener('resize', resize) - } - - return { - calcRate, - windowResize, - unWindowResize, - } +import throttle from 'lodash/throttle' + +// 拆出来是为了更好的分离单独复用 + +// * 屏幕缩放适配(两边留白) +export const usePreviewFitScale = ( + width: number, + height: number, + scaleDom: HTMLElement | null, + callback?: (scale: { + width: number; + height: number; + }) => void +) => { + // * 画布尺寸(px) + const baseWidth = width + const baseHeight = height + + // * 默认缩放值 + const scale = { + width: 1, + height: 1, + } + + // * 需保持的比例 + const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5)) + const calcRate = () => { + // 当前屏幕宽高比 + const currentRate = parseFloat( + (window.innerWidth / window.innerHeight).toFixed(5) + ) + if (scaleDom) { + if (currentRate > baseProportion) { + // 表示更宽 + scale.width = parseFloat(((window.innerHeight * baseProportion) / baseWidth).toFixed(5)) + scale.height = parseFloat((window.innerHeight / baseHeight).toFixed(5)) + scaleDom.style.transform = `scale(${scale.width}, ${scale.height})` + } else { + // 表示更高 + scale.height = parseFloat(((window.innerWidth / baseProportion) / baseHeight).toFixed(5)) + scale.width = parseFloat((window.innerWidth / baseWidth).toFixed(5)) + scaleDom.style.transform = `scale(${scale.width}, ${scale.height})` + } + if (callback) callback(scale) + } + } + + const resize = throttle(() => { + calcRate() + }, 200) + + // * 改变窗口大小重新绘制 + const windowResize = () => { + window.addEventListener('resize', resize) + } + + // * 卸载监听 + const unWindowResize = () => { + window.removeEventListener('resize', resize) + } + + return { + calcRate, + windowResize, + unWindowResize, + } +} + +// * X轴撑满,Y轴滚动条 +export const usePreviewScrollYScale = ( + width: number, + height: number, + scaleDom: HTMLElement | null, + callback?: (scale: { + width: number; + height: number; + }) => void +) => { + // * 画布尺寸(px) + const baseWidth = width + const baseHeight = height + + // * 默认缩放值 + const scale = { + width: 1, + height: 1, + } + + // * 需保持的比例 + const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5)) + const calcRate = () => { + if (scaleDom) { + scale.height = parseFloat(((window.innerWidth / baseProportion) / baseHeight).toFixed(5)) + scale.width = parseFloat((window.innerWidth / baseWidth).toFixed(5)) + scaleDom.style.transform = `scale(${scale.width}, ${scale.height})` + if (callback) callback(scale) + } + } + + const resize = throttle(() => { + calcRate() + }, 200) + + // * 改变窗口大小重新绘制 + const windowResize = () => { + window.addEventListener('resize', resize) + } + + // * 卸载监听 + const unWindowResize = () => { + window.removeEventListener('resize', resize) + } + + return { + calcRate, + windowResize, + unWindowResize, + } +} + +// * Y轴撑满,X轴滚动条 +export const usePreviewScrollXScale = ( + width: number, + height: number, + scaleDom: HTMLElement | null, + callback?: (scale: { + width: number; + height: number; + }) => void +) => { + // * 画布尺寸(px) + const baseWidth = width + const baseHeight = height + + // * 默认缩放值 + const scale = { + height: 1, + width: 1, + } + + // * 需保持的比例 + const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5)) + const calcRate = () => { + if (scaleDom) { + scale.width = parseFloat(((window.innerHeight * baseProportion) / baseWidth).toFixed(5)) + scale.height = parseFloat((window.innerHeight / baseHeight).toFixed(5)) + scaleDom.style.transform = `scale(${scale.width}, ${scale.height})` + if (callback) callback(scale) + } + } + + const resize = throttle(() => { + calcRate() + }, 200) + + // * 改变窗口大小重新绘制 + const windowResize = () => { + window.addEventListener('resize', resize) + } + + // * 卸载监听 + const unWindowResize = () => { + window.removeEventListener('resize', resize) + } + + return { + calcRate, + windowResize, + unWindowResize, + } +} + +// * 变形内容,宽高铺满 +export const usePreviewFullScale = ( + width: number, + height: number, + scaleDom: HTMLElement | null, + callback?: (scale: { + width: number; + height: number; + }) => void +) => { + + // * 默认缩放值 + const scale = { + width: 1, + height: 1, + } + + const calcRate = () => { + if (scaleDom) { + scale.width = parseFloat((window.innerWidth / width).toFixed(5)) + scale.height = parseFloat((window.innerHeight / height).toFixed(5)) + scaleDom.style.transform = `scale(${scale.width}, ${scale.height})` + if (callback) callback(scale) + } + } + + const resize = throttle(() => { + calcRate() + }, 200) + + // * 改变窗口大小重新绘制 + const windowResize = () => { + window.addEventListener('resize', resize) + } + + // * 卸载监听 + const unWindowResize = () => { + window.removeEventListener('resize', resize) + } + + return { + calcRate, + windowResize, + unWindowResize, + } } \ No newline at end of file diff --git a/src/views/preview/hooks/useScale.hook.ts b/src/views/preview/hooks/useScale.hook.ts index 3916c187..b0185383 100644 --- a/src/views/preview/hooks/useScale.hook.ts +++ b/src/views/preview/hooks/useScale.hook.ts @@ -12,7 +12,31 @@ export const useScale = (localStorageInfo: ChartEditStorageType) => { const height = ref(localStorageInfo.editCanvasConfig.height) const scaleRef = ref({ width: 1, height: 1 }) - provide(SCALE_KEY, scaleRef); + provide(SCALE_KEY, scaleRef) + + // 监听鼠标滚轮 +ctrl 键 + const useAddWheelHandle = (removeEvent: Function) => { + addEventListener( + 'wheel', + (e: any) => { + if (window?.$KeyboardActive?.ctrl) { + e.preventDefault() + e.stopPropagation() + removeEvent() + const transform = previewRef.value.style.transform + // 使用正则解析 scale(1, 1) 中的两个数值 + const regRes = transform.match(/scale\((\d+\.?\d*)*/) as RegExpMatchArray + const width = regRes[1] + if (e.wheelDelta > 0) { + previewRef.value.style.transform = `scale(${parseFloat(Number(width).toFixed(2)) + 0.1})` + } else { + previewRef.value.style.transform = `scale(${parseFloat(Number(width).toFixed(2)) - 0.1})` + } + } + }, + { passive: false } + ) + } const updateScaleRef = (scale: { width: number; height: number }) => { // 这里需要解构,保证赋值给scaleRef的为一个新对象 @@ -23,74 +47,82 @@ export const useScale = (localStorageInfo: ChartEditStorageType) => { // 屏幕适配 onMounted(() => { switch (localStorageInfo.editCanvasConfig.previewScaleType) { - case PreviewScaleEnum.FIT: (() => { - const { calcRate, windowResize, unWindowResize } = usePreviewFitScale( - width.value as number, - height.value as number, - previewRef.value, - updateScaleRef - ) - calcRate() - windowResize() - onUnmounted(() => { - unWindowResize() - }) - })() - break; - case PreviewScaleEnum.SCROLL_Y: (() => { - const { calcRate, windowResize, unWindowResize } = usePreviewScrollYScale( - width.value as number, - height.value as number, - previewRef.value, - (scale) => { - const dom = entityRef.value - dom.style.width = `${width.value * scale.width}px` - dom.style.height = `${height.value * scale.height}px` - updateScaleRef(scale) - } - ) - calcRate() - windowResize() - onUnmounted(() => { - unWindowResize() - }) - })() + case PreviewScaleEnum.FIT: + ;(() => { + const { calcRate, windowResize, unWindowResize } = usePreviewFitScale( + width.value as number, + height.value as number, + previewRef.value, + updateScaleRef + ) + calcRate() + windowResize() + useAddWheelHandle(unWindowResize) + onUnmounted(() => { + unWindowResize() + }) + })() + break + case PreviewScaleEnum.SCROLL_Y: + ;(() => { + const { calcRate, windowResize, unWindowResize } = usePreviewScrollYScale( + width.value as number, + height.value as number, + previewRef.value, + scale => { + const dom = entityRef.value + dom.style.width = `${width.value * scale.width}px` + dom.style.height = `${height.value * scale.height}px` + updateScaleRef(scale) + } + ) + calcRate() + windowResize() + useAddWheelHandle(unWindowResize) + onUnmounted(() => { + unWindowResize() + }) + })() - break; - case PreviewScaleEnum.SCROLL_X: (() => { - const { calcRate, windowResize, unWindowResize } = usePreviewScrollXScale( - width.value as number, - height.value as number, - previewRef.value, - (scale) => { - const dom = entityRef.value - dom.style.width = `${width.value * scale.width}px` - dom.style.height = `${height.value * scale.height}px` - updateScaleRef(scale) - } - ) - calcRate() - windowResize() - onUnmounted(() => { - unWindowResize() - }) - })() + break + case PreviewScaleEnum.SCROLL_X: + ;(() => { + const { calcRate, windowResize, unWindowResize } = usePreviewScrollXScale( + width.value as number, + height.value as number, + previewRef.value, + scale => { + const dom = entityRef.value + dom.style.width = `${width.value * scale.width}px` + dom.style.height = `${height.value * scale.height}px` + updateScaleRef(scale) + } + ) + calcRate() + windowResize() + useAddWheelHandle(unWindowResize) + onUnmounted(() => { + unWindowResize() + }) + })() - break; - case PreviewScaleEnum.FULL: (() => { - const { calcRate, windowResize, unWindowResize } = usePreviewFullScale( - width.value as number, - height.value as number, - previewRef.value, - updateScaleRef - ) - calcRate() - windowResize() - onUnmounted(() => { - unWindowResize() - }) - })() - break; + break + case PreviewScaleEnum.FULL: + ;(() => { + const { calcRate, windowResize, unWindowResize } = usePreviewFullScale( + width.value as number, + height.value as number, + previewRef.value, + updateScaleRef + ) + calcRate() + windowResize() + useAddWheelHandle(unWindowResize) + onUnmounted(() => { + unWindowResize() + }) + })() + break } }) diff --git a/src/views/preview/suspenseIndex.vue b/src/views/preview/suspenseIndex.vue index fdc3fdf6..1a1932b9 100644 --- a/src/views/preview/suspenseIndex.vue +++ b/src/views/preview/suspenseIndex.vue @@ -30,7 +30,7 @@ import { computed } from 'vue' import { PreviewRenderList } from './components/PreviewRenderList' import { getFilterStyle, setTitle } from '@/utils' -import { getEditCanvasConfigStyle, getSessionStorageInfo } from './utils' +import { getEditCanvasConfigStyle, getSessionStorageInfo, keyRecordHandle } from './utils' import { useComInstall } from './hooks/useComInstall.hook' import { useScale } from './hooks/useScale.hook' import { useStore } from './hooks/useStore.hook' @@ -60,6 +60,9 @@ const showEntity = computed(() => { useStore(chartEditStore) const { entityRef, previewRef } = useScale(chartEditStore) const { show } = useComInstall(chartEditStore) + +// 开启键盘监听 +keyRecordHandle()