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');