Skip to content

Commit aaea5b8

Browse files
committed
Update: 主题窗口拖拽
1 parent aa44752 commit aaea5b8

File tree

16 files changed

+347
-143
lines changed

16 files changed

+347
-143
lines changed

package/App.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,21 @@ export const theme = App;
1515

1616
export const install = (app: EnhanceAppContext) => {
1717
DefaultTheme.enhanceApp(app);
18-
app.app.use(pinia);
18+
const { app: appInstance } = app;
19+
appInstance.use(pinia);
20+
appInstance.config.globalProperties.$go = function goPage(url: string, target: '_self' | '_blank' = '_self') {
21+
if (url) {
22+
if (target === '_blank') {
23+
window.open(url);
24+
} else {
25+
app.router.go(url);
26+
}
27+
}
28+
};
1929
};
30+
31+
declare module 'vue' {
32+
interface ComponentCustomProperties {
33+
$go: (url: string, target?: '_self' | '_blank') => void;
34+
}
35+
}

package/App.vue

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<div
3-
class="relative h-screen w-screen flex-center"
3+
class="fixed top-0 left-0 h-screen w-screen flex-center"
44
style="background-size: cover; background-position: center; background-repeat: no-repeat;"
55
:style="{ backgroundImage: `url(${ bgList[0] })` }"
66
>
@@ -9,7 +9,7 @@
99
<div
1010
class="relative w-60 h-60 max-w-80vw max-h-80vw"
1111
style="filter: drop-shadow(0 0 16px rgba(0,0,0,.36));"
12-
@click="goPage(aboutMePath)"
12+
@click="$go(aboutMePath)"
1313
>
1414
<img class="w-full w-full rounded-sm cursor-pointer" :src="logo" alt=""/>
1515
</div>
@@ -23,13 +23,13 @@
2323
v-if="socialLinks.length > 0"
2424
class="flex-center gap-2 flex-wrap rounded-full"
2525
>
26-
<a
26+
<span
2727
v-for="v in links"
2828
:key="v.link"
29-
class="h-10 w-10 line-height-10 rounded-full bg-transparent hover:bg-[rgba(255,255,255,.12)] transition-colors duration-240 ease-in-out"
29+
class="h-10 w-10 line-height-10 rounded-full bg-transparent hover:bg-[rgba(255,255,255,.12)]"
30+
un-transition="colors duration-240 ease-in-out"
3031
un-text="center white 6"
31-
:href="v.link"
32-
target="_blank"
32+
@click="$go(v.link, '_blank')"
3333
v-html="v.icon"
3434
/>
3535
</div>
@@ -39,7 +39,7 @@
3939
un-border="~ solid 0.5 gray-4 rounded-2"
4040
un-hover="border-white text-white"
4141
un-transition="colors duration-300 ease"
42-
@click="goPage('/learn/')"
42+
@click="$go('/learn/')"
4343
>
4444
OPEN BLOG ->
4545
</div>
@@ -52,19 +52,17 @@
5252

