@@ -7,37 +7,77 @@ const blogListData = await fetchBlogList();
7
7
8
8
const { $gsap } = useNuxtApp ();
9
9
10
+ const scrollTrigger = (target : string , start : string ) => {
11
+ return { trigger: target , start: start };
12
+ };
13
+
14
+ const firstViewAnimation = () => {
15
+ const baseOptions = {
16
+ opacity: 0 ,
17
+ duration: 1 ,
18
+ };
19
+ $gsap .from (' .fv-bg' , {
20
+ delay: 0.5 ,
21
+ ease: ' power1.out' ,
22
+ ... baseOptions ,
23
+ });
24
+ $gsap .from (' .fv-logo' , {
25
+ delay: 1.5 ,
26
+ ease: ' power1.out' ,
27
+ ... baseOptions ,
28
+ });
29
+ $gsap .from (' .fv-border' , {
30
+ delay: 2.5 ,
31
+ ease: ' power1.out' ,
32
+ ... baseOptions ,
33
+ });
34
+ };
35
+
36
+ const titleAnimation = (target : string ) => {
37
+ $gsap .from (target , {
38
+ scrollTrigger: scrollTrigger (target , ' center bottom' ),
39
+ opacity: 0 ,
40
+ y: ' 10px' ,
41
+ duration: 1 ,
42
+ delay: 0.5 ,
43
+ });
44
+ };
45
+
10
46
const conceptAnimation = (target : string , x : string , duration : number ) => {
11
47
$gsap .from (target , {
12
- scrollTrigger: {
13
- trigger: target ,
14
- start: ' top center' ,
15
- },
48
+ scrollTrigger: scrollTrigger (target , ' top bottom' ),
16
49
opacity: 0 ,
17
50
x: x ,
18
51
duration: duration ,
52
+ delay: 0.5 ,
19
53
});
20
54
};
21
55
22
56
const galleryAnimation = (target : string , y : string , duration : number ) => {
23
57
$gsap .from (target , {
24
- scrollTrigger: {
25
- trigger: target ,
26
- start: ' top bottom' ,
27
- },
58
+ scrollTrigger: scrollTrigger (target , ' top bottom' ),
28
59
opacity: 0 ,
29
60
y: y ,
30
61
duration: duration ,
62
+ delay: 0.5 ,
63
+ stagger: 0.1 ,
64
+ });
65
+ };
66
+
67
+ const menuAnimation = (target : string ) => {
68
+ $gsap .from (target , {
69
+ scrollTrigger: scrollTrigger (target , ' top bottom' ),
70
+ opacity: 0 ,
71
+ y: ' 10px' ,
72
+ duration: 1 ,
73
+ delay: 0.5 ,
31
74
stagger: 0.1 ,
32
75
});
33
76
};
34
77
35
78
const stylistAnimation = (target : string , x : string ) => {
36
79
$gsap .from (target , {
37
- scrollTrigger: {
38
- trigger: target ,
39
- start: ' top bottom' ,
40
- },
80
+ scrollTrigger: scrollTrigger (target , ' top bottom' ),
41
81
opacity: 0 ,
42
82
x: x ,
43
83
duration: 1 ,
@@ -46,12 +86,19 @@ const stylistAnimation = (target: string, x: string) => {
46
86
47
87
// animation
48
88
onMounted (() => {
89
+ // first view
90
+ firstViewAnimation ();
91
+ // title
92
+ titleAnimation (' #blogTitle' );
93
+ // concept
49
94
conceptAnimation (' #concept1img' , ' -50px' , 1 );
50
95
conceptAnimation (' #concept1text' , ' 50px' , 1 );
51
96
conceptAnimation (' #concept2img' , ' 50px' , 1 );
52
97
conceptAnimation (' #concept2text' , ' -50px' , 1 );
53
-
98
+ // gallery
54
99
galleryAnimation (' .gallery-card' , ' -10px' , 1 );
100
+ // menu
101
+ menuAnimation (' .menu-card' );
55
102
56
103
stylistAnimation (' #stylistImg' , ' -50px' );
57
104
stylistAnimation (' #stylistText' , ' 50px' );
@@ -77,10 +124,13 @@ const styles = {
77
124
78
125
<template >
79
126
<div
80
- :class =" `flex justify-center items-center relative w-full h-[750px] ${styles.background}`"
127
+ :class =" `fv-bg flex justify-center items-center relative w-full h-[750px] ${styles.background}`"
81
128
>
82
- <img class =" absolute w-[98%] h-[98%]" src =" /images/mv-border.svg" />
83
- <img class =" title absolute w-[520px]" src =" /images/logo-lg.png" />
129
+ <img
130
+ class =" fv-border absolute w-[98%] h-[98%]"
131
+ src =" /images/mv-border.svg"
132
+ />
133
+ <img class =" fv-logo title absolute w-[520px]" src =" /images/logo-lg.png" />
84
134
</div >
85
135
<!-- catchcopy-->
86
136
<div class =" flex justify-center w-full bg-[#DDD3C3]" >
@@ -97,7 +147,7 @@ const styles = {
97
147
</div >
98
148
<!-- blog-->
99
149
<div id =" blog" class =" py-10" >
100
- <SectionTitle value = " Blog" />
150
+ <SectionTitle :props = " { id: 'blogTitle', value: ' Blog' } " />
101
151
<div class =" w-[250px] py-6 mx-auto" >
102
152
<a :href =" `/post/${blogListData?.contents[0]?.id ?? ''}`" >
103
153
<img
@@ -197,7 +247,7 @@ const styles = {
197
247
</div >
198
248
<!-- gallery-->
199
249
<div id =" gallery" class =" bg-[#F1EAE5] px-[10px] sm:px-[50px] py-[80px]" >
200
- <SectionTitle value = " Gallery" />
250
+ <SectionTitle :props = " { id: 'galleryTitle', value: ' Gallery' } " />
201
251
<div class =" flex justify-center mt-[50px]" >
202
252
<div class =" grid grid-cols-2 lg:grid-cols-4 gap-7" >
203
253
<div
@@ -217,22 +267,25 @@ const styles = {
217
267
</div >
218
268
<!-- menu-->
219
269
<div id =" menu" class =" py-[80px]" >
220
- <SectionTitle value = " Menu" />
270
+ <SectionTitle :props = " { id: 'menuTitle', value: ' Menu' } " />
221
271
<div class =" flex justify-center mt-[50px]" >
222
272
<div class =" inline-block" >
223
273
<div class =" grid grid-cols-1 lg:grid-cols-2 gap-10" >
224
274
<!-- cut menu-->
225
275
<div class =" max-w-[470px]" >
226
276
<div class =" bg-[#DED5D0] px-5 py-2 mb-5" >
227
- <h2 class =" text-main" :style =" { fontFamily: 'Jost, sans-serif' }" >
277
+ <h2
278
+ class =" menu-card text-main"
279
+ :style =" { fontFamily: 'Jost, sans-serif' }"
280
+ >
228
281
Cut Menu(シャンプー・ブロー付き)
229
282
</h2 >
230
283
</div >
231
284
<div
232
285
v-for =" { name: name, price: price } in menuData?.contents.filter(
233
286
(x) => x.attr.includes('Cut Menu')
234
287
)"
235
- class =" flex justify-between text-main px-3 py-3"
288
+ class =" menu-card flex justify-between text-main px-3 py-3"
236
289
>
237
290
<p class =" inline-block text-sm sm:text-base" >
238
291
{{ name }}
@@ -244,15 +297,18 @@ const styles = {
244
297
<!-- other menu-->
245
298
<div class =" max-w-[470px]" >
246
299
<div class =" bg-[#DED5D0] px-5 py-2 mb-5" >
247
- <h2 class =" text-main" :style =" { fontFamily: 'Jost, sans-serif' }" >
300
+ <h2
301
+ class =" menu-card text-main"
302
+ :style =" { fontFamily: 'Jost, sans-serif' }"
303
+ >
248
304
Other Menu
249
305
</h2 >
250
306
</div >
251
307
<div
252
308
v-for =" { name: name, price: price } in menuData?.contents.filter(
253
309
(x) => x.attr.includes('Other Menu')
254
310
)"
255
- class =" flex justify-between text-main px-3 py-3"
311
+ class =" menu-card flex justify-between text-main px-3 py-3"
256
312
>
257
313
<p class =" inline-block text-sm sm:text-base" >
258
314
{{ name }}
@@ -267,7 +323,7 @@ const styles = {
267
323
</div >
268
324
<!-- stylist-->
269
325
<div id =" stylist" class =" bg-[#F1EAE5] py-[80px]" >
270
- <SectionTitle value = " Stylist" />
326
+ <SectionTitle :props = " { id: 'stylistTitle', value: ' Stylist' } " />
271
327
<div class =" relative max-w-[800px] h-[700px] sm:h-[580px] mt-[50px] m-auto" >
272
328
<img
273
329
id =" stylistImg"
@@ -312,7 +368,7 @@ const styles = {
312
368
</div >
313
369
<!-- access-->
314
370
<div class =" py-[80px]" >
315
- <SectionTitle value = " Access" />
371
+ <SectionTitle :props = " { id: 'accessTitle', value: ' Access' } " />
316
372
<div
317
373
class =" block md:flex max-w-[980px] border border-[#503528] p-[20px] mt-[40px] ms-3 me-3 md:ms-auto md:me-auto"
318
374
>
0 commit comments