@miris-inc/components 0.0.1

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,386 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>hero</title>
7
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
8
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
9
+ <link
10
+ href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,200..800;1,200..800&display=swap"
11
+ rel="stylesheet"
12
+ />
13
+ <style>
14
+ .hero-pagination-button {
15
+ text-transform: uppercase;
16
+ color: #9e9e9e;
17
+ cursor: pointer;
18
+ background-color: transparent;
19
+ border-style: none;
20
+ padding: 12px 16px;
21
+ width: var(--button-width);
22
+
23
+ &:hover {
24
+ color: #fff;
25
+ }
26
+ }
27
+
28
+ .hero-nav {
29
+ background-color: transparent;
30
+ position: absolute;
31
+ top: 0;
32
+ height: 100%;
33
+ display: flex;
34
+ align-items: center;
35
+ fill: #fff;
36
+ padding: 16px;
37
+ border-style: none;
38
+ cursor: pointer;
39
+
40
+ &:hover {
41
+ fill: #d7d8d2;
42
+ }
43
+
44
+ & svg {
45
+ width: 40px;
46
+ height: 40px;
47
+ }
48
+ }
49
+
50
+ .hero-nav-prev {
51
+ left: 0;
52
+ }
53
+
54
+ .hero-nav-next {
55
+ right: 0;
56
+ }
57
+
58
+ .hero-display {
59
+ --hero-display-margin: 20%;
60
+
61
+ position: relative;
62
+ place-items: center;
63
+ height: 100%;
64
+ }
65
+
66
+ .hero-pagination-item {
67
+ scroll-snap-align: center;
68
+ display: block;
69
+ }
70
+
71
+ .hero-pagination-list {
72
+ --button-width: 192px;
73
+
74
+ position: absolute;
75
+ inset: 0;
76
+ bottom: auto;
77
+ box-sizing: border-box;
78
+ display: flex;
79
+ justify-content: flex-start;
80
+ align-items: flex-end;
81
+ grid-column-start: 7;
82
+ grid-column-end: 12;
83
+ list-style-type: none;
84
+ padding-inline-start: 0;
85
+ margin-block: 0;
86
+ width: 100%;
87
+ scroll-snap-type: inline mandatory;
88
+ overflow-x: auto;
89
+ padding-inline: calc(50% - (var(--button-width) / 2));
90
+ scrollbar-width: none;
91
+ }
92
+
93
+ .hero-mask {
94
+ mask-image: linear-gradient(
95
+ to right,
96
+ transparent,
97
+ black var(--hero-display-margin),
98
+ black calc(100% - var(--hero-display-margin)),
99
+ transparent
100
+ );
101
+ }
102
+
103
+ .hero-scene {
104
+ height: 100%;
105
+ }
106
+
107
+ body {
108
+ margin: 0;
109
+ background-color: black;
110
+ font-family:
111
+ Plus Jakarta Sans,
112
+ sans-serif;
113
+ }
114
+
115
+ .hero {
116
+ position: relative;
117
+ height: 100%;
118
+ }
119
+
120
+ .hero-container {
121
+ position: relative;
122
+ display: grid;
123
+ max-width: 1536px;
124
+ margin-inline: auto;
125
+ padding-inline: 64px;
126
+ padding-block: 4rem;
127
+ align-items: center;
128
+
129
+ @media (min-width: 1280px) {
130
+ grid-template-columns: repeat(12, minmax(0, 1fr));
131
+ }
132
+ }
133
+
134
+ .hero-wrapper {
135
+ height: 100%;
136
+ @media (min-width: 1280px) {
137
+ grid-column-start: 6;
138
+ grid-column-end: 13;
139
+ }
140
+ }
141
+
142
+ .hero-description {
143
+ width: 100%;
144
+ color: #9e9e9e;
145
+ margin-block: 0;
146
+ }
147
+
148
+ .hero-heading {
149
+ color: #fff;
150
+ font-size: 72px;
151
+ line-height: 94%;
152
+ margin-block: 0;
153
+ }
154
+
155
+ .hero-links-anchor {
156
+ display: block;
157
+ text-transform: uppercase;
158
+ letter-spacing: 2px;
159
+ border-radius: 25px;
160
+ text-align: center;
161
+ padding: 16px 24px;
162
+ text-decoration: none;
163
+ font-size: 10px;
164
+ border-width: 1px;
165
+ border-style: solid;
166
+ }
167
+
168
+ .hero-links-anchor-primary {
169
+ color: #151515;
170
+ background-color: #fff;
171
+ border-color: transparent;
172
+ font-weight: 800;
173
+
174
+ &:hover {
175
+ background-color: #d7d8d2;
176
+ }
177
+ }
178
+
179
+ .hero-links-anchor-secondary {
180
+ border-color: #c2c3be;
181
+ color: #fff;
182
+ font-weight: 500;
183
+
184
+ &:hover {
185
+ background-color: #151515;
186
+ }
187
+ }
188
+
189
+ .hero-links-list {
190
+ display: flex;
191
+ column-gap: 1rem;
192
+ list-style-type: none;
193
+ padding-inline-start: 0;
194
+ margin-block: 0;
195
+ }
196
+
197
+ .hero-text {
198
+ display: grid;
199
+ row-gap: 24px;
200
+
201
+ @media (min-width: 1280px) {
202
+ grid-column-start: 1;
203
+ grid-column-end: 6;
204
+ grid-row-start: 1;
205
+ grid-row-end: 3;
206
+ }
207
+ }
208
+
209
+ .hero-video {
210
+ position: absolute;
211
+ width: 100%;
212
+ height: 100%;
213
+ object-fit: cover;
214
+ }
215
+
216
+ .container {
217
+ height: 800px;
218
+ max-width: 1536px;
219
+ padding-block: 64px;
220
+ margin-inline: auto;
221
+ }
222
+ </style>
223
+ <script type="module" src="/index.ts"></script>
224
+ <script type="module" lang="ts">
225
+ const slots = 7;
226
+
227
+ await customElements.whenDefined("miris-stream");
228
+ for (const hero of document.getElementsByClassName("hero")) {
229
+ const scene = hero.querySelector(".hero-scene");
230
+ const group = hero.querySelector(".hero-group");
231
+ const list = hero.querySelector(".hero-pagination-list");
232
+ const assets = await scene.fetchAssets(["miris.com"]);
233
+ const count = assets.length;
234
+ const streams = [];
235
+ const paginationButtons = [];
236
+ const radius = 1 / (2 * Math.sin(Math.PI / slots));
237
+
238
+ assets.forEach(({ uuid, name, pY = 0, zoom = 1 }, index) => {
239
+ // calculate positions
240
+ const angle = (index % slots) * ((2 * Math.PI) / slots);
241
+ const pX = radius * Math.sin(angle);
242
+ const pZ = radius * Math.cos(angle);
243
+
244
+ const wrapper = document.createElement("miris-group");
245
+ wrapper.position.set(pX, pY, pZ);
246
+ group.append(wrapper);
247
+
248
+ // create stream
249
+ const stream = document.createElement("miris-stream");
250
+ stream.disabled = true;
251
+ stream.controls = true;
252
+ stream.uuid = uuid;
253
+ stream.zoom = zoom * 0.25;
254
+ streams.push(stream);
255
+ wrapper.append(stream);
256
+
257
+ // create list item
258
+ const item = document.createElement("li");
259
+ item.className = "hero-pagination-item";
260
+ list.append(item);
261
+
262
+ // create button
263
+ const button = document.createElement("button");
264
+ button.className = "hero-pagination-button";
265
+ button.innerText = name.replaceAll(/_+/g, " ");
266
+ button.addEventListener("click", () =>
267
+ button.scrollIntoView({ inline: "center", behavior: "smooth" })
268
+ );
269
+ paginationButtons.push(button);
270
+ item.append(button);
271
+ });
272
+
273
+ let waiting = false;
274
+ const scroll = () => {
275
+ // take measurements
276
+ const { clientWidth: cwL, scrollLeft: slL, scrollWidth: swL } = list;
277
+ const cwB = swL / count;
278
+
279
+ // calculate rotation
280
+ const rMaxProgress = 1 - 1 / count;
281
+ const rProgress = rMaxProgress * (slL / (swL - cwL));
282
+ const rRadians = rProgress * 2 * Math.PI;
283
+ const rY = rRadians * (count / slots);
284
+
285
+ // determine active indices
286
+ const iProgress = (slL + cwB / 2) / (swL - cwL + cwB);
287
+ const iCurr = Math.floor(iProgress / (1 / count));
288
+ const iPrev = iCurr - 1;
289
+ const iNext = iCurr + 1;
290
+
291
+ // update scene
292
+ streams.forEach((stream, index) => {
293
+ stream.disabled = ![iPrev, iCurr, iNext].includes(index);
294
+ stream.parentElement.rotation.y = rY;
295
+ });
296
+ group.rotation.y = -rY;
297
+
298
+ // update buttons
299
+ paginationButtons.forEach((button, index) => {
300
+ const className = "hero-pagination-button-active";
301
+ const { classList } = button;
302
+ if (index === iCurr) classList.add(className);
303
+ else classList.remove(className);
304
+ });
305
+
306
+ // release hold
307
+ waiting = false;
308
+ };
309
+
310
+ list.addEventListener("scroll", () => {
311
+ if (!waiting) waiting = Boolean(requestAnimationFrame(scroll));
312
+ });
313
+ scroll();
314
+
315
+ hero.querySelector(".hero-nav-prev")?.addEventListener("click", () => {
316
+ const padding = parseFloat(getComputedStyle(list).paddingLeft);
317
+ const prevButton = hero
318
+ .querySelector(".hero-pagination-button-active")
319
+ ?.parentElement?.previousElementSibling?.querySelector(
320
+ ".hero-pagination-button"
321
+ );
322
+
323
+ if (prevButton) {
324
+ list.scroll({
325
+ left: prevButton.offsetLeft - padding,
326
+ behavior: "smooth",
327
+ });
328
+ }
329
+ });
330
+
331
+ hero.querySelector(".hero-nav-next")?.addEventListener("click", () => {
332
+ const padding = parseFloat(getComputedStyle(list).paddingLeft);
333
+ const nextButton = hero
334
+ .querySelector(".hero-pagination-button-active")
335
+ ?.parentElement?.nextElementSibling?.querySelector(
336
+ ".hero-pagination-button"
337
+ );
338
+
339
+ if (nextButton) {
340
+ list.scroll({
341
+ left: nextButton.offsetLeft - padding,
342
+ behavior: "smooth",
343
+ });
344
+ }
345
+ });
346
+ }
347
+ </script>
348
+ </head>
349
+ <body>
350
+ <div class="container">
351
+ <div class="hero">
352
+ <div class="hero-wrapper">
353
+ <div class="hero-display">
354
+ <div class="hero-mask">
355
+ <miris-scene
356
+ key="l2LWVHS39ZhmXDOtefPoOmvPdAp55OxTPJfwVmNo7rY"
357
+ class="hero-scene"
358
+ >
359
+ <miris-group position="0 0 -3" class="hero-group"></miris-group>
360
+ </miris-scene>
361
+ <ul class="hero-pagination-list"></ul>
362
+ </div>
363
+ <button class="hero-nav hero-nav-prev">
364
+ <svg viewBox="0 0 24 24">
365
+ <path
366
+ fill-rule="evenodd"
367
+ d="M7.72 12.53a.75.75 0 0 1 0-1.06l7.5-7.5a.75.75 0 1 1 1.06 1.06L9.31 12l6.97 6.97a.75.75 0 1 1-1.06 1.06l-7.5-7.5Z"
368
+ clip-rule="evenodd"
369
+ />
370
+ </svg>
371
+ </button>
372
+ <button class="hero-nav hero-nav-next">
373
+ <svg viewBox="0 0 24 24">
374
+ <path
375
+ fill-rule="evenodd"
376
+ d="M16.28 11.47a.75.75 0 0 1 0 1.06l-7.5 7.5a.75.75 0 0 1-1.06-1.06L14.69 12 7.72 5.03a.75.75 0 0 1 1.06-1.06l7.5 7.5Z"
377
+ clip-rule="evenodd"
378
+ />
379
+ </svg>
380
+ </button>
381
+ </div>
382
+ </div>
383
+ </div>
384
+ </div>
385
+ </body>
386
+ </html>