fix: 画布拖拽

This commit is contained in:
jeo young 2022-12-16 18:35:10 +08:00
parent a5f14238f5
commit 3ff687bd54
10 changed files with 321 additions and 95 deletions

View File

@ -21,6 +21,7 @@
"axios": "^0.27.2", "axios": "^0.27.2",
"color": "^4.2.3", "color": "^4.2.3",
"crypto-js": "^4.1.1", "crypto-js": "^4.1.1",
"dom-helpers": "^5.2.1",
"echarts-liquidfill": "^3.1.0", "echarts-liquidfill": "^3.1.0",
"echarts-stat": "^1.2.0", "echarts-stat": "^1.2.0",
"echarts-wordcloud": "^2.0.0", "echarts-wordcloud": "^2.0.0",

32
pnpm-lock.yaml generated
View File

@ -25,6 +25,7 @@ specifiers:
commitlint: ^17.0.2 commitlint: ^17.0.2
crypto-js: ^4.1.1 crypto-js: ^4.1.1
default-passive-events: ^2.0.0 default-passive-events: ^2.0.0
dom-helpers: ^5.2.1
echarts: ^5.3.2 echarts: ^5.3.2
echarts-liquidfill: ^3.1.0 echarts-liquidfill: ^3.1.0
echarts-stat: ^1.2.0 echarts-stat: ^1.2.0
@ -77,6 +78,7 @@ dependencies:
axios: 0.27.2 axios: 0.27.2
color: 4.2.3 color: 4.2.3
crypto-js: 4.1.1 crypto-js: 4.1.1
dom-helpers: 5.2.1
echarts-liquidfill: 3.1.0_echarts@5.3.3 echarts-liquidfill: 3.1.0_echarts@5.3.3
echarts-stat: 1.2.0 echarts-stat: 1.2.0
echarts-wordcloud: 2.0.0_echarts@5.3.3 echarts-wordcloud: 2.0.0_echarts@5.3.3
@ -402,6 +404,13 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@babel/runtime/7.20.6:
resolution: {integrity: sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==}
engines: {node: '>=6.9.0'}
dependencies:
regenerator-runtime: 0.13.11
dev: false
/@babel/template/7.16.7: /@babel/template/7.16.7:
resolution: {integrity: sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==} resolution: {integrity: sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@ -1238,7 +1247,6 @@ packages:
dependencies: dependencies:
'@vue/reactivity': 3.2.37 '@vue/reactivity': 3.2.37
'@vue/shared': 3.2.37 '@vue/shared': 3.2.37
dev: false
/@vue/runtime-dom/3.2.37: /@vue/runtime-dom/3.2.37:
resolution: {integrity: sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw==} resolution: {integrity: sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw==}
@ -1246,7 +1254,6 @@ packages:
'@vue/runtime-core': 3.2.37 '@vue/runtime-core': 3.2.37
'@vue/shared': 3.2.37 '@vue/shared': 3.2.37
csstype: 2.6.20 csstype: 2.6.20
dev: false
/@vue/server-renderer/3.2.37_vue@3.2.37: /@vue/server-renderer/3.2.37_vue@3.2.37:
resolution: {integrity: sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA==} resolution: {integrity: sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA==}
@ -1256,7 +1263,6 @@ packages:
'@vue/compiler-ssr': 3.2.37 '@vue/compiler-ssr': 3.2.37
'@vue/shared': 3.2.37 '@vue/shared': 3.2.37
vue: 3.2.37 vue: 3.2.37
dev: false
/@vue/shared/3.2.37: /@vue/shared/3.2.37:
resolution: {integrity: sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==} resolution: {integrity: sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==}
@ -1833,8 +1839,8 @@ packages:
engines: {node: '>=10'} engines: {node: '>=10'}
hasBin: true hasBin: true
dependencies: dependencies:
is-text-path: 1.0.1
JSONStream: 1.3.5 JSONStream: 1.3.5
is-text-path: 1.0.1
lodash: 4.17.21 lodash: 4.17.21
meow: 8.1.2 meow: 8.1.2
split2: 3.2.2 split2: 3.2.2
@ -1913,7 +1919,6 @@ packages:
/csstype/2.6.20: /csstype/2.6.20:
resolution: {integrity: sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/csstype/-/csstype-2.6.20.tgz} resolution: {integrity: sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/csstype/-/csstype-2.6.20.tgz}
dev: false
/csstype/3.0.11: /csstype/3.0.11:
resolution: {integrity: sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==} resolution: {integrity: sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==}
@ -2065,6 +2070,13 @@ packages:
resolution: {integrity: sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==} resolution: {integrity: sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==}
dev: true dev: true
/dom-helpers/5.2.1:
resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==}
dependencies:
'@babel/runtime': 7.20.6
csstype: 3.0.11
dev: false
/dom-serializer/1.4.1: /dom-serializer/1.4.1:
resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==}
dependencies: dependencies:
@ -2131,7 +2143,6 @@ packages:
dependencies: dependencies:
tslib: 2.3.0 tslib: 2.3.0
zrender: 5.3.2 zrender: 5.3.2
dev: true
/ee-first/1.1.1: /ee-first/1.1.1:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
@ -3812,7 +3823,6 @@ packages:
/monaco-editor/0.33.0: /monaco-editor/0.33.0:
resolution: {integrity: sha512-VcRWPSLIUEgQJQIE0pVT8FcGBIgFoxz7jtqctE+IiCxWugD0DwgyQBcZBhdSrdMC84eumoqMZsGl2GTreOzwqw==} resolution: {integrity: sha512-VcRWPSLIUEgQJQIE0pVT8FcGBIgFoxz7jtqctE+IiCxWugD0DwgyQBcZBhdSrdMC84eumoqMZsGl2GTreOzwqw==}
dev: false
/ms/2.0.0: /ms/2.0.0:
resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
@ -4462,6 +4472,10 @@ packages:
strip-indent: 3.0.0 strip-indent: 3.0.0
dev: true dev: true
/regenerator-runtime/0.13.11:
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
dev: false
/regexp.prototype.flags/1.4.3: /regexp.prototype.flags/1.4.3:
resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -4954,7 +4968,6 @@ packages:
/tslib/2.3.0: /tslib/2.3.0:
resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==} resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==}
dev: true
/tslib/2.4.0: /tslib/2.4.0:
resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==}
@ -5006,7 +5019,6 @@ packages:
resolution: {integrity: sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==} resolution: {integrity: sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==}
engines: {node: '>=4.2.0'} engines: {node: '>=4.2.0'}
hasBin: true hasBin: true
dev: true
/typescript/4.7.3: /typescript/4.7.3:
resolution: {integrity: sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==} resolution: {integrity: sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==}
@ -5426,7 +5438,6 @@ packages:
'@vue/runtime-dom': 3.2.37 '@vue/runtime-dom': 3.2.37
'@vue/server-renderer': 3.2.37_vue@3.2.37 '@vue/server-renderer': 3.2.37_vue@3.2.37
'@vue/shared': 3.2.37 '@vue/shared': 3.2.37
dev: false
/vue3-lazyload/0.2.5-beta_2yymnzrok6eda47acnj2yjm3ae: /vue3-lazyload/0.2.5-beta_2yymnzrok6eda47acnj2yjm3ae:
resolution: {integrity: sha512-GVhJfL9Hcu+AvWsYmUwODivvt+gzpT0ztgAzZaUduoiTaGCv/qzhr0VwAQXfjGF3XFYFyOJsHlAi3/WE0P8XTQ==} resolution: {integrity: sha512-GVhJfL9Hcu+AvWsYmUwODivvt+gzpT0ztgAzZaUduoiTaGCv/qzhr0VwAQXfjGF3XFYFyOJsHlAi3/WE0P8XTQ==}
@ -5592,4 +5603,3 @@ packages:
resolution: {integrity: sha512-8IiYdfwHj2rx0UeIGZGGU4WEVSDEdeVCaIg/fomejg1Xu6OifAL1GVzIPHg2D+MyUkbNgPWji90t0a8IDk+39w==} resolution: {integrity: sha512-8IiYdfwHj2rx0UeIGZGGU4WEVSDEdeVCaIg/fomejg1Xu6OifAL1GVzIPHg2D+MyUkbNgPWji90t0a8IDk+39w==}
dependencies: dependencies:
tslib: 2.3.0 tslib: 2.3.0
dev: true

