srcdev-nuxt-components 1.1.2 → 1.1.4
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.
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
.container-glow-wrapper {
|
|
2
|
+
--container-bg-colour: light-dark(hsl(250, 18%, 93%), hsl(246 44% 7%));
|
|
3
|
+
--container-border-colour: hsl(280 10% 50% / 1);
|
|
4
|
+
--card: light-dark(white, hsl(246 44% 7%));
|
|
5
|
+
--container-border-width: 2px;
|
|
6
|
+
--container-border-radius: 12px;
|
|
7
|
+
--gradient: conic-gradient(
|
|
8
|
+
from 180deg at 50% 70%,
|
|
9
|
+
hsla(0, 0%, 98%, 1) 0deg,
|
|
10
|
+
#eec32d 72.0000010728836deg,
|
|
11
|
+
#fc0303 144.0000021457672deg,
|
|
12
|
+
#709ab9 216.00000858306885deg,
|
|
13
|
+
#4dffbf 288.0000042915344deg,
|
|
14
|
+
hsla(0, 0%, 98%, 1) 1turn
|
|
15
|
+
);
|
|
16
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="container-glow-wrapper" ref="containerGlowWrapper">
|
|
3
|
+
<template v-for="(item, key) in data" :key="key">
|
|
4
|
+
<component :is="tag" class="container-glow-core" :class="elementClasses" ref="containerGlowItem">
|
|
5
|
+
<div class="glows"></div>
|
|
6
|
+
<slot :name="`container-glow-${key}`"></slot>
|
|
7
|
+
</component>
|
|
8
|
+
</template>
|
|
9
|
+
</div>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script setup lang="ts">
|
|
13
|
+
interface Data {
|
|
14
|
+
title: string;
|
|
15
|
+
content: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const props = defineProps({
|
|
19
|
+
data: {
|
|
20
|
+
type: Array as PropType<Data[]>,
|
|
21
|
+
default: () => [],
|
|
22
|
+
},
|
|
23
|
+
tag: {
|
|
24
|
+
type: String as PropType<string>,
|
|
25
|
+
default: 'div',
|
|
26
|
+
},
|
|
27
|
+
styleClassPassthrough: {
|
|
28
|
+
type: Array as PropType<string[]>,
|
|
29
|
+
default: () => [],
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
|
|
34
|
+
|
|
35
|
+
const controller = new AbortController();
|
|
36
|
+
|
|
37
|
+
const containerGlowWrapper = ref<HTMLElement>();
|
|
38
|
+
const containerGlowItem = ref<HTMLElement[]>([]);
|
|
39
|
+
|
|
40
|
+
const CONFIG = {
|
|
41
|
+
proximity: 40,
|
|
42
|
+
spread: 80,
|
|
43
|
+
blur: 20,
|
|
44
|
+
gap: 32,
|
|
45
|
+
vertical: false,
|
|
46
|
+
opacity: 0,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const PROXIMITY = 10;
|
|
50
|
+
|
|
51
|
+
const UPDATE = (event: PointerEvent) => {
|
|
52
|
+
// get the angle based on the center point of the card and pointer position
|
|
53
|
+
for (const CARD of containerGlowItem.value) {
|
|
54
|
+
// Check the card against the proximity and then start updating
|
|
55
|
+
const CARD_BOUNDS = CARD.getBoundingClientRect();
|
|
56
|
+
// Get distance between pointer and outerbounds of card
|
|
57
|
+
if (
|
|
58
|
+
event?.x > CARD_BOUNDS.left - CONFIG.proximity &&
|
|
59
|
+
event?.x < CARD_BOUNDS.left + CARD_BOUNDS.width + CONFIG.proximity &&
|
|
60
|
+
event?.y > CARD_BOUNDS.top - CONFIG.proximity &&
|
|
61
|
+
event?.y < CARD_BOUNDS.top + CARD_BOUNDS.height + CONFIG.proximity
|
|
62
|
+
) {
|
|
63
|
+
// If within proximity set the active opacity
|
|
64
|
+
CARD.style.setProperty('--active', String(1));
|
|
65
|
+
} else {
|
|
66
|
+
CARD.style.setProperty('--active', String(CONFIG.opacity));
|
|
67
|
+
}
|
|
68
|
+
const CARD_CENTER = [CARD_BOUNDS.left + CARD_BOUNDS.width * 0.5, CARD_BOUNDS.top + CARD_BOUNDS.height * 0.5];
|
|
69
|
+
let ANGLE = (Math.atan2(event?.y - CARD_CENTER[1], event?.x - CARD_CENTER[0]) * 180) / Math.PI;
|
|
70
|
+
ANGLE = ANGLE < 0 ? ANGLE + 360 : ANGLE;
|
|
71
|
+
CARD.style.setProperty('--start', String(ANGLE + 90));
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const RESTYLE = () => {
|
|
76
|
+
containerGlowWrapper.value?.style.setProperty('--gap', String(CONFIG.gap));
|
|
77
|
+
containerGlowWrapper.value?.style.setProperty('--blur', String(CONFIG.blur));
|
|
78
|
+
containerGlowWrapper.value?.style.setProperty('--spread', String(CONFIG.spread));
|
|
79
|
+
containerGlowWrapper.value?.style.setProperty('--direction', CONFIG.vertical ? 'column' : 'row');
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// document.body.addEventListener('pointermove', UPDATE);
|
|
83
|
+
|
|
84
|
+
onMounted(() => {
|
|
85
|
+
RESTYLE();
|
|
86
|
+
if (containerGlowWrapper.value) {
|
|
87
|
+
document.body.addEventListener('pointermove', UPDATE, {
|
|
88
|
+
signal: controller.signal,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
onBeforeUnmount(() => {
|
|
94
|
+
return controller.abort();
|
|
95
|
+
});
|
|
96
|
+
</script>
|
|
97
|
+
|
|
98
|
+
<style lang="css">
|
|
99
|
+
.container-glow-wrapper {
|
|
100
|
+
--container-bg-colour: light-dark(hsl(250, 18%, 93%), hsl(246 44% 7%));
|
|
101
|
+
--container-border-colour: hsl(280 10% 50% / 1);
|
|
102
|
+
--card: light-dark(white, hsl(246 44% 7%));
|
|
103
|
+
--container-border-width: 2px;
|
|
104
|
+
--container-border-radius: 12px;
|
|
105
|
+
--gradient: conic-gradient(
|
|
106
|
+
from 180deg at 50% 70%,
|
|
107
|
+
hsla(0, 0%, 98%, 1) 0deg,
|
|
108
|
+
#eec32d 72.0000010728836deg,
|
|
109
|
+
#ec4b4b 144.0000021457672deg,
|
|
110
|
+
#709ab9 216.00000858306885deg,
|
|
111
|
+
#4dffbf 288.0000042915344deg,
|
|
112
|
+
hsla(0, 0%, 98%, 1) 1turn
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
@property --start {
|
|
116
|
+
syntax: '<number>';
|
|
117
|
+
inherits: true;
|
|
118
|
+
initial-value: 0;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
display: flex;
|
|
122
|
+
gap: 3.2rem;
|
|
123
|
+
|
|
124
|
+
.container-glow-core {
|
|
125
|
+
& *,
|
|
126
|
+
& *:after,
|
|
127
|
+
& *:before {
|
|
128
|
+
box-sizing: border-box;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
--active: 0.15;
|
|
132
|
+
--start: 0;
|
|
133
|
+
height: 100%;
|
|
134
|
+
background: var(--card);
|
|
135
|
+
padding: 2rem;
|
|
136
|
+
aspect-ratio: 330 / 400;
|
|
137
|
+
border-radius: var(--container-border-radius);
|
|
138
|
+
min-width: 280px;
|
|
139
|
+
max-width: 280px;
|
|
140
|
+
display: flex;
|
|
141
|
+
flex-direction: column;
|
|
142
|
+
gap: 0.25rem;
|
|
143
|
+
position: relative;
|
|
144
|
+
|
|
145
|
+
&:is(:hover, :focus-visible) {
|
|
146
|
+
z-index: 2;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
&::before {
|
|
150
|
+
position: absolute;
|
|
151
|
+
inset: 0;
|
|
152
|
+
border: var(--container-border-width) solid transparent;
|
|
153
|
+
content: '';
|
|
154
|
+
border-radius: var(--container-border-radius);
|
|
155
|
+
pointer-events: none;
|
|
156
|
+
background: var(--container-border-colour);
|
|
157
|
+
background-attachment: fixed;
|
|
158
|
+
border-radius: var(--container-border-radius);
|
|
159
|
+
mask: linear-gradient(#0000, #0000),
|
|
160
|
+
conic-gradient(from calc(((var(--start) + (var(--spread) * 0.25)) - (var(--spread) * 1.5)) * 1deg), hsl(0 0% 100% / 0.15) 0deg, white, hsl(0 0% 100% / 0.15) calc(var(--spread) * 2.5deg));
|
|
161
|
+
mask-clip: padding-box, border-box;
|
|
162
|
+
mask-composite: intersect;
|
|
163
|
+
opacity: var(--active);
|
|
164
|
+
transition: opacity 1s;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
&::after {
|
|
168
|
+
/* --container-bg-colour-size: 100%; */
|
|
169
|
+
content: '';
|
|
170
|
+
pointer-events: none;
|
|
171
|
+
position: absolute;
|
|
172
|
+
background: var(--gradient);
|
|
173
|
+
background-attachment: fixed;
|
|
174
|
+
border-radius: var(--container-border-radius);
|
|
175
|
+
opacity: var(--active, 0);
|
|
176
|
+
transition: opacity 1s;
|
|
177
|
+
--alpha: 0;
|
|
178
|
+
inset: 0;
|
|
179
|
+
border: var(--container-border-width) solid transparent;
|
|
180
|
+
mask: linear-gradient(#0000, #0000), conic-gradient(from calc(((var(--start) + (var(--spread) * 0.25)) - (var(--spread) * 0.5)) * 1deg), #0000 0deg, #fff, #0000 calc(var(--spread) * 0.5deg));
|
|
181
|
+
filter: brightness(1.5);
|
|
182
|
+
mask-clip: padding-box, border-box;
|
|
183
|
+
mask-composite: intersect;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.glows {
|
|
187
|
+
pointer-events: none;
|
|
188
|
+
position: absolute;
|
|
189
|
+
inset: 0;
|
|
190
|
+
filter: blur(calc(var(--blur) * 1px));
|
|
191
|
+
|
|
192
|
+
&::after,
|
|
193
|
+
&::before {
|
|
194
|
+
--alpha: 0;
|
|
195
|
+
content: '';
|
|
196
|
+
background: var(--gradient);
|
|
197
|
+
background-attachment: fixed;
|
|
198
|
+
position: absolute;
|
|
199
|
+
inset: -5px;
|
|
200
|
+
border: 10px solid transparent;
|
|
201
|
+
border-radius: var(--container-border-radius);
|
|
202
|
+
mask: linear-gradient(#0000, #0000), conic-gradient(from calc((var(--start) - (var(--spread) * 0.5)) * 1deg), #000 0deg, #fff, #0000 calc(var(--spread) * 1deg));
|
|
203
|
+
mask-composite: intersect;
|
|
204
|
+
mask-clip: padding-box, border-box;
|
|
205
|
+
opacity: var(--active);
|
|
206
|
+
transition: opacity 1s;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
</style>
|
package/package.json
CHANGED