-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscroll-shape-morph.html
More file actions
178 lines (150 loc) · 6.25 KB
/
Copy pathscroll-shape-morph.html
File metadata and controls
178 lines (150 loc) · 6.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Architecture Studio</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500&family=Bebas+Neue&display=swap" rel="stylesheet">
<style>
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
interact-element { display: block; }
html, body { height: 100%; overflow-x: clip; }
body {
background: #0c0c0c;
font-family: 'Inter', sans-serif;
-webkit-font-smoothing: antialiased;
}
.bg-image {
position: fixed;
inset: 0;
background: url('https://images.unsplash.com/photo-1618221195710-dd6b41faaea6?auto=format&fit=crop&q=80&w=1800') center / cover;
}
.bg-image::after {
content: '';
position: absolute;
inset: 0;
background: rgba(12, 12, 12, 0.55);
}
.scroll-driver { height: 500vh; position: relative; }
.sticky-stage {
position: sticky;
top: 0;
height: 100vh;
overflow: clip;
display: flex;
align-items: center;
justify-content: center;
}
.center-container {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
}
.shape-wrap { position: absolute; inset: -5%; }
.shape-wrap > div { width: 100%; height: 100%; }
.shape-wrap svg { width: 100%; height: 100%; }
.text-overlay { position: relative; pointer-events: none; }
.text-inner {
text-align: center;
pointer-events: auto;
padding: clamp(3rem, 6vw, 6rem) clamp(3rem, 7vw, 8rem);
}
.label {
font-size: clamp(0.55rem, 0.7vw, 0.75rem);
letter-spacing: 0.3em;
text-transform: uppercase;
font-weight: 500;
color: rgba(0, 0, 0, 0.4);
margin-bottom: clamp(0.8rem, 1.5vw, 1.5rem);
}
.title {
font-family: 'Bebas Neue', sans-serif;
font-size: clamp(2rem, 4.2vw, 5rem);
line-height: 1;
font-weight: 400;
margin-bottom: clamp(0.6rem, 1.2vw, 1.2rem);
letter-spacing: 0.06em;
text-transform: uppercase;
color: #0c0c0c;
}
.description {
font-size: clamp(0.7rem, 0.95vw, 0.95rem);
line-height: 1.8;
font-weight: 300;
color: rgba(0, 0, 0, 0.55);
max-width: clamp(200px, 28vw, 400px);
margin: 0 auto;
}
.description a {
color: rgba(0, 0, 0, 0.85);
text-decoration: underline;
text-underline-offset: 3px;
text-decoration-color: rgba(0, 0, 0, 0.3);
}
.description a:hover {
text-decoration-color: rgba(0, 0, 0, 0.85);
}
</style>
</head>
<body>
<div class="bg-image"></div>
<interact-element data-interact-key="scroll-driver" class="scroll-driver">
<div class="sticky-stage">
<div class="center-container">
<interact-element data-interact-key="mask-1" class="shape-wrap">
<div><svg viewBox="0 0 519 479" preserveAspectRatio="none" fill="none"><path d="M0 0H518.5V479H0V0Z" fill="#fff"/></svg></div>
</interact-element>
<interact-element data-interact-key="mask-2" class="shape-wrap">
<div><svg viewBox="0 0 525 495" preserveAspectRatio="none" fill="none"><path d="M0 200C0 89.5431 89.5431 0 200 0H525V295C525 405.457 435.457 495 325 495H0V200Z" fill="#fff"/></svg></div>
</interact-element>
<interact-element data-interact-key="mask-3" class="shape-wrap">
<div><svg viewBox="0 0 501 495" preserveAspectRatio="none" fill="none"><rect width="501" height="495" rx="247.5" fill="#fff"/></svg></div>
</interact-element>
<interact-element data-interact-key="mask-4" class="shape-wrap">
<div><svg viewBox="0 0 501 495" preserveAspectRatio="none" fill="none"><path d="M365 0C376.046 0 385.001 8.95431 385.001 20V110H481C492.046 110 501.001 118.954 501.001 130V475C501.001 486.046 492.046 495 481.001 495H136.001C124.955 495 116.001 486.046 116.001 475V385H20.001C8.95528 385 0 376.046 0 365V20C3.86565e-06 8.95447 8.95453 0.000263872 20 0H365Z" fill="#fff"/></svg></div>
</interact-element>
<interact-element data-interact-key="mask-5" class="shape-wrap">
<div><svg viewBox="0 0 501 495" preserveAspectRatio="none" fill="none"><path d="M249.568 43.6777L286.817 0H481C492.046 2.9185e-06 501 8.95431 501 20V180.287L428.079 247.5L501 314.713V475C501 486.046 492.046 495 481 495H288.681L251.432 451.322L214.183 495H20C8.95432 495 1.89637e-05 486.046 0 475V314.713L72.9199 247.5L0 180.287V20C0 8.95431 8.95431 1.49578e-07 20 0H212.319L249.568 43.6777Z" fill="#fff"/></svg></div>
</interact-element>
<div class="text-overlay">
<div class="text-inner">
<p class="label">Architecture Studio</p>
<h2 class="title">Shaping<br>Space & Light</h2>
<p class="description">We design buildings that move people. Every project begins with listening — to the site, the purpose, and the people who will inhabit it. <a href="#">Start a project</a></p>
</div>
</div>
</div>
</div>
</interact-element>
<script type="module">
import { Interact } from 'https://esm.sh/@wix/interact/web';
const range = {
rangeStart: { name: 'cover', offset: { value: 0, unit: 'percentage' } },
rangeEnd: { name: 'cover', offset: { value: 100, unit: 'percentage' } },
};
function slice(key, start, end) {
const kf = [];
if (start > 0) kf.push({ opacity: 0, offset: 0 }, { opacity: 0, offset: start - 0.001 });
kf.push({ opacity: 1, offset: start }, { opacity: 1, offset: end });
if (end < 1) kf.push({ opacity: 0, offset: end + 0.001 }, { opacity: 0, offset: 1 });
return { key, keyframeEffect: { name: key, keyframes: kf }, fill: 'both', ...range };
}
Interact.create({
interactions: [{
key: 'scroll-driver',
trigger: 'viewProgress',
effects: [
slice('mask-1', 0, 0.2),
slice('mask-2', 0.2, 0.4),
slice('mask-3', 0.4, 0.6),
slice('mask-4', 0.6, 0.8),
slice('mask-5', 0.8, 1),
]
}]
});
</script>
</body>
</html>