@coffic/cosy-ui 0.8.23 → 0.8.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.css +1 -1
- package/dist/index-astro.ts +1 -0
- package/dist/src-astro/grid/Grid.astro +274 -20
- package/dist/src-astro/list/ListItem.astro +71 -0
- package/dist/src-astro/list/ListItemBreath.astro +60 -0
- package/dist/src-astro/list/ListItemGlow.astro +65 -0
- package/dist/src-astro/list/ListItemIconLeft.astro +53 -0
- package/dist/src-astro/list/ListItemIconRight.astro +53 -0
- package/dist/src-astro/list/ListItemPulse.astro +61 -0
- package/dist/src-astro/list/ListItemRing.astro +59 -0
- package/dist/src-astro/list/index.ts +7 -0
- package/dist/src-vue/alert/Alert.vue +1 -1
- package/dist/src-vue/alert-dialog/Multilang.vue +1 -1
- package/dist/src-vue/buttons/Button.vue +20 -14
- package/dist/src-vue/container/Container.vue +1 -1
- package/dist/src-vue/iPhone/StatusBarContent.vue +88 -76
- package/dist/src-vue/iPhone/iPhoneWindow.vue +149 -129
- package/dist/src-vue/list/ListItem.vue +92 -2
- package/dist/src-vue/list/ListItemBreath.vue +70 -0
- package/dist/src-vue/list/ListItemGlow.vue +75 -0
- package/dist/src-vue/list/ListItemIconLeft.vue +63 -0
- package/dist/src-vue/list/ListItemIconRight.vue +63 -0
- package/dist/src-vue/list/ListItemPulse.vue +71 -0
- package/dist/src-vue/list/ListItemRing.vue +71 -0
- package/dist/src-vue/mac-window/MacWindow.vue +160 -139
- package/package.json +1 -1
@@ -0,0 +1,59 @@
|
|
1
|
+
---
|
2
|
+
/**
|
3
|
+
* @component ListItemRing
|
4
|
+
* @description ListItem Ring 外环脉冲动画子组件
|
5
|
+
*/
|
6
|
+
import '../../style.ts';
|
7
|
+
const { loading = false, duration } = Astro.props;
|
8
|
+
---
|
9
|
+
|
10
|
+
<li
|
11
|
+
class:list={[
|
12
|
+
'cosy:mb-2 cosy:rounded-md cosy:bg-base-300 cosy:p-2 cosy:flex cosy:items-center cosy:gap-3 cosy:hover:bg-accent/10 cosy:relative cosy:overflow-hidden',
|
13
|
+
loading && !duration ? 'cosy:ring-2 cosy:ring-accent ring-pulse-anim' : '',
|
14
|
+
]}
|
15
|
+
{...Astro.props}>
|
16
|
+
{
|
17
|
+
loading && duration && (
|
18
|
+
<div
|
19
|
+
class="cosy:absolute cosy:left-0 cosy:top-0 cosy:h-full cosy:bg-accent/40 cosy:z-0 loading-bar"
|
20
|
+
style={`animation-duration: ${duration}ms;`}
|
21
|
+
/>
|
22
|
+
)
|
23
|
+
}
|
24
|
+
<div
|
25
|
+
class="cosy:relative cosy:z-10 cosy:w-full cosy:flex cosy:items-center cosy:gap-3">
|
26
|
+
<slot />
|
27
|
+
</div>
|
28
|
+
</li>
|
29
|
+
|
30
|
+
<style scoped>
|
31
|
+
/* Ring 外环脉冲动画 */
|
32
|
+
@keyframes ring-pulse {
|
33
|
+
0%,
|
34
|
+
100% {
|
35
|
+
transform: scale(1);
|
36
|
+
}
|
37
|
+
50% {
|
38
|
+
transform: scale(1.02);
|
39
|
+
}
|
40
|
+
}
|
41
|
+
.ring-pulse-anim {
|
42
|
+
animation: ring-pulse 1.5s ease-in-out infinite;
|
43
|
+
}
|
44
|
+
|
45
|
+
/* 进度条动画 */
|
46
|
+
.loading-bar {
|
47
|
+
width: 0%;
|
48
|
+
height: 100%;
|
49
|
+
animation: loading-bar-anim linear forwards;
|
50
|
+
}
|
51
|
+
@keyframes loading-bar-anim {
|
52
|
+
0% {
|
53
|
+
width: 0%;
|
54
|
+
}
|
55
|
+
100% {
|
56
|
+
width: 100%;
|
57
|
+
}
|
58
|
+
}
|
59
|
+
</style>
|
@@ -1,20 +1,20 @@
|
|
1
1
|
<script setup lang="ts">
|
2
2
|
import { computed } from 'vue';
|
3
|
-
import '../../style
|
3
|
+
import '../../style';
|
4
4
|
|
5
5
|
interface Props {
|
6
6
|
variant?:
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
7
|
+
| 'primary'
|
8
|
+
| 'secondary'
|
9
|
+
| 'accent'
|
10
|
+
| 'info'
|
11
|
+
| 'success'
|
12
|
+
| 'warning'
|
13
|
+
| 'error'
|
14
|
+
| 'ghost'
|
15
|
+
| 'link'
|
16
|
+
| 'outline'
|
17
|
+
| 'neutral';
|
18
18
|
size?: 'lg' | 'md' | 'sm' | 'xs';
|
19
19
|
shape?: 'circle' | 'square';
|
20
20
|
wide?: boolean;
|
@@ -89,8 +89,14 @@ const buttonClasses = computed(() => {
|
|
89
89
|
</script>
|
90
90
|
|
91
91
|
<template>
|
92
|
-
<component
|
93
|
-
:
|
92
|
+
<component
|
93
|
+
:is="props.href ? 'a' : 'button'"
|
94
|
+
:class="buttonClasses"
|
95
|
+
:type="props.href ? undefined : props.type"
|
96
|
+
:disabled="props.disabled"
|
97
|
+
:href="props.href"
|
98
|
+
:target="props.target"
|
99
|
+
>
|
94
100
|
<span class="cosy:flex cosy:items-center cosy:gap-2">
|
95
101
|
<slot name="icon-left" />
|
96
102
|
<slot />
|
@@ -24,98 +24,110 @@ StatusBarContent 组件显示 iPhone 状态栏的内容,包括时间、信号
|
|
24
24
|
<script lang="ts">
|
25
25
|
import { defineComponent, ref, onMounted, onUnmounted, computed } from 'vue';
|
26
26
|
import { IPhoneSignalIcon, IPhoneWifiIcon, IPhoneBatteryIcon } from '../icons';
|
27
|
-
import '../../style
|
27
|
+
import '../../style';
|
28
28
|
|
29
29
|
export default defineComponent({
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
},
|
41
|
-
},
|
42
|
-
setup(props) {
|
43
|
-
const currentTime = ref('12:00');
|
44
|
-
|
45
|
-
// 更新时间的函数
|
46
|
-
const updateTime = () => {
|
47
|
-
const now = new Date();
|
48
|
-
const hours = now.getHours().toString().padStart(2, '0');
|
49
|
-
const minutes = now.getMinutes().toString().padStart(2, '0');
|
50
|
-
currentTime.value = `${hours}:${minutes}`;
|
51
|
-
};
|
52
|
-
|
53
|
-
// 计算缩放后的字体大小
|
54
|
-
const scaledFontSize = computed(() => {
|
55
|
-
const baseFontSize = 14; // 基础字体大小
|
56
|
-
return `${baseFontSize * props.scaleRatio}px`;
|
57
|
-
});
|
58
|
-
|
59
|
-
// 计算缩放后的图标尺寸
|
60
|
-
const scaledIconSize = computed(() => {
|
61
|
-
const baseIconSize = 15; // 基础图标宽度
|
62
|
-
return `${baseIconSize * props.scaleRatio}px`;
|
63
|
-
});
|
64
|
-
|
65
|
-
// 计算缩放后的图标高度百分比
|
66
|
-
const scaledIconHeight = computed(() => {
|
67
|
-
const baseHeight = 60; // 基础高度百分比
|
68
|
-
return `${baseHeight * props.scaleRatio}%`;
|
69
|
-
});
|
70
|
-
|
71
|
-
// 设置定时器更新时间
|
72
|
-
let timeInterval: number;
|
73
|
-
onMounted(() => {
|
74
|
-
updateTime();
|
75
|
-
timeInterval = window.setInterval(updateTime, 60000); // 每分钟更新一次
|
76
|
-
});
|
77
|
-
|
78
|
-
onUnmounted(() => {
|
79
|
-
if (timeInterval) {
|
80
|
-
clearInterval(timeInterval);
|
81
|
-
}
|
82
|
-
});
|
83
|
-
|
84
|
-
return {
|
85
|
-
currentTime,
|
86
|
-
scaledFontSize,
|
87
|
-
scaledIconSize,
|
88
|
-
scaledIconHeight,
|
89
|
-
};
|
30
|
+
name: 'StatusBarContent',
|
31
|
+
components: {
|
32
|
+
IPhoneSignalIcon,
|
33
|
+
IPhoneWifiIcon,
|
34
|
+
IPhoneBatteryIcon,
|
35
|
+
},
|
36
|
+
props: {
|
37
|
+
scaleRatio: {
|
38
|
+
type: Number,
|
39
|
+
default: 1,
|
90
40
|
},
|
41
|
+
},
|
42
|
+
setup(props) {
|
43
|
+
const currentTime = ref('12:00');
|
44
|
+
|
45
|
+
// 更新时间的函数
|
46
|
+
const updateTime = () => {
|
47
|
+
const now = new Date();
|
48
|
+
const hours = now.getHours().toString().padStart(2, '0');
|
49
|
+
const minutes = now.getMinutes().toString().padStart(2, '0');
|
50
|
+
currentTime.value = `${hours}:${minutes}`;
|
51
|
+
};
|
52
|
+
|
53
|
+
// 计算缩放后的字体大小
|
54
|
+
const scaledFontSize = computed(() => {
|
55
|
+
const baseFontSize = 14; // 基础字体大小
|
56
|
+
return `${baseFontSize * props.scaleRatio}px`;
|
57
|
+
});
|
58
|
+
|
59
|
+
// 计算缩放后的图标尺寸
|
60
|
+
const scaledIconSize = computed(() => {
|
61
|
+
const baseIconSize = 15; // 基础图标宽度
|
62
|
+
return `${baseIconSize * props.scaleRatio}px`;
|
63
|
+
});
|
64
|
+
|
65
|
+
// 计算缩放后的图标高度百分比
|
66
|
+
const scaledIconHeight = computed(() => {
|
67
|
+
const baseHeight = 60; // 基础高度百分比
|
68
|
+
return `${baseHeight * props.scaleRatio}%`;
|
69
|
+
});
|
70
|
+
|
71
|
+
// 设置定时器更新时间
|
72
|
+
let timeInterval: number;
|
73
|
+
onMounted(() => {
|
74
|
+
updateTime();
|
75
|
+
timeInterval = window.setInterval(updateTime, 60000); // 每分钟更新一次
|
76
|
+
});
|
77
|
+
|
78
|
+
onUnmounted(() => {
|
79
|
+
if (timeInterval) {
|
80
|
+
clearInterval(timeInterval);
|
81
|
+
}
|
82
|
+
});
|
83
|
+
|
84
|
+
return {
|
85
|
+
currentTime,
|
86
|
+
scaledFontSize,
|
87
|
+
scaledIconSize,
|
88
|
+
scaledIconHeight,
|
89
|
+
};
|
90
|
+
},
|
91
91
|
});
|
92
92
|
</script>
|
93
93
|
|
94
94
|
<template>
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
95
|
+
<div class="cosy:flex cosy:items-center cosy:h-full cosy:justify-between">
|
96
|
+
<!-- 左侧时间 -->
|
97
|
+
<span
|
98
|
+
class="cosy:font-medium time-text"
|
99
|
+
:style="{ fontSize: scaledFontSize }"
|
100
|
+
>
|
101
|
+
{{ currentTime }}
|
102
|
+
</span>
|
103
|
+
|
104
|
+
<!-- 右侧状态图标 -->
|
105
|
+
<div
|
106
|
+
class="cosy:flex cosy:flex-row cosy:items-center cosy:space-x-1 cosy:h-full"
|
107
|
+
>
|
108
|
+
<div
|
109
|
+
:style="{
|
110
|
+
width: scaledIconSize,
|
111
|
+
height: scaledIconHeight,
|
112
|
+
minWidth: 0,
|
113
|
+
minHeight: 0,
|
114
|
+
}"
|
115
|
+
>
|
116
|
+
<IPhoneBatteryIcon />
|
117
|
+
</div>
|
107
118
|
</div>
|
119
|
+
</div>
|
108
120
|
</template>
|
109
121
|
|
110
122
|
<style scoped>
|
111
123
|
/* 确保图标渲染更平滑 */
|
112
124
|
svg {
|
113
|
-
|
125
|
+
shape-rendering: geometricPrecision;
|
114
126
|
}
|
115
127
|
|
116
128
|
/* 时间文字基础样式 */
|
117
129
|
.time-text {
|
118
|
-
|
119
|
-
|
130
|
+
line-height: 1;
|
131
|
+
transition: font-size 0.2s ease;
|
120
132
|
}
|
121
133
|
</style>
|
@@ -63,8 +63,8 @@ iPhoneWindow 组件模拟 iPhone 设备的外观,包含状态栏、时间显
|
|
63
63
|
@emits
|
64
64
|
-->
|
65
65
|
<script lang="ts">
|
66
|
-
import '../../style
|
67
|
-
import { AlertDialog } from '../../index-vue
|
66
|
+
import '../../style';
|
67
|
+
import { AlertDialog } from '../../index-vue';
|
68
68
|
import { ref, defineComponent } from 'vue';
|
69
69
|
import iphoneFrame from './assets/iPhone 14 Pro - Deep Purple - Portrait.png';
|
70
70
|
import StatusBarContent from './StatusBarContent.vue';
|
@@ -83,148 +83,168 @@ const mainContentWidthAspectRatio = 1179 / iphoneFrameWidth;
|
|
83
83
|
// 比例-总高度
|
84
84
|
const mainContentHeightAspectRatio = 2556 / iphoneFrameHeight;
|
85
85
|
// 比例-状态栏高度
|
86
|
-
const iphoneFrameStatusBarHeightAspectRatio =
|
86
|
+
const iphoneFrameStatusBarHeightAspectRatio =
|
87
|
+
iphoneFrameStatusBarHeight / iphoneFrameHeight;
|
87
88
|
// 比例-状态栏离上边框的距离
|
88
|
-
const iphoneFrameStatusBarTopAspectRatio =
|
89
|
+
const iphoneFrameStatusBarTopAspectRatio =
|
90
|
+
iphoneFrameStatusBarTop / iphoneFrameHeight;
|
89
91
|
|
90
92
|
// 预定义的高度选项
|
91
93
|
type HeightOption = 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl';
|
92
94
|
|
93
95
|
const heightClasses: Record<HeightOption, string> = {
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
96
|
+
sm: 'cosy:h-64', // 256px
|
97
|
+
md: 'cosy:h-80', // 320px
|
98
|
+
lg: 'cosy:h-96', // 384px
|
99
|
+
xl: 'cosy:h-[480px]', // 480px
|
100
|
+
'2xl': 'cosy:h-[560px]', // 560px
|
101
|
+
'3xl': 'cosy:h-[640px]', // 640px
|
102
|
+
'4xl': 'cosy:h-[720px]', // 720px
|
103
|
+
'5xl': 'cosy:h-[800px]', // 800px
|
102
104
|
};
|
103
105
|
|
104
106
|
export default defineComponent({
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
107
|
+
name: 'iPhoneWindow',
|
108
|
+
components: {
|
109
|
+
AlertDialog,
|
110
|
+
StatusBarContent,
|
111
|
+
},
|
112
|
+
props: {
|
113
|
+
height: {
|
114
|
+
type: String as () => HeightOption,
|
115
|
+
default: 'lg',
|
116
|
+
validator: (value: string) => {
|
117
|
+
return Object.keys(heightClasses).includes(value);
|
118
|
+
},
|
109
119
|
},
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
default: 'lg',
|
114
|
-
validator: (value: string) => {
|
115
|
-
return Object.keys(heightClasses).includes(value);
|
116
|
-
},
|
117
|
-
},
|
118
|
-
debug: {
|
119
|
-
type: Boolean,
|
120
|
-
default: false,
|
121
|
-
},
|
122
|
-
title: {
|
123
|
-
type: String,
|
124
|
-
default: '',
|
125
|
-
},
|
126
|
-
statusBarButtons: {
|
127
|
-
type: Array,
|
128
|
-
default: () => [],
|
129
|
-
},
|
130
|
-
withShadow: {
|
131
|
-
type: Boolean,
|
132
|
-
default: true,
|
133
|
-
},
|
134
|
-
showFrame: {
|
135
|
-
type: Boolean,
|
136
|
-
default: true,
|
137
|
-
},
|
138
|
-
backgroundColor: {
|
139
|
-
type: String,
|
140
|
-
default: '',
|
141
|
-
},
|
120
|
+
debug: {
|
121
|
+
type: Boolean,
|
122
|
+
default: false,
|
142
123
|
},
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
// 计算当前高度的缩放比例
|
148
|
-
const getScaleRatio = () => {
|
149
|
-
const heightValues = {
|
150
|
-
sm: 256,
|
151
|
-
md: 320,
|
152
|
-
lg: 384,
|
153
|
-
xl: 480,
|
154
|
-
'2xl': 560,
|
155
|
-
'3xl': 640,
|
156
|
-
'4xl': 720,
|
157
|
-
'5xl': 800,
|
158
|
-
};
|
159
|
-
const currentHeight = heightValues[props.height];
|
160
|
-
// 基于特定高度计算缩放比例
|
161
|
-
return currentHeight / 500;
|
162
|
-
};
|
163
|
-
|
164
|
-
return {
|
165
|
-
showAlertDialog,
|
166
|
-
alertMessage,
|
167
|
-
iphoneFrame: (iphoneFrame as any).src || iphoneFrame,
|
168
|
-
heightClasses,
|
169
|
-
mainContentWidthAspectRatio,
|
170
|
-
mainContentHeightAspectRatio,
|
171
|
-
iphoneFrameWidth,
|
172
|
-
iphoneFrameHeight,
|
173
|
-
iphoneFrameStatusBarTop,
|
174
|
-
iphoneFrameStatusBarHeight,
|
175
|
-
iphoneFrameStatusBarHeightAspectRatio,
|
176
|
-
iphoneFrameStatusBarTopAspectRatio,
|
177
|
-
getScaleRatio,
|
178
|
-
};
|
124
|
+
title: {
|
125
|
+
type: String,
|
126
|
+
default: '',
|
179
127
|
},
|
128
|
+
statusBarButtons: {
|
129
|
+
type: Array,
|
130
|
+
default: () => [],
|
131
|
+
},
|
132
|
+
withShadow: {
|
133
|
+
type: Boolean,
|
134
|
+
default: true,
|
135
|
+
},
|
136
|
+
showFrame: {
|
137
|
+
type: Boolean,
|
138
|
+
default: true,
|
139
|
+
},
|
140
|
+
backgroundColor: {
|
141
|
+
type: String,
|
142
|
+
default: '',
|
143
|
+
},
|
144
|
+
},
|
145
|
+
setup(props) {
|
146
|
+
const showAlertDialog = ref(false);
|
147
|
+
const alertMessage = ref('');
|
148
|
+
|
149
|
+
// 计算当前高度的缩放比例
|
150
|
+
const getScaleRatio = () => {
|
151
|
+
const heightValues = {
|
152
|
+
sm: 256,
|
153
|
+
md: 320,
|
154
|
+
lg: 384,
|
155
|
+
xl: 480,
|
156
|
+
'2xl': 560,
|
157
|
+
'3xl': 640,
|
158
|
+
'4xl': 720,
|
159
|
+
'5xl': 800,
|
160
|
+
};
|
161
|
+
const currentHeight = heightValues[props.height];
|
162
|
+
// 基于特定高度计算缩放比例
|
163
|
+
return currentHeight / 500;
|
164
|
+
};
|
165
|
+
|
166
|
+
return {
|
167
|
+
showAlertDialog,
|
168
|
+
alertMessage,
|
169
|
+
iphoneFrame: (iphoneFrame as any).src || iphoneFrame,
|
170
|
+
heightClasses,
|
171
|
+
mainContentWidthAspectRatio,
|
172
|
+
mainContentHeightAspectRatio,
|
173
|
+
iphoneFrameWidth,
|
174
|
+
iphoneFrameHeight,
|
175
|
+
iphoneFrameStatusBarTop,
|
176
|
+
iphoneFrameStatusBarHeight,
|
177
|
+
iphoneFrameStatusBarHeightAspectRatio,
|
178
|
+
iphoneFrameStatusBarTopAspectRatio,
|
179
|
+
getScaleRatio,
|
180
|
+
};
|
181
|
+
},
|
180
182
|
});
|
181
183
|
</script>
|
182
184
|
|
183
185
|
<template>
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
186
|
+
<div
|
187
|
+
:class="['cosy:relative', heightClasses[height]]"
|
188
|
+
:style="{
|
189
|
+
aspectRatio: `${iphoneFrameWidth}/${iphoneFrameHeight}`,
|
190
|
+
// 调试模式,背景色为半透明的黄色
|
191
|
+
backgroundColor: debug ? 'rgba(255, 255, 0, 0.3)' : 'transparent',
|
192
|
+
}"
|
193
|
+
>
|
194
|
+
<!-- iPhone 边框 -->
|
195
|
+
<img
|
196
|
+
v-if="showFrame"
|
197
|
+
style="max-width: 100%; max-height: 100%"
|
198
|
+
:src="iphoneFrame"
|
199
|
+
alt="iPhone frame"
|
200
|
+
/>
|
201
|
+
|
202
|
+
<!-- 顶部状态栏 -->
|
203
|
+
<div
|
204
|
+
:style="{
|
205
|
+
position: 'absolute',
|
206
|
+
top: iphoneFrameStatusBarTopAspectRatio * 100 + '%',
|
207
|
+
height: iphoneFrameStatusBarHeightAspectRatio * 100 + '%',
|
208
|
+
width: mainContentWidthAspectRatio * 100 + '%',
|
209
|
+
left: '50%',
|
210
|
+
transform: 'translate(-50%, 0)',
|
211
|
+
paddingLeft: '5%',
|
212
|
+
paddingRight: '5%',
|
213
|
+
// 调试模式,背景色为半透明的红色
|
214
|
+
backgroundColor: debug ? 'rgba(255, 0, 0, 0.3)' : 'transparent',
|
215
|
+
zIndex: 10,
|
216
|
+
}"
|
217
|
+
>
|
218
|
+
<StatusBarContent :scaleRatio="getScaleRatio()" />
|
219
|
+
</div>
|
220
|
+
|
221
|
+
<!-- 内容区域 -->
|
222
|
+
<div
|
223
|
+
class="cosy:inset-0 cosy:h-full"
|
224
|
+
:style="{
|
225
|
+
width: mainContentWidthAspectRatio * 100 + '%',
|
226
|
+
height: mainContentHeightAspectRatio * 100 + '%',
|
227
|
+
// 水平居中
|
228
|
+
left: '50%',
|
229
|
+
// 垂直居中
|
230
|
+
top: '50%',
|
231
|
+
transform: 'translate(-50%, -50%)',
|
232
|
+
position: 'absolute',
|
233
|
+
// 调试模式,背景色为半透明的蓝色
|
234
|
+
backgroundColor: debug ? 'rgba(0, 0, 255, 0.3)' : 'transparent',
|
235
|
+
zIndex: 10,
|
236
|
+
}"
|
237
|
+
>
|
238
|
+
<div
|
239
|
+
:class="[
|
240
|
+
debug ? 'cosy:bg-green-300/50' : '',
|
241
|
+
'cosy:h-full cosy:w-full cosy:overflow-hidden',
|
242
|
+
]"
|
243
|
+
>
|
244
|
+
<slot />
|
245
|
+
</div>
|
227
246
|
</div>
|
247
|
+
</div>
|
228
248
|
|
229
|
-
|
230
|
-
</template>
|
249
|
+
<AlertDialog v-model="showAlertDialog" :message="alertMessage" />
|
250
|
+
</template>
|