View File

@ -67,7 +67,8 @@ export enum WinKeyboard {
ALT = ' alt', ALT = ' alt',
CTRL_SOURCE_KEY = 'control', CTRL_SOURCE_KEY = 'control',
SHIFT_SOURCE_KEY = 'shift', SHIFT_SOURCE_KEY = 'shift',
ALT_SOURCE_KEY = 'alt' ALT_SOURCE_KEY = 'alt',
SPACE='Space'
} }
// Mac 键盘枚举 // Mac 键盘枚举

View File

@ -273,15 +273,21 @@ export const objToCookie = (obj: RequestParamsObjType) => {
* @returns * @returns
*/ */
export const setKeyboardDressShow = (keyCode?: number) => { export const setKeyboardDressShow = (keyCode?: number) => {
const code = new Map([[17, WinKeyboard.CTRL]]) const code = new Map([
[17, WinKeyboard.CTRL],
[32, WinKeyboard.SPACE]
])
const dom = document.getElementById('keyboard-dress-show') const dom = document.getElementById('keyboard-dress-show')
if (!dom) return if (!dom) return
if (!keyCode) { if (!keyCode) {
window.onKeySpacePressHold?.(false)
dom.innerText = '' dom.innerText = ''
return return
} }
if (keyCode && code.has(keyCode)) { if (keyCode && code.has(keyCode)) {
window.onKeySpacePressHold?.(true)
dom.innerText = `按下了「${code.get(keyCode)}」键` dom.innerText = `按下了「${code.get(keyCode)}」键`
} }
} }

View File

@ -18,14 +18,14 @@
</n-space> </n-space>
</div> </div>
<div <div class="content" :class="{
class="content" 'content-height-show-top-bottom': showBottom || showTop,
:class="{ 'content-height-show-both': showBottom && showTop
'content-height-show-top-bottom': showBottom || showTop, }">
'content-height-show-both': showBottom && showTop <template v-if="disabledScroll">
}" <slot></slot>
> </template>
<template v-if="xScroll"> <template v-else-if="xScroll">
<n-scrollbar x-scrollable> <n-scrollbar x-scrollable>
<n-scrollbar> <n-scrollbar>
<slot></slot> <slot></slot>
@ -83,6 +83,11 @@ defineProps({
xScroll: { xScroll: {
type: Boolean, type: Boolean,
default: false default: false
},
//使
disabledScroll: {
type: Boolean,
default: false
} }
}) })
@ -93,41 +98,52 @@ const backHandle = () => {
<style lang="scss" scoped> <style lang="scss" scoped>
$topOrBottomHeight: 40px; $topOrBottomHeight: 40px;
@include go(content-box) { @include go(content-box) {
height: calc(100vh - #{$--header-height}); height: calc(100vh - #{$--header-height});
margin: 1px; margin: 1px;
margin-bottom: 0; margin-bottom: 0;
&.bg-depth0 { &.bg-depth0 {
@include fetch-bg-color('background-color1'); @include fetch-bg-color('background-color1');
.bottom, .bottom,
.top { .top {
@include fetch-bg-color('background-color1'); @include fetch-bg-color('background-color1');
} }
} }
&.bg-depth1 { &.bg-depth1 {
@include fetch-bg-color('background-color1'); @include fetch-bg-color('background-color1');
.bottom, .bottom,
.top { .top {
@include fetch-bg-color('background-color2'); @include fetch-bg-color('background-color2');
} }
} }
&.bg-depth2 { &.bg-depth2 {
@include fetch-bg-color('background-color2'); @include fetch-bg-color('background-color2');
.bottom, .bottom,
.top { .top {
@include fetch-bg-color('background-color3'); @include fetch-bg-color('background-color3');
} }
} }
&.bg-depth3 { &.bg-depth3 {
@include fetch-bg-color('background-color3'); @include fetch-bg-color('background-color3');
.bottom, .bottom,
.top { .top {
@include fetch-bg-color('background-color4'); @include fetch-bg-color('background-color4');
} }
} }
&.flex { &.flex {
flex: 1; flex: 1;
} }
.top, .top,
.bottom { .bottom {
display: flex; display: flex;
@ -138,10 +154,12 @@ $topOrBottomHeight: 40px;
padding: 0 10px; padding: 0 10px;
border-top: 1px solid; border-top: 1px solid;
@include fetch-border-color('hover-border-color'); @include fetch-border-color('hover-border-color');
.mt-1 { .mt-1 {
margin-top: 2px; margin-top: 2px;
} }
} }
.top { .top {
border-bottom: 1px solid; border-bottom: 1px solid;
@include fetch-border-color('background-color1'); @include fetch-border-color('background-color1');
@ -159,6 +177,7 @@ $topOrBottomHeight: 40px;
.content-height-show-top-bottom { .content-height-show-top-bottom {
height: calc(100vh - #{$--header-height} - #{$topOrBottomHeight}); height: calc(100vh - #{$--header-height} - #{$topOrBottomHeight});
} }
.content-height-show-both { .content-height-show-both {
height: calc(100vh - #{$--header-height} - #{$topOrBottomHeight} - #{$topOrBottomHeight}); height: calc(100vh - #{$--header-height} - #{$topOrBottomHeight} - #{$topOrBottomHeight});
} }

View File

@ -0,0 +1,199 @@
<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()
//
const _startX = (screensRect.left + thick - canvasRect.left) / scale.value
const _startY = (screensRect.top + thick - canvasRect.top) / scale.value
startX.value = _startX
startY.value = _startY
}
//
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 isShowReferLine = ref(true)
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
}
}
const cornerClick = () => {
isShowReferLine.value = !isShowReferLine.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>

View File

@ -1,72 +1,44 @@
<template> <template>
<edit-rule></edit-rule> <!-- <edit-rule></edit-rule> -->
<content-box <content-box id="go-chart-edit-layout" :flex="true" :showTop="false" :showBottom="true" :depth="1" :xScroll="true"
id="go-chart-edit-layout" :disabledScroll="true" @mousedown="mousedownHandleUnStop" @drop="dragHandle" @dragover="dragoverHandle"
:flex="true" @dragenter="dragoverHandle">
:showTop="false" <ruler>
:showBottom="true" <!-- 画布主体 -->
:depth="1" <div id="go-chart-edit-content" @contextmenu="handleContextMenu">
:xScroll="true" <!-- 展示 -->
@mousedown="mousedownHandleUnStop" <edit-range>
@drop="dragHandle" <!-- 滤镜预览 -->
@dragover="dragoverHandle" <div :style="{
@dragenter="dragoverHandle"
>
<!-- 画布主体 -->
<div id="go-chart-edit-content" @contextmenu="handleContextMenu">
<!-- 展示 -->
<edit-range>
<!-- 滤镜预览 -->
<div
:style="{
...getFilterStyle(chartEditStore.getEditCanvasConfig), ...getFilterStyle(chartEditStore.getEditCanvasConfig),
...rangeStyle ...rangeStyle
}" }">
> <!-- 图表 -->
<!-- 图表 --> <div v-for="(item, index) in chartEditStore.getComponentList" :key="item.id">
<div v-for="(item, index) in chartEditStore.getComponentList" :key="item.id"> <!-- 分组 -->
<!-- 分组 --> <edit-group v-if="item.isGroup" :groupData="(item as CreateComponentGroupType)"
<edit-group :groupIndex="index"></edit-group>
v-if="item.isGroup"
:groupData="(item as CreateComponentGroupType)"
:groupIndex="index"
></edit-group>
<!-- 单组件 --> <!-- 单组件 -->
<edit-shape-box <edit-shape-box v-else :data-id="item.id" :index="index" :style="{
v-else
:data-id="item.id"
:index="index"
:style="{
...useComponentStyle(item.attr, index), ...useComponentStyle(item.attr, index),
...getBlendModeStyle(item.styles) as any ...getBlendModeStyle(item.styles) as any
}" }" :item="item" @click="mouseClickHandle($event, item)" @mousedown="mousedownHandle($event, item)"
:item="item" @mouseenter="mouseenterHandle($event, item)" @mouseleave="mouseleaveHandle($event, item)"
@click="mouseClickHandle($event, item)" @contextmenu="handleContextMenu($event, item, optionsHandle)">
@mousedown="mousedownHandle($event, item)" <component class="edit-content-chart" :class="animationsClass(item.styles.animations)"
@mouseenter="mouseenterHandle($event, item)" :is="item.chartConfig.chartKey" :chartConfig="item" :themeSetting="themeSetting"
@mouseleave="mouseleaveHandle($event, item)" :themeColor="themeColor" :style="{
@contextmenu="handleContextMenu($event, item, optionsHandle)" ...useSizeStyle(item.attr),
> ...getFilterStyle(item.styles),
<component ...getTransformStyle(item.styles)
class="edit-content-chart" }"></component>
:class="animationsClass(item.styles.animations)" </edit-shape-box>
:is="item.chartConfig.chartKey" </div>
:chartConfig="item"
:themeSetting="themeSetting"
:themeColor="themeColor"
:style="{
...useSizeStyle(item.attr),
...getFilterStyle(item.styles),
...getTransformStyle(item.styles)
}"
></component>
</edit-shape-box>
</div> </div>
</div> </edit-range>
</edit-range> </div>
</div> </ruler>
<!-- 工具栏 --> <!-- 工具栏 -->
<template #aside> <template #aside>
<edit-tools></edit-tools> <edit-tools></edit-tools>
@ -97,10 +69,11 @@ import { useComponentStyle, useSizeStyle } from './hooks/useStyle.hook'
import { ContentBox } from '../ContentBox/index' import { ContentBox } from '../ContentBox/index'
import { EditGroup } from './components/EditGroup' import { EditGroup } from './components/EditGroup'
import { EditRange } from './components/EditRange' import { EditRange } from './components/EditRange'
import { EditRule } from './components/EditRule' // import { EditRule } from './components/EditRule'
import { EditBottom } from './components/EditBottom' import { EditBottom } from './components/EditBottom'
import { EditShapeBox } from './components/EditShapeBox' import { EditShapeBox } from './components/EditShapeBox'
import { EditTools } from './components/EditTools' import { EditTools } from './components/EditTools'
import Ruler from './components/EditRule/ruler.vue'
const chartEditStore = useChartEditStore() const chartEditStore = useChartEditStore()
const { handleContextMenu } = useContextMenu() const { handleContextMenu } = useContextMenu()
@ -185,12 +158,14 @@ onMounted(() => {
overflow: hidden; overflow: hidden;
@extend .go-point-bg; @extend .go-point-bg;
@include background-image('background-point'); @include background-image('background-point');
@include goId('chart-edit-content') { @include goId('chart-edit-content') {
border-radius: 10px; border-radius: 10px;
margin: 25px; margin: 25px;
overflow: hidden; overflow: hidden;
@extend .go-transition; @extend .go-transition;
@include fetch-theme('box-shadow'); @include fetch-theme('box-shadow');
.edit-content-chart { .edit-content-chart {
position: absolute; position: absolute;
overflow: hidden; overflow: hidden;

View File

@ -110,21 +110,33 @@ const macKeyList: Array<string> = [
const keyRecordHandle = () => { const keyRecordHandle = () => {
// 默认赋值 // 默认赋值
window.$KeyboardActive = { window.$KeyboardActive = {
ctrl: false ctrl: false,
space: false
} }
document.onkeydown = (e: KeyboardEvent) => { document.onkeydown = (e: KeyboardEvent) => {
if(e.keyCode === 17 && window.$KeyboardActive) { const { keyCode } = e
if (keyCode == 32 && e.target == document.body) e.preventDefault()
if ([17, 32].includes(keyCode) && window.$KeyboardActive) {
setKeyboardDressShow(e.keyCode) setKeyboardDressShow(e.keyCode)
window.$KeyboardActive.ctrl = true switch (keyCode) {
case 17: window.$KeyboardActive.ctrl = true; break
case 32: window.$KeyboardActive.space = true; break
}
} }
} }
document.onkeyup = (e: KeyboardEvent) => { document.onkeyup = (e: KeyboardEvent) => {
if(e.keyCode === 17 && window.$KeyboardActive) const { keyCode } = e
{ if (keyCode == 32 && e.target == document.body) e.preventDefault()
window.$KeyboardActive.ctrl = false
if ([17, 32].includes(keyCode) && window.$KeyboardActive) {
setKeyboardDressShow() setKeyboardDressShow()
switch (keyCode) {
case 17: window.$KeyboardActive.ctrl = false; break
case 32: window.$KeyboardActive.space = false; break
}
} }
} }
} }
@ -176,7 +188,7 @@ export const useAddKeyboard = () => {
case keyboardValue.forward: case keyboardValue.forward:
keymaster(e, throttle(() => { chartEditStore.setForward(); return false }, throttleTime)) keymaster(e, throttle(() => { chartEditStore.setForward(); return false }, throttleTime))
break; break;
// 创建分组 ct+g // 创建分组 ct+g
case keyboardValue.group: case keyboardValue.group:
keymaster(e, throttle(() => { chartEditStore.setGroup(); return false }, throttleTime)) keymaster(e, throttle(() => { chartEditStore.setGroup(); return false }, throttleTime))
@ -217,8 +229,8 @@ export const useAddKeyboard = () => {
// 卸载监听事件 // 卸载监听事件
export const useRemoveKeyboard = () => { export const useRemoveKeyboard = () => {
document.onkeydown = () => {}; document.onkeydown = () => { };
document.onkeyup = () => {}; document.onkeyup = () => { };
winKeyList.forEach((key: string) => { winKeyList.forEach((key: string) => {
keymaster.unbind(key) keymaster.unbind(key)

2
types/global.d.ts vendored
View File

@ -7,6 +7,8 @@ interface Window {
$vue: any $vue: any
// 键盘按键记录 // 键盘按键记录
$KeyboardActive?: { [T: string]: boolean } $KeyboardActive?: { [T: string]: boolean }
//当空格按下
onKeySpacePressHold?: Function
// 编辑 JSON 的存储对象 // 编辑 JSON 的存储对象
opener: any opener: any
} }

View File

@ -4,4 +4,5 @@ declare module '*.vue' {
export default component export default component
} }
declare module 'lodash/*' declare module 'lodash/*'
declare module 'dom-helpers'