Skip to content

Commit

Permalink
perf: gkd-w, BodyScrollbar
Browse files Browse the repository at this point in the history
  • Loading branch information
lisonge committed Dec 14, 2024
1 parent 93f2969 commit 1943400
Show file tree
Hide file tree
Showing 8 changed files with 216 additions and 17 deletions.
21 changes: 15 additions & 6 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,35 @@
import { dateZhCN, zhCN } from 'naive-ui';
import { RouterView } from 'vue-router';
import ErrorDlg from './components/ErrorDlg.vue';
import { ScrollbarWrapper } from './utils/others';
</script>
<template>
<NConfigProvider :locale="zhCN" :date-locale="dateZhCN" abstract>
<ErrorDlg />
<RouterView />
</NConfigProvider>
<ScrollbarWrapper />
</template>
<style lang="scss">
$winMinWidth: 1200px;
$winMinHeight: 700px;
:root {
--gkd-width: max(1200px, 100vw);
--gkd-height: max(700px, 100vh);
--gkd-w: max(#{$winMinWidth}, 100vw);
--gkd-h: max(#{$winMinHeight}, 100vh);
}
body {
&:not(.mobile) {
width: var(--gkd-w);
}
}
#app {
display: flex;
flex-direction: column;
width: var(--gkd-width);
height: var(--gkd-height);
&.mobile {
--gkd-width: 100vw;
&:not(.app-auto-h) {
height: var(--gkd-h);
}
}
.gkd_code,
Expand Down
169 changes: 169 additions & 0 deletions src/components/BodyScrollbar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
<script setup lang="ts">
import type { CSSProperties } from 'vue';
const { y, x } = useWindowScroll();
const { height: winH, width: winW } = useWindowSize();
const body = useElementBounding(document.body);
const yShow = computed(() => body.height.value > winH.value);
const yHeight = computed(() => {
const clientHeight = body.height.value;
const bodyHeight = clientHeight;
return (winH.value / bodyHeight) * winH.value;
});
const translateY = computed(() => {
const clientHeight = body.height.value;
const height = yHeight.value;
return (y.value / (clientHeight - winH.value)) * (winH.value - height);
});
const yStyle = computed<CSSProperties>(() => {
if (!yShow.value) return {};
return {
transform: `translateY(${translateY.value}px)`,
height: `${yHeight.value}px`,
};
});
const clickBoxY = async (e: MouseEvent) => {
const deltaY =
yHeight.value *
0.9 *
(e.clientY < yHeight.value + translateY.value ? -1 : 1);
const clientHeight = body.height.value;
const bodyHeight = clientHeight;
const height = (winH.value / bodyHeight) * winH.value;
y.value += (deltaY / (winH.value - height)) * (clientHeight - winH.value);
};
const yDragging = shallowRef(false);
let lastYEvent: MouseEvent | undefined = undefined;
const pointerdownY = (e: MouseEvent) => {
lastYEvent = e;
yDragging.value = true;
};
useEventListener('pointermove', (e) => {
if (!lastYEvent) return;
const deltaY = e.clientY - lastYEvent.clientY;
lastYEvent = e;
const clientHeight = body.height.value;
const bodyHeight = clientHeight;
const height = (winH.value / bodyHeight) * winH.value;
y.value += (deltaY / (winH.value - height)) * (clientHeight - winH.value);
});
useEventListener('pointerup', () => {
lastYEvent = undefined;
yDragging.value = false;
});
// 不知道为什么 body_width 比 win_width 多出 0.2 或 0.4, 使用 Math.floor 去除
const xShow = computed(() => Math.floor(body.width.value) > winW.value);
const xWidth = computed(() => {
const clientWidth = body.width.value;
const bodyWidth = clientWidth;
return (winW.value / bodyWidth) * winW.value;
});
const translateX = computed(() => {
const clientWidth = body.width.value;
const width = xWidth.value;
return (x.value / (clientWidth - winW.value)) * (winW.value - width);
});
const xStyle = computed<CSSProperties>(() => {
if (!xShow.value) return {};
return {
transform: `translateX(${translateX.value}px)`,
width: `${xWidth.value}px`,
};
});
const clickBoxX = (e: MouseEvent) => {
const deltaX =
xWidth.value * 0.9 * (e.clientX < xWidth.value + translateX.value ? -1 : 1);
const clientWidth = body.width.value;
const bodyWidth = clientWidth;
const width = (winW.value / bodyWidth) * winW.value;
const newX =
x.value + (deltaX / (winW.value - width)) * (clientWidth - winW.value);
x.value = newX;
};
const xDragging = shallowRef(false);
let lastXEvent: MouseEvent | undefined = undefined;
const pointerdownX = (e: MouseEvent) => {
lastXEvent = e;
xDragging.value = true;
};
useEventListener('pointermove', (e) => {
if (!lastXEvent) return;
const deltaX = e.clientX - lastXEvent.clientX;
lastXEvent = e;
const clientWidth = body.width.value;
const bodyWidth = clientWidth;
const width = (winW.value / bodyWidth) * winW.value;
x.value += (deltaX / (winW.value - width)) * (clientWidth - winW.value);
});
useEventListener('pointerup', () => {
lastXEvent = undefined;
xDragging.value = false;
});
useEventListener('selectstart', (e) => {
if (lastXEvent || lastYEvent) {
e.preventDefault();
}
});
</script>
<template>
<div fixed z-2000 class="BodyScrollbar">
<div
v-show="yShow"
scrollbar-y
fixed
right-2px
top-0
bottom-0
w-8px
@pointerdown="pointerdownY"
@click="clickBoxY"
>
<div
@click.stop
w-full
bg="#909399"
opacity-30
hover:opacity="50"
:style="yStyle"
:class="{
'opacity-50': yDragging,
}"
></div>
</div>
<div
v-if="xShow"
scrollbar-x
fixed
bottom-2px
left-0
right-0
h-8px
@pointerdown="pointerdownX"
@click="clickBoxX"
>
<div
@click.stop
h-full
bg="#909399"
opacity-30
hover:opacity="50"
:style="xStyle"
:class="{
'opacity-50': xDragging,
}"
></div>
</div>
</div>
</template>
<style>
body:not(.mobile)::-webkit-scrollbar {
display: none;
}
html:not(.mobile) {
scrollbar-width: none;
}
</style>
2 changes: 1 addition & 1 deletion src/components/TrackDlg.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ watchEffect(() => {
v-model:show="show"
preset="dialog"
title="选择器路径视图"
class="min-w-[calc(var(--gkd-width)*0.4)]"
class="min-w-[calc(var(--gkd-w)*0.4)]"
@afterLeave="onUpdateTrack()"
>
<template #icon>
Expand Down
27 changes: 21 additions & 6 deletions src/utils/others.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { LocationQuery } from 'vue-router';
import { message } from './discrete';
import root from './root';
import { Teleport } from 'vue';
import BodyScrollbar from '@/components/BodyScrollbar.vue';

export const obj2form = (...objs: Record<string, unknown>[]) => {
const fd = new FormData();
Expand Down Expand Up @@ -64,15 +66,13 @@ export const copy = (() => {
};
})();

export const useAdaptMobile = () => {
const isMobile = window.innerHeight > window.innerWidth;
export const useAutoHeight = () => {
const cls = 'app-auto-h';
onMounted(() => {
if (isMobile) {
root.classList.add('mobile');
}
root.classList.add(cls);
});
onUnmounted(() => {
root.classList.remove('mobile');
root.classList.remove(cls);
});
};

Expand Down Expand Up @@ -143,3 +143,18 @@ export const toInteger = (v: unknown): number | undefined => {
}
}
};

export const ScrollbarWrapper = defineComponent(() => {
const show = shallowRef(false);
const isMobile = 'ontouchstart' in document.documentElement;
show.value = !isMobile;
if (isMobile) {
document.body.classList.add('mobile');
document.documentElement.classList.add('mobile');
}
return () => {
return show.value
? h(Teleport, { to: document.body }, h(BodyScrollbar))
: undefined;
};
});
4 changes: 2 additions & 2 deletions src/utils/size.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ const windowSize = useWindowSize();
export const vw = computed(() => windowSize.width.value / 100);
// const vh = computed(() => windowSize.width.value / 100);

// --gkd-width: max(1200px, 100vw);
// --gkd-w: max(1200px, 100vw);
export const gkdWidth = computed(() => Math.max(1200, windowSize.width.value));

// --gkd-height: max(700px, 100vh);
// --gkd-h: max(700px, 100vh);
export const gkdHeight = computed(() => Math.max(700, windowSize.height.value));
6 changes: 6 additions & 0 deletions src/views/SelectorPage.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
<script setup lang="ts">
import { useAutoHeight } from '@/utils/others';
// 页面: 输入框, 输入后解析当前选择器的结构
useAutoHeight();
</script>
<template>
<div flex flex-col items-center p-8px>
<input />
<div v-for="i in 60" :key="i">
{{ Math.random() }}
</div>
</div>
</template>
2 changes: 1 addition & 1 deletion src/views/snapshot/AttrCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ const selectText = computed(() => {
</NTd>
<NTd>
<NEllipsis
class="w-[calc(var(--gkd-width)*0.12)]"
class="w-[calc(var(--gkd-w)*0.12)]"
:class="{
'text-left direction-rtl': attrx.name == 'id',
'opacity-50': attrx.value === null,
Expand Down
2 changes: 1 addition & 1 deletion src/views/snapshot/ScreenshotCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ const imgBounding = useElementBounding(imgRef);
cursor-crosshair
h-full
object-contain
class="max-w-[calc(var(--gkd-width)*0.35)]"
class="max-w-[calc(var(--gkd-w)*0.35)]"
@mouseover="imgHover = true"
@mouseleave="imgHover = false"
@mousemove="imgMove"
Expand Down

0 comments on commit 1943400

Please sign in to comment.