|
1 | 1 | <template> |
2 | | - <div |
| 2 | + <NanoModal |
3 | 3 | ref="container" |
4 | | - class="nano-theme absolute" |
5 | | - :style="{ ...containerLayoutStyle, ...animation }" |
| 4 | + v-model:fullscreen="ctl.fullscreen" |
| 5 | + v-model:layout="containerLayout" |
| 6 | + :drag-el="headerEl" |
| 7 | + :visible="visible" |
| 8 | + :width-range="[ '20vw', '100vw' ]" |
| 9 | + :height-range="[ '60vh', '100vh' ]" |
| 10 | + class="nano-theme" |
6 | 11 | > |
7 | 12 | <div v-show="!loading" class="relative w-full h-full flex flex-col"> |
8 | 13 | <NanoHeader ref="header" @dblclick.self="ctl.fullscreen = !ctl.fullscreen"/> |
|
14 | 19 | <NanoBackdrop/> |
15 | 20 | <NanoNavModal/> |
16 | 21 | <NanoSidebarDirModal/> |
17 | | - </div> |
| 22 | + </NanoModal> |
18 | 23 | </template> |
19 | 24 |
|
20 | 25 | <script setup lang="ts"> |
|
25 | 30 | import NanoBackdrop from '@NanoUI/NanoBackdrop/index.vue'; |
26 | 31 | import NanoNavModal from '@NanoUI/NanoNavModal/index.vue'; |
27 | 32 | import NanoSidebarDirModal from '@NanoUI/NanoSidebarDirModal/index.vue'; |
28 | | - import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'; |
| 33 | + import NanoModal from '@NanoUI/NanoModal/index.vue'; |
| 34 | + import { computed, onBeforeUnmount, onMounted, ref } from 'vue'; |
29 | 35 | import { controllerStore } from '@store/controller'; |
30 | | - import { contentLayoutStore, getWidthFromString, LayoutBaseInfo } from '@store/contentLayout'; |
31 | | - import { drag } from '../../utils/drag'; |
32 | | - import { debounce } from 'lodash-es'; |
| 36 | + import { contentLayoutStore } from '@store/contentLayout'; |
33 | 37 |
|
34 | 38 | const ctl = controllerStore(); |
35 | 39 | const layout = contentLayoutStore(); |
36 | 40 |
|
37 | | - const container = ref<HTMLElement | null>(null); |
| 41 | + const container = ref<InstanceType<typeof NanoModal> | null>(null); |
38 | 42 | const header = ref<InstanceType<typeof NanoHeader> | null>(); |
39 | 43 | const resizeObserver = ref<ResizeObserver | null>(null); |
40 | 44 | const loading = ref(true); |
41 | | - const enableAnimation = ref(true); |
| 45 | + const visible = computed(() => !ctl.onlyFullscreen); |
42 | 46 |
|
43 | | - const animation = computed(() => { |
44 | | - return enableAnimation.value ? { |
45 | | - transition: 'top .12s, left .12s, width .12s, height .12s' |
46 | | - } : { |
47 | | - transition: 'width .12s, height .12s' |
48 | | - }; |
| 47 | + const headerEl = computed(() => header.value?.$el); |
| 48 | + const containerLayout = computed({ |
| 49 | + get: () => layout.containerLayout, |
| 50 | + set: (value) => layout.setContainerLayout(value) |
49 | 51 | }); |
50 | 52 |
|
51 | | - const containerLayout = ref<LayoutBaseInfo>(layout.containerLayout); |
52 | | -
|
53 | | - const containerLayoutStyle = computed(() => { |
54 | | - return !ctl.onlyFullscreen && !ctl.fullscreen ? containerLayout.value : { |
55 | | - top: 0, |
56 | | - left: 0, |
57 | | - width: '100vw', |
58 | | - height: '100vh' |
59 | | - }; |
60 | | - }); |
61 | | -
|
62 | | - watch(containerLayout, debounce((val) => { |
63 | | - // console.log('containerLayout changed', val); |
64 | | - layout.setContainerLayout(val); |
65 | | - }, 200), { deep: true }); |
66 | | -
|
67 | 53 | onMounted(() => { |
68 | | - const containerEl = container.value!; |
| 54 | + const containerEl = container.value!.$el; |
69 | 55 | resizeObserver.value = new ResizeObserver((entries: ResizeObserverEntry[]) => { |
70 | 56 | for (const entry of entries) { |
71 | 57 | const { target } = entry; |
|
100 | 86 | }); |
101 | 87 | resizeObserver.value.observe(containerEl); |
102 | 88 |
|
103 | | - type OriginLayout = { |
104 | | - isFullscreen: boolean; |
105 | | - notFullScreenWidth: number; |
106 | | - screenWidth: number; |
107 | | - screenHeight: number; |
108 | | - left: number; |
109 | | - top: number; |
110 | | - }; |
111 | 89 |
|
112 | | - drag<OriginLayout>({ |
113 | | - el: header.value!.$el, |
114 | | - originalData: () => { |
115 | | - const { clientWidth, clientHeight } = document.documentElement; |
116 | | - const { offsetLeft, offsetTop } = containerEl; |
117 | | - const width = getWidthFromString(layout.container.changed?.width || layout.container.default?.width || ''); |
118 | | - return { |
119 | | - isFullscreen: ctl.fullscreen, |
120 | | - notFullScreenWidth: width, |
121 | | - screenWidth: clientWidth, |
122 | | - screenHeight: clientHeight, |
123 | | - left: offsetLeft, |
124 | | - top: offsetTop |
125 | | - }; |
126 | | - }, |
127 | | - handlerFn: ({ |
128 | | - x, |
129 | | - y, |
130 | | - originalData: { isFullscreen, notFullScreenWidth, screenWidth, screenHeight, left, top }, |
131 | | - pointerWelt, |
132 | | - initial |
133 | | - }) => { |
134 | | - let newLeft = left + x; |
135 | | - const newTop = top + y; |
136 | | - if (isFullscreen) { |
137 | | - ctl.fullscreen = false; |
138 | | - newLeft = initial.x - (initial.x / screenWidth) * notFullScreenWidth + x; |
139 | | - } |
140 | | - if (!pointerWelt.top && !pointerWelt.bottom && newTop > 0) { |
141 | | - containerLayout.value.top = newTop / screenHeight * 100 + '%'; |
142 | | - } else { |
143 | | - containerLayout.value.top = pointerWelt.bottom ? '98%' : '0'; |
144 | | - } |
145 | | - if (!pointerWelt.left && !pointerWelt.right) { |
146 | | - containerLayout.value.left = newLeft / screenWidth * 100 + '%'; |
147 | | - } |
148 | | - }, |
149 | | - beforeFn: () => enableAnimation.value = false, |
150 | | - afterFn: () => enableAnimation.value = true |
151 | | - }); |
152 | 90 | }); |
153 | 91 |
|
154 | 92 | onBeforeUnmount(() => { |
|
0 commit comments