From 012b64f00c4ad2139614a9a481584b050362f044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A5=94=E8=B7=91=E7=9A=84=E9=9D=A2=E6=9D=A1?= <1262327911@qq.com> Date: Fri, 16 Dec 2022 22:18:24 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E7=94=BB=E5=B8=83?= =?UTF-8?q?=E6=8B=96=E6=8B=BD=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/EditRange/index.vue | 2 + .../ContentEdit/components/EditRule/index.vue | 306 ++++++++++++++---- .../ContentEdit/components/EditRule/ruler.vue | 193 ----------- src/views/chart/ContentEdit/index.vue | 71 ++-- 4 files changed, 296 insertions(+), 276 deletions(-) delete mode 100644 src/views/chart/ContentEdit/components/EditRule/ruler.vue diff --git a/src/views/chart/ContentEdit/components/EditRange/index.vue b/src/views/chart/ContentEdit/components/EditRange/index.vue index e8b1b15d..d9a7bcc9 100644 --- a/src/views/chart/ContentEdit/components/EditRange/index.vue +++ b/src/views/chart/ContentEdit/components/EditRange/index.vue @@ -55,6 +55,8 @@ const rangeModelStyle = computed(() => { position: relative; transform-origin: left top; background-size: cover; + border-radius: 20px; + overflow: hidden; @include fetch-border-color('hover-border-color'); @include fetch-bg-color('background-color2'); @include go(edit-range-model) { diff --git a/src/views/chart/ContentEdit/components/EditRule/index.vue b/src/views/chart/ContentEdit/components/EditRule/index.vue index 2e98460f..11baf858 100644 --- a/src/views/chart/ContentEdit/components/EditRule/index.vue +++ b/src/views/chart/ContentEdit/components/EditRule/index.vue @@ -1,49 +1,157 @@ <template> - <sketch-rule - v-if="configShow" - :thick="thick" - :scale="scale" - :width="canvasBox().width" - :height="canvasBox().height" - :startX="startX" - :startY="startY" - :lines="lines" - ></sketch-rule> + <div class="go-sketch-rule"> + <sketch-rule + v-if="sketchRuleReDraw" + :thick="thick" + :scale="scale" + :width="canvasBox().width" + :height="canvasBox().height" + :startX="startX" + :startY="startY" + :lines="lines" + :palette="paletteStyle" + > + </sketch-rule> + <div ref="$app" class="edit-screens" @scroll="handleScroll"> + <div ref="$container" class="edit-screen-container" :style="{ width: width * 2 + 'px' }"> + <div + ref="refSketchRuleBox" + class="canvas" + @mousedown="dragCanvas" + :style="{ marginLeft: '-' + (canvasBox().width / 2 - 25) + 'px' }" + > + <div :style="{ pointerEvents: isPressSpace ? 'none' : 'auto' }"> + <slot></slot> + </div> + </div> + </div> + </div> + <!-- 修复右下角白点用的 --> + <div v-if="designStore.getDarkTheme" class="fix-edit-screens-block"></div> + </div> </template> - <script setup lang="ts"> -import { ref, toRefs, computed, watch, nextTick, onBeforeUnmount } from 'vue' -import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' +import { ref, reactive, onMounted, toRefs, watch, onUnmounted, computed } from 'vue' +import { listen } from 'dom-helpers' import { useDesignStore } from '@/store/modules/designStore/designStore' -import { useChartLayoutStore } from '@/store/modules/chartLayoutStore/chartLayoutStore' +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' const chartEditStore = useChartEditStore() -const chartLayoutStore = useChartLayoutStore() const designStore = useDesignStore() -const { width, height } = toRefs(chartEditStore.getEditCanvasConfig) -const { scale, lockScale } = toRefs(chartEditStore.getEditCanvas) -const { getLayers, getCharts, getDetails } = toRefs(chartLayoutStore) - -const configShow = ref(true) - -// x轴标尺开始的坐标数值 -const startX = -10 -// y轴标尺开始的坐标数值 -const startY = -10 -// 标尺的厚度 const thick = 20 -// 初始化水平标尺上的参考线 -const lines = { - h: [], - v: [] +let prevMoveXVallue = [0, 0] +let prevMoveYVallue = [0, 0] + +const $app = ref() +const sketchRuleReDraw = ref(true) +const refSketchRuleBox = ref() +const $container = ref() +const isPressSpace = ref(false) +const cursorStyle = ref('auto') +const { width, height } = toRefs(chartEditStore.getEditCanvasConfig) +const startX = ref(0) +const startY = ref(0) +const lines = reactive({ h: [], v: [] }) + +const scale = computed(() => { + return chartEditStore.getEditCanvas.scale +}) + +// 滚动条拖动的高度 +const containerWidth = computed(() => { + return `${height.value * 2}px` +}) + +// 主题 +const paletteStyle = computed(() => { + const isDarkTheme = designStore.getDarkTheme + return isDarkTheme + ? { + bgColor: '#18181c', + longfgColor: '#4d4d4d', + shortfgColor: '#4d4d4d', + fontColor: '#4d4d4d', + shadowColor: '#18181c', + borderColor: '#18181c', + cornerActiveColor: '#18181c' + } + : {} +}) + +// 颜色 +const themeColor = computed(() => { + return designStore.getAppTheme +}) + +const handleWheel = (e: any) => { + e.preventDefault() + if (e.ctrlKey || e.metaKey) { + let resScale = scale.value + // 放大(200%) + if (e.wheelDelta >= 0 && scale.value < 2) { + resScale = scale.value + 0.05 + chartEditStore.setScale(resScale) + return + } + // 缩小(10%) + if (e.wheelDelta < 0 && scale.value > 0.1) { + resScale = scale.value - 0.05 + chartEditStore.setScale(resScale) + } + } +} + +const handleScroll = () => { + if (!$app.value) return + const screensRect = $app.value.getBoundingClientRect() + const canvasRect = refSketchRuleBox.value.getBoundingClientRect() + // 标尺开始的刻度 + startX.value = (screensRect.left + thick - canvasRect.left) / scale.value + startY.value = (screensRect.top + thick - canvasRect.top) / scale.value +} + +const dragCanvas = (e: any) => { + if (!window.$KeyboardActive?.space) return + + // @ts-ignore + document.activeElement?.blur() + + e.preventDefault() + e.stopPropagation() + + const startX = e.pageX + const startY = e.pageY + + const listenMousemove = listen(window, 'mousemove', (e: any) => { + const nx = e.pageX - startX + const ny = e.pageY - startY + + const [prevMoveX1, prevMoveX2] = prevMoveXVallue + const [prevMoveY1, prevMoveY2] = prevMoveYVallue + + prevMoveXVallue = [prevMoveX2, nx] + prevMoveYVallue = [prevMoveY2, ny] + + $app.value.scrollLeft -= + prevMoveX2 > prevMoveX1 ? Math.abs(prevMoveX2 - prevMoveX1) : -Math.abs(prevMoveX2 - prevMoveX1) + $app.value.scrollTop -= + prevMoveY2 > prevMoveY1 ? Math.abs(prevMoveY2 - prevMoveY1) : -Math.abs(prevMoveY2 - prevMoveY1) + }) + + const listenMouseup = listen(window, 'mouseup', () => { + listenMousemove() + listenMouseup() + prevMoveXVallue = [0, 0] + prevMoveYVallue = [0, 0] + }) } const canvasBox = () => { const layoutDom = document.getElementById('go-chart-edit-layout') if (layoutDom) { return { - height: layoutDom.clientHeight - 40, + height: layoutDom.clientHeight - 40 - 44, width: layoutDom.clientWidth } } @@ -53,53 +161,61 @@ const canvasBox = () => { } } -// 颜色 -const themeColor = computed(() => { - return designStore.getAppTheme -}) +// 在位置不动的情况下重绘标尺 +const reDraw = () => { + sketchRuleReDraw.value = false + setTimeout(() => { + sketchRuleReDraw.value = true + }, 10) +} + +watch( + () => designStore.getDarkTheme, + () => { + reDraw() + } +) // 处理标尺重制大小 -const ruleChangeHandle = () => { - configShow.value = false - setTimeout(() => { - configShow.value = true - }) -} - -const ruleChangeHandleTimeOut = () => { - if (lockScale.value) { - setTimeout(() => { - ruleChangeHandle() - }, 500) - } -} - watch( () => scale.value, - () => ruleChangeHandle() + (newValue, oldValue) => { + if (oldValue !== newValue) { + handleScroll() + chartEditStore.setScale(newValue) + } + } ) watch( - () => getLayers.value, - () => ruleChangeHandleTimeOut() + () => isPressSpace.value, + newValue => { + cursorStyle.value = newValue ? 'grab' : 'auto' + } ) -watch( - () => getCharts.value, - () => ruleChangeHandleTimeOut() -) +onMounted(() => { + if ($app.value) { + $app.value.addEventListener('wheel', handleWheel, { passive: false }) + // 滚动居中 + $app.value.scrollLeft = $container.value.getBoundingClientRect().width / 2 - canvasBox().width / 2 + } +}) -watch( - () => getDetails.value, - () => ruleChangeHandleTimeOut() -) +onUnmounted(() => { + if ($app.value) { + $app.value.removeEventListener('wheel', handleWheel) + } +}) +window.onKeySpacePressHold = (isHold: boolean) => { + isPressSpace.value = isHold +} </script> <style> /* 使用 SCSS 会报错,直接使用最基础的 CSS 进行修改, 此库有计划 Vue3 版本,但是开发的时候还没发布 */ - #mb-ruler { top: 0; left: 0; @@ -142,3 +258,69 @@ watch( border-width: 0 !important; } </style> + +<style lang="scss" scoped> +@include go('sketch-rule') { + position: relative; + overflow: hidden; + width: 100%; + height: 100%; + + .edit-screens { + position: absolute; + width: 100%; + height: 100%; + overflow: auto; + user-select: none; + padding-bottom: 0px; + + /* firefox */ + scrollbar-color: rgba(144, 146, 152, 0.3) transparent; + scrollbar-width: thin; + + /* chrome */ + &::-webkit-scrollbar, + &::-webkit-scrollbar-track-piece { + background-color: transparent; + } + + &::-webkit-scrollbar { + width: 7px; + } + + &::-webkit-scrollbar-thumb { + border-radius: 5px; + background-color: rgba(144, 146, 152, 0.3); + } + } + + .fix-edit-screens-block { + position: absolute; + bottom: 0; + right: 0; + width: 10px; + height: 10px; + background-color: $--color-dark-bg-1; + } + + .edit-screen-container { + position: absolute; + height: v-bind('containerWidth'); + } + + .canvas { + position: absolute; + top: 80px; + left: 50%; + transform-origin: 50% 0; + + &:hover { + cursor: v-bind('cursorStyle'); + } + + &:active { + cursor: crosshair; + } + } +} +</style> diff --git a/src/views/chart/ContentEdit/components/EditRule/ruler.vue b/src/views/chart/ContentEdit/components/EditRule/ruler.vue deleted file mode 100644 index 79668649..00000000 --- a/src/views/chart/ContentEdit/components/EditRule/ruler.vue +++ /dev/null @@ -1,193 +0,0 @@ -<template> - <div :style="{ position: 'relative', overflow: 'hidden', width: '100%', height: '100%' }"> - <sketch-rule :thick="thick" :scale="scale" :width="canvasBox().width" :height="canvasBox().height" - :startX="startX" :startY="startY" :lines="lines" - :palette="{ bgColor: '#18181c', longfgColor: '#4d4d4d', shortfgColor: '#4d4d4d', fontColor: '#4d4d4d', shadowColor: '#18181c', borderColor: '#18181c', cornerActiveColor: '#18181c' }"> - </sketch-rule> - <div ref="$app" class="screens" @scroll="handleScroll"> - <div ref="$container" class="screenContainer" :style="{ width: screenContainerWidth + 'px' }"> - <div id="refcanvasBox" ref="refcanvasBox" class="canvas" @mousedown="dragCanvas" - :style="{ marginLeft: '-' + (canvasBox().width / 2 - 25) + 'px' }"> - <div :style="{ pointerEvents: isPressSpace ? 'none' : 'auto' }"> - <slot></slot> - </div> - </div> - </div> - </div> - </div> -</template> -<script setup lang="ts"> -import { ref, reactive, onMounted, toRefs, watch, onUnmounted, computed } from 'vue' -import { listen } from "dom-helpers" - -import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' - -const chartEditStore = useChartEditStore() - -const thick = 20 -const screenContainerWidth = 5000 -var prevMoveXVallue = [0, 0] -var prevMoveYVallue = [0, 0] - -const $app = ref() -const refcanvasBox = ref() -const $container = ref() - -const scale = computed(() => { - return chartEditStore.getEditCanvas.scale -}) -const startX = ref(0) -const startY = ref(0) -const lines = reactive({ h: [], v: [] }) - -const handleWheel = (e: any) => { - e.preventDefault() - if (e.ctrlKey || e.metaKey) { - // const nextScale = parseFloat(Math.max(.2, scale.value - e.deltaY / canvasBox().height).toFixed(2)) - // chartEditStore.setScale(nextScale) - - chartEditStore.setScale(e.wheelDelta >= 120 ? scale.value + 0.01 : e.wheelDelta <= 120 ? scale.value - 0.01 : scale.value) - } -} - -const isPressSpace = ref(false) -const cursorStyle = ref('auto') - -window.onKeySpacePressHold = (isHold: boolean) => { - isPressSpace.value = isHold -} -watch( - () => isPressSpace.value, - newValue => { - cursorStyle.value = newValue ? 'grab' : 'auto' - } -) - -onMounted(() => { - $app.value.addEventListener('wheel', handleWheel, { passive: false }) - // 滚动居中 - $app.value.scrollLeft = $container.value.getBoundingClientRect().width / 2 - canvasBox().width / 2 - -}) - -const handleScroll = () => { - const screensRect = $app.value.getBoundingClientRect() - const canvasRect = refcanvasBox.value.getBoundingClientRect() - - // 标尺开始的刻度 - startX.value = (screensRect.left + thick - canvasRect.left) / scale.value - startY.value = (screensRect.top + thick - canvasRect.top) / scale.value -} -// 处理标尺重制大小 -watch( - () => scale.value, - (newValue, oldValue) => { - if (oldValue !== newValue) { - handleScroll() - chartEditStore.setScale(newValue) - } - } -) - -onUnmounted(() => { - $app.value.removeEventListener('wheel', handleWheel) -}) - -const dragCanvas = (e: any) => { - if (!window.$KeyboardActive?.space) return - - // @ts-ignore - document.activeElement?.blur() - - e.preventDefault() - e.stopPropagation() - - const startX = e.pageX - const startY = e.pageY - - const un1 = listen(window, "mousemove", (e: any) => { - - const nx = e.pageX - startX - const ny = e.pageY - startY - - const [prevMoveX1, prevMoveX2] = prevMoveXVallue - const [prevMoveY1, prevMoveY2] = prevMoveYVallue - - prevMoveXVallue = [prevMoveX2, nx] - prevMoveYVallue = [prevMoveY2, ny] - - $app.value.scrollLeft -= prevMoveX2 > prevMoveX1 ? Math.abs(prevMoveX2 - prevMoveX1) : -Math.abs(prevMoveX2 - prevMoveX1) - $app.value.scrollTop -= prevMoveY2 > prevMoveY1 ? Math.abs(prevMoveY2 - prevMoveY1) : -Math.abs(prevMoveY2 - prevMoveY1) - }) - const un2 = listen(window, "mouseup", () => { - un1() - un2() - prevMoveXVallue = [0, 0] - prevMoveYVallue = [0, 0] - }) -} - -const { width, height } = toRefs(chartEditStore.getEditCanvasConfig) - -const canvasBox = () => { - const layoutDom = document.getElementById('go-chart-edit-layout') - if (layoutDom) { - return { - height: layoutDom.clientHeight - 40 - 44, - width: layoutDom.clientWidth - } - } - return { - width: width.value, - height: height.value - } -} -</script> -<style lang="scss" scoped> -.screens { - position: absolute; - width: 100%; - height: 100%; - overflow: auto; - user-select: none; - - /* firefox */ - scrollbar-color: rgba(144, 146, 152, .3) transparent; - scrollbar-width: thin; - - /* chrome */ - &::-webkit-scrollbar, - &::-webkit-scrollbar-track-piece { - background-color: transparent; - } - - &::-webkit-scrollbar { - width: 7px; - } - - &::-webkit-scrollbar-thumb { - border-radius: 5px; - background-color: rgba(144, 146, 152, .3); - } -} - -.screenContainer { - position: absolute; - height: 3000px; -} - -.canvas { - position: absolute; - top: 80px; - left: 50%; - transform-origin: 50% 0; - - &:hover { - cursor: v-bind('cursorStyle'); - } - - &:active { - cursor: crosshair; - } -} -</style> \ No newline at end of file diff --git a/src/views/chart/ContentEdit/index.vue b/src/views/chart/ContentEdit/index.vue index f43d426f..2598f65f 100644 --- a/src/views/chart/ContentEdit/index.vue +++ b/src/views/chart/ContentEdit/index.vue @@ -1,43 +1,74 @@ <template> <!-- <edit-rule></edit-rule> --> - <content-box id="go-chart-edit-layout" :flex="true" :showTop="false" :showBottom="true" :depth="1" :xScroll="true" :disabledScroll="true" - @mousedown="mousedownHandleUnStop" @drop="dragHandle" @dragover="dragoverHandle" @dragenter="dragoverHandle"> - <ruler> + <content-box + id="go-chart-edit-layout" + :flex="true" + :showTop="false" + :showBottom="true" + :depth="1" + :xScroll="true" + :disabledScroll="true" + @mousedown="mousedownHandleUnStop" + @drop="dragHandle" + @dragover="dragoverHandle" + @dragenter="dragoverHandle" + > + <edit-rule> <!-- 画布主体 --> <div id="go-chart-edit-content" @contextmenu="handleContextMenu"> <!-- 展示 --> <edit-range> <!-- 滤镜预览 --> - <div :style="{ - ...getFilterStyle(chartEditStore.getEditCanvasConfig), - ...rangeStyle - }"> + <div + :style="{ + ...getFilterStyle(chartEditStore.getEditCanvasConfig), + ...rangeStyle + }" + > <!-- 图表 --> <div v-for="(item, index) in chartEditStore.getComponentList" :key="item.id"> <!-- 分组 --> - <edit-group v-if="item.isGroup" :groupData="(item as CreateComponentGroupType)" - :groupIndex="index"></edit-group> + <edit-group + v-if="item.isGroup" + :groupData="(item as CreateComponentGroupType)" + :groupIndex="index" + ></edit-group> <!-- 单组件 --> - <edit-shape-box v-else :data-id="item.id" :index="index" :style="{ + <edit-shape-box + v-else + :data-id="item.id" + :index="index" + :style="{ ...useComponentStyle(item.attr, index), ...getBlendModeStyle(item.styles) as any - }" :item="item" @click="mouseClickHandle($event, item)" @mousedown="mousedownHandle($event, item)" - @mouseenter="mouseenterHandle($event, item)" @mouseleave="mouseleaveHandle($event, item)" - @contextmenu="handleContextMenu($event, item, optionsHandle)"> - <component class="edit-content-chart" :class="animationsClass(item.styles.animations)" - :is="item.chartConfig.chartKey" :chartConfig="item" :themeSetting="themeSetting" - :themeColor="themeColor" :style="{ + }" + :item="item" + @click="mouseClickHandle($event, item)" + @mousedown="mousedownHandle($event, item)" + @mouseenter="mouseenterHandle($event, item)" + @mouseleave="mouseleaveHandle($event, item)" + @contextmenu="handleContextMenu($event, item, optionsHandle)" + > + <component + class="edit-content-chart" + :class="animationsClass(item.styles.animations)" + :is="item.chartConfig.chartKey" + :chartConfig="item" + :themeSetting="themeSetting" + :themeColor="themeColor" + :style="{ ...useSizeStyle(item.attr), ...getFilterStyle(item.styles), ...getTransformStyle(item.styles) - }"></component> + }" + ></component> </edit-shape-box> </div> </div> </edit-range> </div> - </ruler> + </edit-rule> <!-- 工具栏 --> <template #aside> @@ -69,8 +100,7 @@ import { useComponentStyle, useSizeStyle } from './hooks/useStyle.hook' import { ContentBox } from '../ContentBox/index' import { EditGroup } from './components/EditGroup' import { EditRange } from './components/EditRange' -// import { EditRule } from './components/EditRule' -import Ruler from './components/EditRule/ruler.vue' +import { EditRule } from './components/EditRule' import { EditBottom } from './components/EditBottom' import { EditShapeBox } from './components/EditShapeBox' import { EditTools } from './components/EditTools' @@ -161,7 +191,6 @@ onMounted(() => { @include goId('chart-edit-content') { border-radius: 10px; - margin: 25px; overflow: hidden; @extend .go-transition; @include fetch-theme('box-shadow');