5353
<script setup lang="ts">
5454
import NanoContainer from '@NanoUI/NanoContainer/index.vue';
55-
import { useData, useRouter } from 'vitepress';
55+
import { useData } from 'vitepress';
5656
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
5757
import { DefaultTheme } from 'vitepress/types/default-theme';
5858
import { controllerStore } from '@store/controller';
5959
6060
const { frontmatter, site } = useData();
6161
62-
console.log(useData().site.value);
62+
// console.log(useData().site.value);
6363
6464
const { logo, socialLinks, backgrounds: bgList, motto, name, aboutMePath } = site.value.themeConfig;
6565
66-
const router = useRouter();
67-
6866
const links = computed(() => {
6967
return site.value?.themeConfig.socialLinks?.map((v: DefaultTheme.SocialLink) => {
7068
let icon: string;
@@ -80,10 +78,6 @@
8078
}) || [];
8179
});
8280
83-
function goPage(url: string) {
84-
url && router.go(url);
85-
}
86-
8781
const onlyShowIndex = ref<boolean>(false);
8882
8983
watch(() => frontmatter.value.layout, (value) => {

package/components/NanoBody/index.vue

Lines changed: 65 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
<template>
2-
<div ref="body" class="relative grow flex items-stretch min-h-0">
2+
<div ref="container" class="relative grow flex items-stretch min-h-0">
33
<NanoLeftActionBar v-if="!ctl.hideLeftActionBar" ref="leftActionBar"/>
4-
<NanoLeftSidebar v-if="!ctl.hideLeftSidebar" ref="leftSidebar">
4+
<NanoLeftSidebar v-if="!ctl.hideLeftSidebar" ref="leftSidebar" :style="layout.leftSidebarLayout">
55
<!--draggable line-->
66
<div
77
ref="leftDraggableLine"
8-
class="absolute z-2 right--1 top-0 h-full w-2 bg-transparent cursor-col-resize"
8+
class="absolute z-4 right--2 top-0 h-full w-2 bg-transparent cursor-col-resize"
99
/>
1010
</NanoLeftSidebar>
1111
<NanoMain ref="main"/>
12-
<NanoRightSidebar v-if="!ctl.hideRightSidebar" ref="rightSidebar">
12+
<NanoRightSidebar v-if="!ctl.hideRightSidebar" ref="rightSidebar" :style="layout.rightSidebarLayout">
1313
<!--draggable line-->
1414
<div
1515
ref="rightDraggableLine"
16-
class="absolute z-2 left--1 top-0 h-full w-2 bg-transparent cursor-col-resize"
16+
class="absolute z-4 left--2 top-0 h-full w-2 bg-transparent cursor-col-resize"
1717
/>
1818
</NanoRightSidebar>
1919
<NanoRightActionBar v-if="!ctl.hideRightActionBar" ref="rightActionBar"/>
@@ -28,11 +28,14 @@
2828
import NanoRightActionBar from '@NanoUI/NanoRightActionBar/index.vue';
2929
import { controllerStore } from '@store/controller';
3030
import { onMounted, ref } from 'vue';
31-
import { dragChangeWidth } from '../../utils/dragChangeWidth';
31+
import { drag } from '../../utils/drag';
32+
import { contentLayoutStore } from '@store/contentLayout';
3233
3334
const ctl = controllerStore();
3435
35-
const body = ref<HTMLElement | null>(null);
36+
const layout = contentLayoutStore();
37+
38+
const container = ref<HTMLElement | null>(null);
3639
const leftActionBar = ref<InstanceType<typeof NanoLeftActionBar> | null>();
3740
const leftSidebar = ref<InstanceType<typeof NanoLeftSidebar> | null>();
3841
const rightSidebar = ref<InstanceType<typeof NanoRightSidebar> | null>();
@@ -41,20 +44,63 @@
4144
const leftDraggableLine = ref<HTMLDivElement | null>();
4245
const rightDraggableLine = ref<HTMLDivElement | null>();
4346
47+
type OriginalDataType = {
48+
// container width
49+
cw: number;
50+
// left sidebar width
51+
lsw: number;
52+
// right sidebar width
53+
rsw: number;
54+
// left action bar width
55+
law: number;
56+
// right action bar width
57+
raw: number;
58+
};
59+
4460
onMounted(() => {
45-
if (body.value && leftSidebar.value && rightSidebar.value && leftActionBar.value && rightActionBar.value) {
46-
dragChangeWidth({
47-
parentEl: body.value!,
48-
targetEl: leftSidebar.value!.$el,
49-
dragEl: leftDraggableLine.value!,
50-
otherEls: [ rightSidebar.value!.$el, leftActionBar.value!.$el, rightActionBar.value!.$el ]
61+
if (container.value && leftSidebar.value && rightSidebar.value && leftActionBar.value && rightActionBar.value) {
62+
const originalData = (): OriginalDataType => {
63+
return {
64+
cw: container.value!.clientWidth,
65+
lsw: leftSidebar.value!.$el.clientWidth,
66+
rsw: rightSidebar.value!.$el.clientWidth,
67+
law: leftActionBar.value!.$el.clientWidth,
68+
raw: rightActionBar.value!.$el.clientWidth
69+
};
70+
};
71+
drag<OriginalDataType>({
72+
el: leftDraggableLine.value!,
73+
originalData,
74+
handlerFn: ({ x, originalData: { cw, law, lsw, rsw, raw } }) => {
75+
const newWidth = lsw + x;
76+
const otherElsWidth = law + raw + rsw;
77+
if (cw - otherElsWidth - 400 < newWidth) {
78+
return;
79+
}
80+
if (newWidth < 120) {
81+
return;
82+
}
83+
layout.setLeftSidebarLayout({
84+
width: newWidth / cw * 100 + '%'
85+
});
86+
}
5187
});
52-
dragChangeWidth({
53-
parentEl: body.value!,
54-
targetEl: rightSidebar.value!.$el,
55-
dragEl: rightDraggableLine.value!,
56-
otherEls: [ leftSidebar.value!.$el, leftActionBar.value!.$el, rightActionBar.value!.$el ],
57-
reverseDirection: true
88+
drag<OriginalDataType>({
89+
el: rightDraggableLine.value!,
90+
originalData,
91+
handlerFn: ({ x, originalData: { cw, law, lsw, rsw, raw } }) => {
92+
const newWidth = rsw - x;
93+
const otherElsWidth = law + raw + lsw;
94+
if (cw - otherElsWidth - 400 < newWidth) {
95+
return;
96+
}
97+
if (newWidth < 120) {
98+
return;
99+
}
100+
layout.setRightSidebarLayout({
101+
width: newWidth / cw * 100 + '%'
102+
});
103+
}
58104
});
59105
}
60106
});

package/components/NanoContainer/index.vue

Lines changed: 80 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
<template>
22
<div
3-
ref="root"
4-
class="nano-theme absolute flex flex-col"
5-
:style="windowStyle"
3+
ref="container"
4+
class="nano-theme absolute"
5+
:style="{ ...layout.containerLayout, ...animation }"
66
>
7-
<template v-if="!loading">
8-
<NanoHeader/>
7+
<div v-show="!loading" class="relative w-full h-full flex flex-col">
8+
<NanoHeader ref="header" @dblclick="ctl.fullscreen = !ctl.fullscreen"/>
99
<NanoBody/>
1010
<NanoFooter/>
11-
</template>
11+
</div>
1212

13-
<NanoLoading v-else/>
13+
<NanoLoading v-show="loading"/>
1414
<NanoBackdrop/>
1515
<NanoNavModal/>
1616
<NanoSidebarDirModal/>
@@ -27,33 +27,28 @@
2727
import NanoSidebarDirModal from '@NanoUI/NanoSidebarDirModal/index.vue';
2828
import { computed, onBeforeUnmount, onMounted, ref } from 'vue';
2929
import { controllerStore } from '@store/controller';
30+
import { contentLayoutStore, getWidthFromString } from '@store/contentLayout';
31+
import { drag } from '../../utils/drag';
3032
3133
const ctl = controllerStore();
34+
const layout = contentLayoutStore();
3235
33-
const root = ref<HTMLElement | null>(null);
36+
const container = ref<HTMLElement | null>(null);
37+
const header = ref<InstanceType<typeof NanoHeader> | null>();
3438
const resizeObserver = ref<ResizeObserver | null>(null);
3539
const loading = ref(true);
40+
const enableAnimation = ref(true);
3641
37-
const windowStyle = computed(() => {
38-
if (!ctl.onlyFullscreen && !ctl.fullscreen) {
39-
return {
40-
width: '90vw',
41-
height: '90vh',
42-
top: '5vh',
43-
left: '5vw'
44-
};
45-
} else {
46-
return {
47-
width: '100vw',
48-
height: '100vh',
49-
top: '0',
50-
left: '0'
51-
};
52-
}
42+
const animation = computed(() => {
43+
return enableAnimation.value ? {
44+
transition: 'top .12s, left .12s, width .12s, height .12s'
45+
} : {
46+
transition: 'width .12s, height .12s'
47+
};
5348
});
5449
5550
onMounted(() => {
56-
const rootEl = root.value!;
51+
const containerEl = container.value!;
5752
resizeObserver.value = new ResizeObserver((entries: ResizeObserverEntry[]) => {
5853
for (const entry of entries) {
5954
const { target } = entry;
@@ -80,11 +75,67 @@
8075
ctl.hideCopyright = false;
8176
}
8277
}
83-
setTimeout(() => {
84-
loading.value = false;
85-
}, 1200);
78+
if (loading.value) {
79+
setTimeout(() => {
80+
loading.value = false;
81+
}, 1200);
82+
}
83+
});
84+
resizeObserver.value.observe(containerEl!);
85+
86+
type OriginLayout = {
87+
isFullscreen: boolean;
88+
notFullScreenWidth: number;
89+
screenWidth: number;
90+
screenHeight: number;
91+
left: number;
92+
top: number;
93+
};
94+
95+
drag<OriginLayout>({
96+
el: header.value!.$el,
97+
originalData: () => {
98+
const { clientWidth, clientHeight } = document.documentElement;
99+
const { offsetLeft, offsetTop } = containerEl;
100+
const width = getWidthFromString(layout.container.changed?.width || layout.container.default?.width || '');
101+
return {
102+
isFullscreen: ctl.fullscreen,
103+
notFullScreenWidth: width,
104+
screenWidth: clientWidth,
105+
screenHeight: clientHeight,
106+
left: offsetLeft,
107+
top: offsetTop
108+
};
109+
},
110+
handlerFn: ({ x, y, originalData: { isFullscreen, notFullScreenWidth, screenWidth, screenHeight, left, top }, pointerWelt, initial }) => {
111+
let newLeft = left + x;
112+
const newTop = top + y;
113+
if (isFullscreen) {
114+
ctl.fullscreen = false;
115+
newLeft = initial.x - (initial.x / screenWidth) * notFullScreenWidth + x;
116+
}
117+
if (!pointerWelt.top && !pointerWelt.bottom && newTop > 0) {
118+
layout.setContainerLayout({
119+
top: newTop / screenHeight * 100 + '%'
120+
});
121+
} else {
122+
layout.setContainerLayout({
123+
top: pointerWelt.bottom ? '98%' : '0'
124+
});
125+
}
126+
if (!pointerWelt.left && !pointerWelt.right) {
127+
layout.setContainerLayout({
128+
left: newLeft / screenWidth * 100 + '%'
129+
});
130+
} else {
131+
layout.setContainerLayout({
132+
left: pointerWelt.right ? '98%' : '0'
133+
});
134+
}
135+
},
136+
beforeFn: () => enableAnimation.value = false,
137+
afterFn: () => enableAnimation.value = true
86138
});
87-
resizeObserver.value.observe(rootEl!);
88139
});
89140
90141
onBeforeUnmount(() => {

package/components/NanoHeader/index.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
un-flex="~ justify-between"
77
>
88
<!--header left-->
9-
<div class="relative h-full flex-center">
9+
<div class="relative h-full flex-center" @mousedown.stop>
1010
<NanoLogo/>
1111
<NanoHeaderTopNav v-if="!ctl.hideHeaderTopNav"/>
1212
<NanoMiniHeaderTopNav v-else/>
1313
</div>
1414
<!--header right-->
15-
<div class="relative h-full flex flex-row-reverse">
15+
<div class="relative h-full flex flex-row-reverse" @mousedown.stop>
1616
<NanoWindowController/>
1717
</div>
1818
</header>

package/components/NanoHeaderTopNav/index.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div class="relative h-[var(--s)] flex items-center gap-4 px-[calc(var(--s)*0.2)]">
2+
<div class="relative h-[var(--s)] flex items-center gap-4 px-[calc(var(--s)*0.2)] select-none">
33
<template
44
v-for="(nav, index) in navList"
55
:key="nav.link"

package/components/NanoLeftSidebar/index.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<div
3-
class="relative shrink-0 h-full w-[var(--sidebar-left-size)]"
3+
class="relative shrink-0 h-full"
44
:class="{ 'w-0!': !openStatus }"
55
un-border="r-solid r-1px r-[var(--sidebar-border-color)]"
66
un-flex="~ col"

package/components/NanoLoading/index.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div class="box rounded-6px">
2+
<div class="box w-full h-full rounded-6px">
33
<div class="cat">
44
<div class="cat__body"/>
55
<div class="cat__body"/>

0 commit comments

Comments
 (0)