@xlui/xux-ui 0.2.1 → 1.1.0
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/assets/areas.worker-Ci--LHMH.js +1 -0
- package/dist/browser-Bfcp93e9.js +8 -0
- package/dist/browser-Dj1SWzn2.mjs +1456 -0
- package/dist/index.css +1 -1
- package/dist/index.js +32 -32
- package/dist/index.mjs +18021 -2703
- package/package.json +70 -63
- package/src/components/Button/index.vue +6 -6
- package/src/components/Card/index.vue +44 -11
- package/src/components/DateTimePicker/index.vue +121 -39
- package/src/components/Qrcode/index.vue +390 -0
- package/src/components/RegionCascader/areas.worker.ts +196 -0
- package/src/components/RegionCascader/data/china-areas.full.json +14464 -0
- package/src/components/RegionCascader/data/init.mjs +377 -0
- package/src/components/RegionCascader/index.vue +870 -0
- package/src/components/Select/index.vue +25 -22
- package/src/components/SpecialEffects/fireworks.vue +134 -0
- package/src/components/SpecialEffects/glow.vue +377 -0
- package/src/components/Switch/index.vue +335 -0
- package/src/index.ts +9 -0
- package/LICENSE +0 -194
@@ -53,15 +53,16 @@
|
|
53
53
|
</template>
|
54
54
|
</div>
|
55
55
|
</div>
|
56
|
-
<
|
56
|
+
<Icon
|
57
57
|
:class="[
|
58
|
-
'
|
58
|
+
'text-gray-400 transition-transform duration-300 ease-in-out text-lg',
|
59
59
|
{
|
60
|
-
'
|
61
|
-
'
|
60
|
+
'rotate-180': isOpen,
|
61
|
+
'rotate-0': !isOpen
|
62
62
|
}
|
63
63
|
]"
|
64
|
-
|
64
|
+
icon="mdi:chevron-down"
|
65
|
+
></Icon>
|
65
66
|
</div>
|
66
67
|
|
67
68
|
<!-- 下拉菜单 -->
|
@@ -116,23 +117,24 @@
|
|
116
117
|
:tabindex="0"
|
117
118
|
>
|
118
119
|
<div class="flex items-center gap-3">
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
120
|
+
<!-- 多选复选框 -->
|
121
|
+
<div v-if="multiple" class="flex items-center">
|
122
|
+
<div
|
123
|
+
:class="[
|
124
|
+
'w-4 h-4 rounded border flex items-center justify-center transition-all duration-150',
|
125
|
+
{
|
126
|
+
'border-[#1a1a1a] ': isSelected(option),
|
127
|
+
'border-gray-300 bg-white': !isSelected(option)
|
128
|
+
}
|
129
|
+
]"
|
130
|
+
>
|
131
|
+
<Icon
|
132
|
+
v-if="isSelected(option)"
|
133
|
+
icon="mdi:check"
|
134
|
+
class="text-[#1a1a1a] text-xs font-bold"
|
135
|
+
></Icon>
|
136
|
+
</div>
|
137
|
+
</div>
|
136
138
|
<!-- 单选单选框 -->
|
137
139
|
<div v-else class="flex items-center">
|
138
140
|
<div
|
@@ -160,6 +162,7 @@
|
|
160
162
|
</template>
|
161
163
|
|
162
164
|
<script setup lang="ts">
|
165
|
+
import { Icon } from '@iconify/vue'
|
163
166
|
/**
|
164
167
|
* Select 选择器组件
|
165
168
|
* @displayName XSelect
|
@@ -0,0 +1,134 @@
|
|
1
|
+
<template>
|
2
|
+
<div
|
3
|
+
class="fireworks-wrapper"
|
4
|
+
@click="handleClick"
|
5
|
+
>
|
6
|
+
<!-- 插槽:包裹任何内容 -->
|
7
|
+
<slot></slot>
|
8
|
+
|
9
|
+
<!-- 烟花效果容器 -->
|
10
|
+
<div
|
11
|
+
v-for="(firework, index) in activeFireworks"
|
12
|
+
:key="index"
|
13
|
+
class="firework-effect"
|
14
|
+
:style="{
|
15
|
+
left: `${firework.x}px`,
|
16
|
+
top: `${firework.y}px`,
|
17
|
+
}"
|
18
|
+
>
|
19
|
+
<div class="firework-particle"></div>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
</template>
|
23
|
+
|
24
|
+
<script setup lang="ts">
|
25
|
+
/**
|
26
|
+
* Fireworks 烟花特效包裹组件
|
27
|
+
* @displayName XFireworks
|
28
|
+
*/
|
29
|
+
import { ref } from 'vue'
|
30
|
+
|
31
|
+
interface Firework {
|
32
|
+
x: number
|
33
|
+
y: number
|
34
|
+
id: number
|
35
|
+
}
|
36
|
+
|
37
|
+
const activeFireworks = ref<Firework[]>([])
|
38
|
+
let fireworkId = 0
|
39
|
+
|
40
|
+
// 处理点击事件
|
41
|
+
const handleClick = (event: MouseEvent) => {
|
42
|
+
const rect = (event.currentTarget as HTMLElement).getBoundingClientRect()
|
43
|
+
const x = event.clientX - rect.left
|
44
|
+
const y = event.clientY - rect.top
|
45
|
+
|
46
|
+
const firework: Firework = {
|
47
|
+
x,
|
48
|
+
y,
|
49
|
+
id: fireworkId++
|
50
|
+
}
|
51
|
+
|
52
|
+
activeFireworks.value.push(firework)
|
53
|
+
|
54
|
+
// 1.25秒后移除烟花
|
55
|
+
setTimeout(() => {
|
56
|
+
const index = activeFireworks.value.findIndex(f => f.id === firework.id)
|
57
|
+
if (index > -1) {
|
58
|
+
activeFireworks.value.splice(index, 1)
|
59
|
+
}
|
60
|
+
}, 1250)
|
61
|
+
}
|
62
|
+
</script>
|
63
|
+
|
64
|
+
<style scoped>
|
65
|
+
/* 烟花包裹容器 */
|
66
|
+
.fireworks-wrapper {
|
67
|
+
position: relative;
|
68
|
+
display: inline-block;
|
69
|
+
cursor: pointer;
|
70
|
+
}
|
71
|
+
|
72
|
+
/* 烟花效果定位 */
|
73
|
+
.firework-effect {
|
74
|
+
position: absolute;
|
75
|
+
pointer-events: none;
|
76
|
+
z-index: 9999;
|
77
|
+
}
|
78
|
+
|
79
|
+
/* 烟花粒子 */
|
80
|
+
.firework-particle {
|
81
|
+
position: absolute;
|
82
|
+
width: 10px;
|
83
|
+
height: 10px;
|
84
|
+
border-radius: 50%;
|
85
|
+
transform: translate(-50%, -50%);
|
86
|
+
animation: fireworks-bang 1.25s ease-out forwards,
|
87
|
+
fireworks-gravity 1.25s ease-in forwards;
|
88
|
+
}
|
89
|
+
|
90
|
+
/* 烟花爆炸动画 */
|
91
|
+
@keyframes fireworks-bang {
|
92
|
+
to {
|
93
|
+
box-shadow:
|
94
|
+
114px -107px #8800ff,
|
95
|
+
212px -166px #a600ff,
|
96
|
+
197px -6px #ff006a,
|
97
|
+
179px -329px #3300ff,
|
98
|
+
-167px -262px #ff0062,
|
99
|
+
233px 66px #ff008c,
|
100
|
+
81px 43px #0051ff,
|
101
|
+
-13px 55px #00ff2b,
|
102
|
+
-60px -183px #0900ff,
|
103
|
+
127px -259px #ff00e6,
|
104
|
+
117px -122px #00b7ff,
|
105
|
+
95px 21px #ff8000,
|
106
|
+
115px 2px #0004ff,
|
107
|
+
-160px -328px #00ff40,
|
108
|
+
69px -242px #000dff,
|
109
|
+
-208px -230px #ff0400,
|
110
|
+
30px -15px #e6ff00,
|
111
|
+
235px -15px #fb00ff,
|
112
|
+
80px -232px #d5ff00,
|
113
|
+
175px -173px #00ff3c,
|
114
|
+
-187px -176px #aaff00,
|
115
|
+
4px 27px #ff6f00,
|
116
|
+
227px -106px #ff0099,
|
117
|
+
119px 18px #00ffd5,
|
118
|
+
-102px 5px #ff0088,
|
119
|
+
-16px -4px #00fff7,
|
120
|
+
-201px -310px #00ffdd,
|
121
|
+
64px -181px #f700ff,
|
122
|
+
-234px -15px #00fffb,
|
123
|
+
-184px -263px #aa00ff;
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
127
|
+
/* 重力下落动画 */
|
128
|
+
@keyframes fireworks-gravity {
|
129
|
+
to {
|
130
|
+
transform: translate(-50%, -50%) translateY(200px);
|
131
|
+
opacity: 0;
|
132
|
+
}
|
133
|
+
}
|
134
|
+
</style>
|
@@ -0,0 +1,377 @@
|
|
1
|
+
<template>
|
2
|
+
<div class="glow-button-wrapper">
|
3
|
+
<button
|
4
|
+
class="glow-button"
|
5
|
+
:style="buttonStyle"
|
6
|
+
@click="handleClick"
|
7
|
+
>
|
8
|
+
<span class="spark"></span>
|
9
|
+
<span class="backdrop"></span>
|
10
|
+
|
11
|
+
<!-- 星星图标 -->
|
12
|
+
<svg class="sparkle" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
13
|
+
<path d="M14.187 8.096L15 5.25L15.813 8.096C16.0231 8.83114 16.4171 9.50062 16.9577 10.0413C17.4984 10.5819 18.1679 10.9759 18.903 11.186L21.75 12L18.904 12.813C18.1689 13.0231 17.4994 13.4171 16.9587 13.9577C16.4181 14.4984 16.0241 15.1679 15.814 15.903L15 18.75L14.187 15.904C13.9769 15.1689 13.5829 14.4994 13.0423 13.9587C12.5016 13.4181 11.8321 13.0241 11.097 12.814L8.25 12L11.096 11.187C11.8311 10.9769 12.5006 10.5829 13.0413 10.0423C13.5819 9.50162 13.9759 8.83214 14.186 8.097L14.187 8.096Z" fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path>
|
14
|
+
<path d="M6 14.25L5.741 15.285C5.59267 15.8785 5.28579 16.4206 4.85319 16.8532C4.42059 17.2858 3.87853 17.5927 3.285 17.741L2.25 18L3.285 18.259C3.87853 18.4073 4.42059 18.7142 4.85319 19.1468C5.28579 19.5794 5.59267 20.1215 5.741 20.715L6 21.75L6.259 20.715C6.40725 20.1216 6.71398 19.5796 7.14639 19.147C7.5788 18.7144 8.12065 18.4075 8.714 18.259L9.75 18L8.714 17.741C8.12065 17.5925 7.5788 17.2856 7.14639 16.853C6.71398 16.4204 6.40725 15.8784 6.259 15.285L6 14.25Z" fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path>
|
15
|
+
<path d="M6.5 4L6.303 4.5915C6.24777 4.75718 6.15472 4.90774 6.03123 5.03123C5.90774 5.15472 5.75718 5.24777 5.5915 5.303L5 5.5L5.5915 5.697C5.75718 5.75223 5.90774 5.84528 6.03123 5.96877C6.15472 6.09226 6.24777 6.24282 6.303 6.4085L6.5 7L6.697 6.4085C6.75223 6.24282 6.84528 6.09226 6.96877 5.96877C7.09226 5.84528 7.24282 5.75223 7.4085 5.697L8 5.5L7.4085 5.303C7.24282 5.24777 7.09226 5.15472 6.96877 5.03123C6.84528 4.90774 6.75223 4.75718 6.697 4.5915L6.5 4Z" fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path>
|
16
|
+
</svg>
|
17
|
+
|
18
|
+
<span class="text">
|
19
|
+
<slot>{{ text }}</slot>
|
20
|
+
</span>
|
21
|
+
</button>
|
22
|
+
|
23
|
+
<div class="bodydrop"></div>
|
24
|
+
|
25
|
+
<!-- 粒子效果 -->
|
26
|
+
<span aria-hidden="true" class="particle-pen">
|
27
|
+
<svg v-for="i in 20" :key="i" class="particle" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
28
|
+
<path d="M6.937 3.846L7.75 1L8.563 3.846C8.77313 4.58114 9.1671 5.25062 9.70774 5.79126C10.2484 6.3319 10.9179 6.72587 11.653 6.936L14.5 7.75L11.654 8.563C10.9189 8.77313 10.2494 9.1671 9.70874 9.70774C9.1681 10.2484 8.77413 10.9179 8.564 11.653L7.75 14.5L6.937 11.654C6.72687 10.9189 6.3329 10.2494 5.79226 9.70874C5.25162 9.1681 4.58214 8.77413 3.847 8.564L1 7.75L3.846 6.937C4.58114 6.72687 5.25062 6.3329 5.79126 5.79226C6.3319 5.25162 6.72587 4.58214 6.936 3.847L6.937 3.846Z" fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path>
|
29
|
+
</svg>
|
30
|
+
</span>
|
31
|
+
</div>
|
32
|
+
</template>
|
33
|
+
|
34
|
+
<script setup lang="ts">
|
35
|
+
/**
|
36
|
+
* GButton 发光按钮组件
|
37
|
+
* @displayName XGButton
|
38
|
+
*
|
39
|
+
* 使用方法:
|
40
|
+
* <XGButton color="#8b5cf6">点击我</XGButton>
|
41
|
+
*/
|
42
|
+
import { computed } from 'vue'
|
43
|
+
|
44
|
+
export interface GButtonProps {
|
45
|
+
/** 按钮文字 */
|
46
|
+
text?: string
|
47
|
+
/** 发光颜色(Hex格式) */
|
48
|
+
color?: string
|
49
|
+
/** 按钮大小 */
|
50
|
+
size?: 'small' | 'medium' | 'large'
|
51
|
+
}
|
52
|
+
|
53
|
+
const props = withDefaults(defineProps<GButtonProps>(), {
|
54
|
+
text: 'Button',
|
55
|
+
color: '#8b5cf6', // 默认紫色
|
56
|
+
size: 'medium'
|
57
|
+
})
|
58
|
+
|
59
|
+
const emit = defineEmits<{
|
60
|
+
click: [event: MouseEvent]
|
61
|
+
}>()
|
62
|
+
|
63
|
+
// 将hex颜色转换为HSL
|
64
|
+
const hexToHsl = (hex: string) => {
|
65
|
+
// 移除 # 号
|
66
|
+
hex = hex.replace('#', '')
|
67
|
+
|
68
|
+
// 转换为RGB
|
69
|
+
const r = parseInt(hex.substring(0, 2), 16) / 255
|
70
|
+
const g = parseInt(hex.substring(2, 4), 16) / 255
|
71
|
+
const b = parseInt(hex.substring(4, 6), 16) / 255
|
72
|
+
|
73
|
+
const max = Math.max(r, g, b)
|
74
|
+
const min = Math.min(r, g, b)
|
75
|
+
let h = 0
|
76
|
+
let s = 0
|
77
|
+
const l = (max + min) / 2
|
78
|
+
|
79
|
+
if (max !== min) {
|
80
|
+
const d = max - min
|
81
|
+
s = l > 0.5 ? d / (2 - max - min) : d / (max + min)
|
82
|
+
|
83
|
+
switch (max) {
|
84
|
+
case r: h = ((g - b) / d + (g < b ? 6 : 0)) / 6; break
|
85
|
+
case g: h = ((b - r) / d + 2) / 6; break
|
86
|
+
case b: h = ((r - g) / d + 4) / 6; break
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
return {
|
91
|
+
h: Math.round(h * 360),
|
92
|
+
s: Math.round(s * 100),
|
93
|
+
l: Math.round(l * 100)
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
const hslColor = computed(() => hexToHsl(props.color))
|
98
|
+
|
99
|
+
const sizeMap = {
|
100
|
+
small: '0.9rem',
|
101
|
+
medium: '1.2rem',
|
102
|
+
large: '1.5rem'
|
103
|
+
}
|
104
|
+
|
105
|
+
const buttonStyle = computed(() => ({
|
106
|
+
'--hue': hslColor.value.h,
|
107
|
+
'--saturation': `${hslColor.value.s}%`,
|
108
|
+
'--lightness': `${hslColor.value.l}%`,
|
109
|
+
'--font-size': sizeMap[props.size]
|
110
|
+
}))
|
111
|
+
|
112
|
+
const handleClick = (event: MouseEvent) => {
|
113
|
+
emit('click', event)
|
114
|
+
}
|
115
|
+
</script>
|
116
|
+
|
117
|
+
<style scoped>
|
118
|
+
.glow-button-wrapper {
|
119
|
+
position: relative;
|
120
|
+
display: inline-block;
|
121
|
+
}
|
122
|
+
|
123
|
+
.glow-button {
|
124
|
+
--active: 0;
|
125
|
+
--hue: 260;
|
126
|
+
--saturation: 97%;
|
127
|
+
--lightness: 50%;
|
128
|
+
|
129
|
+
--bg: radial-gradient(
|
130
|
+
40% 50% at center 100%,
|
131
|
+
hsl(var(--hue) calc(var(--active) * var(--saturation)) 72% / var(--active)),
|
132
|
+
transparent
|
133
|
+
),
|
134
|
+
radial-gradient(
|
135
|
+
80% 100% at center 120%,
|
136
|
+
hsl(var(--hue) calc(var(--active) * var(--saturation)) 70% / var(--active)),
|
137
|
+
transparent
|
138
|
+
),
|
139
|
+
hsl(var(--hue) calc(var(--active) * var(--saturation)) calc((var(--active) * 44%) + 12%));
|
140
|
+
|
141
|
+
background: var(--bg);
|
142
|
+
font-size: var(--font-size, 1.2rem);
|
143
|
+
font-weight: 500;
|
144
|
+
border: 0;
|
145
|
+
cursor: pointer;
|
146
|
+
padding: 1em 1.5em;
|
147
|
+
display: flex;
|
148
|
+
align-items: center;
|
149
|
+
gap: 0.5em;
|
150
|
+
white-space: nowrap;
|
151
|
+
border-radius: 100px;
|
152
|
+
position: relative;
|
153
|
+
box-shadow:
|
154
|
+
0 0 calc(var(--active) * 3em) calc(var(--active) * 1em) hsl(var(--hue) var(--saturation) 61% / 0.75),
|
155
|
+
0 0em 0 0 hsl(var(--hue) calc(var(--active) * var(--saturation)) calc((var(--active) * 50%) + 30%)) inset,
|
156
|
+
0 -0.05em 0 0 hsl(var(--hue) calc(var(--active) * var(--saturation)) calc(var(--active) * 60%)) inset;
|
157
|
+
transition: box-shadow 0.3s, scale 0.3s, background 0.3s;
|
158
|
+
scale: calc(1 + (var(--active) * 0.1));
|
159
|
+
}
|
160
|
+
|
161
|
+
.glow-button:active {
|
162
|
+
scale: 1;
|
163
|
+
}
|
164
|
+
|
165
|
+
.glow-button:hover,
|
166
|
+
.glow-button:focus-visible {
|
167
|
+
--active: 1;
|
168
|
+
}
|
169
|
+
|
170
|
+
.glow-button:before {
|
171
|
+
content: "";
|
172
|
+
position: absolute;
|
173
|
+
inset: -0.2em;
|
174
|
+
z-index: -1;
|
175
|
+
border: 0.25em solid hsl(var(--hue) var(--saturation) var(--lightness) / 0.5);
|
176
|
+
border-radius: 100px;
|
177
|
+
opacity: var(--active, 0);
|
178
|
+
transition: opacity 0.3s;
|
179
|
+
}
|
180
|
+
|
181
|
+
.spark {
|
182
|
+
position: absolute;
|
183
|
+
inset: 0;
|
184
|
+
border-radius: 100px;
|
185
|
+
rotate: 0deg;
|
186
|
+
overflow: hidden;
|
187
|
+
mask: linear-gradient(white, transparent 50%);
|
188
|
+
animation: flip 2s infinite steps(2, end);
|
189
|
+
}
|
190
|
+
|
191
|
+
@keyframes flip {
|
192
|
+
to {
|
193
|
+
rotate: 360deg;
|
194
|
+
}
|
195
|
+
}
|
196
|
+
|
197
|
+
.spark:before {
|
198
|
+
content: "";
|
199
|
+
position: absolute;
|
200
|
+
width: 200%;
|
201
|
+
aspect-ratio: 1;
|
202
|
+
top: 0%;
|
203
|
+
left: 50%;
|
204
|
+
z-index: -1;
|
205
|
+
translate: -50% -15%;
|
206
|
+
rotate: 0;
|
207
|
+
transform: rotate(-90deg);
|
208
|
+
opacity: calc((var(--active)) + 0.4);
|
209
|
+
background: conic-gradient(
|
210
|
+
from 0deg,
|
211
|
+
transparent 0 340deg,
|
212
|
+
white 360deg
|
213
|
+
);
|
214
|
+
transition: opacity 0.3s;
|
215
|
+
animation: rotate 2s linear infinite both;
|
216
|
+
}
|
217
|
+
|
218
|
+
.spark:after {
|
219
|
+
content: "";
|
220
|
+
position: absolute;
|
221
|
+
inset: 0.1em;
|
222
|
+
border-radius: 100px;
|
223
|
+
}
|
224
|
+
|
225
|
+
.backdrop {
|
226
|
+
position: absolute;
|
227
|
+
inset: 0.1em;
|
228
|
+
background: var(--bg);
|
229
|
+
border-radius: 100px;
|
230
|
+
transition: background 0.3s;
|
231
|
+
}
|
232
|
+
|
233
|
+
@keyframes rotate {
|
234
|
+
to {
|
235
|
+
transform: rotate(90deg);
|
236
|
+
}
|
237
|
+
}
|
238
|
+
|
239
|
+
.sparkle {
|
240
|
+
inline-size: 1.25em;
|
241
|
+
translate: -25% -5%;
|
242
|
+
color: hsl(0 0% calc((var(--active, 0) * 70%) + 40%));
|
243
|
+
fill: currentColor;
|
244
|
+
stroke: currentColor;
|
245
|
+
transition: color 0.3s;
|
246
|
+
z-index: 1;
|
247
|
+
}
|
248
|
+
|
249
|
+
.sparkle path {
|
250
|
+
transform-box: fill-box;
|
251
|
+
transform-origin: center;
|
252
|
+
animation-delay: calc(0.45s + (var(--delay, 0) * 1s));
|
253
|
+
animation-duration: 0.6s;
|
254
|
+
}
|
255
|
+
|
256
|
+
.glow-button:is(:hover, :focus-visible) .sparkle path {
|
257
|
+
animation-name: bounce;
|
258
|
+
}
|
259
|
+
|
260
|
+
@keyframes bounce {
|
261
|
+
35%, 65% {
|
262
|
+
scale: var(--scale, 1);
|
263
|
+
}
|
264
|
+
}
|
265
|
+
|
266
|
+
.sparkle path:nth-of-type(1) {
|
267
|
+
--scale: 0.5;
|
268
|
+
--delay: 0.1;
|
269
|
+
}
|
270
|
+
|
271
|
+
.sparkle path:nth-of-type(2) {
|
272
|
+
--scale: 1.5;
|
273
|
+
--delay: 0.2;
|
274
|
+
}
|
275
|
+
|
276
|
+
.sparkle path:nth-of-type(3) {
|
277
|
+
--scale: 2.5;
|
278
|
+
--delay: 0.35;
|
279
|
+
}
|
280
|
+
|
281
|
+
.text {
|
282
|
+
translate: 2% -6%;
|
283
|
+
letter-spacing: 0.01ch;
|
284
|
+
background: linear-gradient(
|
285
|
+
90deg,
|
286
|
+
hsl(0 0% calc((var(--active) * 100%) + 65%)),
|
287
|
+
hsl(0 0% calc((var(--active) * 100%) + 26%))
|
288
|
+
);
|
289
|
+
-webkit-background-clip: text;
|
290
|
+
background-clip: text;
|
291
|
+
color: transparent;
|
292
|
+
transition: background 0.3s;
|
293
|
+
z-index: 1;
|
294
|
+
}
|
295
|
+
|
296
|
+
.bodydrop {
|
297
|
+
display: none;
|
298
|
+
}
|
299
|
+
|
300
|
+
.particle-pen {
|
301
|
+
position: absolute;
|
302
|
+
width: 200%;
|
303
|
+
aspect-ratio: 1;
|
304
|
+
top: 50%;
|
305
|
+
left: 50%;
|
306
|
+
translate: -50% -50%;
|
307
|
+
-webkit-mask: radial-gradient(white, transparent 65%);
|
308
|
+
mask: radial-gradient(white, transparent 65%);
|
309
|
+
z-index: -1;
|
310
|
+
opacity: var(--active, 0);
|
311
|
+
transition: opacity 0.3s;
|
312
|
+
pointer-events: none;
|
313
|
+
}
|
314
|
+
|
315
|
+
.glow-button:is(:hover, :focus-visible) ~ .particle-pen {
|
316
|
+
--active: 1;
|
317
|
+
}
|
318
|
+
|
319
|
+
.particle {
|
320
|
+
fill: white;
|
321
|
+
width: 0.25rem;
|
322
|
+
aspect-ratio: 1;
|
323
|
+
position: absolute;
|
324
|
+
opacity: 0.8;
|
325
|
+
animation: float-out 1s infinite linear;
|
326
|
+
transform-origin: 1000% 1000%;
|
327
|
+
z-index: -1;
|
328
|
+
animation-play-state: paused;
|
329
|
+
}
|
330
|
+
|
331
|
+
.glow-button:is(:hover, :focus-visible) ~ .particle-pen .particle {
|
332
|
+
animation-play-state: running;
|
333
|
+
}
|
334
|
+
|
335
|
+
.particle path {
|
336
|
+
fill: hsl(0 0% 90%);
|
337
|
+
stroke: none;
|
338
|
+
}
|
339
|
+
|
340
|
+
.particle:nth-of-type(even) {
|
341
|
+
animation-direction: reverse;
|
342
|
+
}
|
343
|
+
|
344
|
+
/* 为每个粒子设置不同的位置和延迟 */
|
345
|
+
.particle:nth-of-type(1) { --x: 20; --y: 10; --delay: -0.1s; }
|
346
|
+
.particle:nth-of-type(2) { --x: 80; --y: 15; --delay: -0.2s; }
|
347
|
+
.particle:nth-of-type(3) { --x: 50; --y: 5; --delay: -0.3s; }
|
348
|
+
.particle:nth-of-type(4) { --x: 10; --y: 30; --delay: -0.4s; }
|
349
|
+
.particle:nth-of-type(5) { --x: 90; --y: 35; --delay: -0.5s; }
|
350
|
+
.particle:nth-of-type(6) { --x: 30; --y: 85; --delay: -0.6s; }
|
351
|
+
.particle:nth-of-type(7) { --x: 70; --y: 90; --delay: -0.7s; }
|
352
|
+
.particle:nth-of-type(8) { --x: 15; --y: 60; --delay: -0.8s; }
|
353
|
+
.particle:nth-of-type(9) { --x: 85; --y: 65; --delay: -0.9s; }
|
354
|
+
.particle:nth-of-type(10) { --x: 45; --y: 95; --delay: -1s; }
|
355
|
+
.particle:nth-of-type(11) { --x: 25; --y: 45; --delay: -1.1s; }
|
356
|
+
.particle:nth-of-type(12) { --x: 75; --y: 50; --delay: -1.2s; }
|
357
|
+
.particle:nth-of-type(13) { --x: 5; --y: 75; --delay: -1.3s; }
|
358
|
+
.particle:nth-of-type(14) { --x: 95; --y: 80; --delay: -1.4s; }
|
359
|
+
.particle:nth-of-type(15) { --x: 55; --y: 25; --delay: -1.5s; }
|
360
|
+
.particle:nth-of-type(16) { --x: 35; --y: 70; --delay: -1.6s; }
|
361
|
+
.particle:nth-of-type(17) { --x: 65; --y: 20; --delay: -1.7s; }
|
362
|
+
.particle:nth-of-type(18) { --x: 40; --y: 55; --delay: -1.8s; }
|
363
|
+
.particle:nth-of-type(19) { --x: 60; --y: 40; --delay: -1.9s; }
|
364
|
+
.particle:nth-of-type(20) { --x: 50; --y: 50; --delay: -2s; }
|
365
|
+
|
366
|
+
.particle {
|
367
|
+
top: calc(var(--y) * 1%);
|
368
|
+
left: calc(var(--x) * 1%);
|
369
|
+
animation-delay: var(--delay);
|
370
|
+
}
|
371
|
+
|
372
|
+
@keyframes float-out {
|
373
|
+
to {
|
374
|
+
rotate: 360deg;
|
375
|
+
}
|
376
|
+
}
|
377
|
+
</style>
|