@miris-inc/components 0.0.3 → 0.0.6-008a30d6
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/package.json +9 -4
- package/bus.ts +0 -33
- package/camera.ts +0 -67
- package/elements.ts +0 -4
- package/group.ts +0 -12
- package/index.html +0 -11
- package/index.ts +0 -10
- package/primitive.ts +0 -202
- package/scene.ts +0 -127
- package/stream.ts +0 -217
- package/test/carousel-multiple.html +0 -386
- package/test/carousel-single.html +0 -494
- package/test/controls.html +0 -71
- package/test/hero-test.html +0 -99
- package/test/index.html +0 -29
- package/test/sdk.html +0 -10
- package/vite.config.ts +0 -32
package/stream.ts
DELETED
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
PerspectiveCamera as ThreeCamera,
|
|
3
|
-
WebGLRenderer as ThreeRenderer,
|
|
4
|
-
} from "three";
|
|
5
|
-
import {
|
|
6
|
-
MirisScene as ThreeScene,
|
|
7
|
-
MirisStream as ThreeStream,
|
|
8
|
-
MirisControls as ThreeControls,
|
|
9
|
-
} from "@miris-inc/three";
|
|
10
|
-
import Bus from "./bus";
|
|
11
|
-
import Primitive from "./primitive";
|
|
12
|
-
import type Scene from "./scene";
|
|
13
|
-
|
|
14
|
-
export default class MirisStream extends Primitive {
|
|
15
|
-
static observedAttributes = ["uuid", "key", "disabled", "controls"];
|
|
16
|
-
|
|
17
|
-
#disabled = false;
|
|
18
|
-
// prettier-ignore
|
|
19
|
-
get disabled() { return this.#disabled }
|
|
20
|
-
set disabled(disabled) {
|
|
21
|
-
if (disabled === this.#disabled) return;
|
|
22
|
-
|
|
23
|
-
this.#disabled = disabled;
|
|
24
|
-
|
|
25
|
-
if (disabled) {
|
|
26
|
-
this.setAttribute("disabled", "");
|
|
27
|
-
this._disable();
|
|
28
|
-
} else {
|
|
29
|
-
this.removeAttribute("disabled");
|
|
30
|
-
this._enable();
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
#uuid: string | null = null;
|
|
35
|
-
// prettier-ignore
|
|
36
|
-
get uuid() { return this.#uuid }
|
|
37
|
-
set uuid(uuid) {
|
|
38
|
-
if (uuid === this.#uuid) return;
|
|
39
|
-
|
|
40
|
-
if (this._threeObject) this._threeObject.clearBoxes();
|
|
41
|
-
const oldUuid = this.#uuid;
|
|
42
|
-
|
|
43
|
-
this.#uuid = uuid;
|
|
44
|
-
|
|
45
|
-
if (uuid) {
|
|
46
|
-
this.setAttribute("uuid", uuid);
|
|
47
|
-
if (oldUuid) this._disable();
|
|
48
|
-
this._enable();
|
|
49
|
-
} else {
|
|
50
|
-
this.removeAttribute("uuid");
|
|
51
|
-
this._disable();
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
#controls = false;
|
|
56
|
-
// prettier-ignore
|
|
57
|
-
get controls() { return this.#controls }
|
|
58
|
-
set controls(controls) {
|
|
59
|
-
if (controls === this.#controls) return;
|
|
60
|
-
|
|
61
|
-
this.#controls = controls;
|
|
62
|
-
|
|
63
|
-
if (controls) this.#control();
|
|
64
|
-
else this.#uncontrol();
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
#threeControls: ThreeControls | null = null;
|
|
68
|
-
|
|
69
|
-
#key: string | null = null;
|
|
70
|
-
// prettier-ignore
|
|
71
|
-
get key() { return this.#key }
|
|
72
|
-
set key(key) {
|
|
73
|
-
if (key === this.#key) return;
|
|
74
|
-
|
|
75
|
-
this.#key = key;
|
|
76
|
-
|
|
77
|
-
if (key) this.setAttribute("key", key);
|
|
78
|
-
else this.removeAttribute("key");
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
protected override _threeObject: ThreeStream | null = null;
|
|
82
|
-
|
|
83
|
-
#renderer: ThreeRenderer | null = null;
|
|
84
|
-
#observer: ResizeObserver | null = null;
|
|
85
|
-
#shadow: ShadowRoot | null = null;
|
|
86
|
-
#scene: ThreeScene | null = null;
|
|
87
|
-
|
|
88
|
-
constructor() {
|
|
89
|
-
super();
|
|
90
|
-
|
|
91
|
-
this.#key = this.getAttribute("key");
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
#enableScene() {
|
|
95
|
-
if (this.#renderer) return;
|
|
96
|
-
|
|
97
|
-
const renderer = new ThreeRenderer({ alpha: true });
|
|
98
|
-
const scene = new ThreeScene(this.key);
|
|
99
|
-
const camera = new ThreeCamera();
|
|
100
|
-
const controls = new ThreeControls(null, camera, renderer.domElement);
|
|
101
|
-
const observer = new ResizeObserver((entries: ResizeObserverEntry[]) => {
|
|
102
|
-
const entry = entries[entries.length - 1]!;
|
|
103
|
-
const width = entry.contentBoxSize[0]!.inlineSize;
|
|
104
|
-
const height = entry.contentBoxSize[0]!.blockSize;
|
|
105
|
-
|
|
106
|
-
renderer.setPixelRatio(devicePixelRatio);
|
|
107
|
-
renderer.setSize(width, height, false);
|
|
108
|
-
|
|
109
|
-
camera.aspect = width / height;
|
|
110
|
-
camera.updateProjectionMatrix();
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
if (!this.#shadow) {
|
|
114
|
-
this.#shadow = this.attachShadow({ mode: "closed" });
|
|
115
|
-
const sheet = new CSSStyleSheet();
|
|
116
|
-
sheet.insertRule(":host { display: block }");
|
|
117
|
-
sheet.insertRule("canvas { display: block; width: 100%; height: 100% }");
|
|
118
|
-
this.#shadow.adoptedStyleSheets.push(sheet);
|
|
119
|
-
this.#shadow.append(renderer.domElement);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (this._threeObject) scene.add(this._threeObject);
|
|
123
|
-
|
|
124
|
-
observer.observe(this);
|
|
125
|
-
renderer.setAnimationLoop(() => renderer.render(scene, camera));
|
|
126
|
-
this.#renderer = renderer;
|
|
127
|
-
this.#scene = scene;
|
|
128
|
-
this.#threeControls = controls;
|
|
129
|
-
this.#observer = observer;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
override _enable() {
|
|
133
|
-
if (this.disabled) return;
|
|
134
|
-
|
|
135
|
-
if (!this._threeObject && this.uuid) {
|
|
136
|
-
this._threeObject = new ThreeStream(this.uuid, this.key);
|
|
137
|
-
this._threeObject.name = this.uuid;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
super._enable();
|
|
141
|
-
|
|
142
|
-
if (this.#scene && this._threeObject) this.#scene.add(this._threeObject);
|
|
143
|
-
if (!this._parent && this.uuid) this.#enableScene();
|
|
144
|
-
|
|
145
|
-
if (this.controls) this.#control();
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
#disableScene() {
|
|
149
|
-
if (this.#renderer) {
|
|
150
|
-
this.#renderer?.dispose();
|
|
151
|
-
this.#renderer = null;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (this.#observer) {
|
|
155
|
-
this.#observer?.disconnect();
|
|
156
|
-
this.#observer = null;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
override _disable() {
|
|
161
|
-
// // Cannot implement until Aqua allows multiple scenes per page
|
|
162
|
-
// if (!this._parent) this.#disableScene();
|
|
163
|
-
|
|
164
|
-
if (this._threeObject) this.#scene?.remove(this._threeObject);
|
|
165
|
-
|
|
166
|
-
if (this.controls) this.#uncontrol();
|
|
167
|
-
|
|
168
|
-
super._disable();
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
#control() {
|
|
172
|
-
if (!this.controls || !this._threeObject) return;
|
|
173
|
-
|
|
174
|
-
const scene = this.closest("miris-scene") as Scene | null;
|
|
175
|
-
|
|
176
|
-
if (scene) Bus.publish(scene, "control", this._threeObject);
|
|
177
|
-
else this.#threeControls?.objects.add(this._threeObject);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
#uncontrol() {
|
|
181
|
-
if (this.controls || !this._threeObject) return;
|
|
182
|
-
|
|
183
|
-
const scene = this.closest("miris-scene") as Scene | null;
|
|
184
|
-
|
|
185
|
-
if (scene) Bus.publish(scene, "uncontrol", this._threeObject);
|
|
186
|
-
else this.#threeControls?.objects.delete(this._threeObject);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
attributeChangedCallback(
|
|
190
|
-
name: string,
|
|
191
|
-
_oldValue: string | null,
|
|
192
|
-
newValue: string | null
|
|
193
|
-
) {
|
|
194
|
-
switch (name) {
|
|
195
|
-
case "controls":
|
|
196
|
-
this.controls = newValue !== null;
|
|
197
|
-
break;
|
|
198
|
-
case "disabled":
|
|
199
|
-
this.disabled = newValue !== null;
|
|
200
|
-
break;
|
|
201
|
-
case "key":
|
|
202
|
-
this.#key = newValue;
|
|
203
|
-
break;
|
|
204
|
-
case "uuid":
|
|
205
|
-
this.uuid = newValue;
|
|
206
|
-
break;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
update() {
|
|
211
|
-
if (this._threeObject) this._threeObject?.update();
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
toggleRenderBounds(shouldRender: boolean) {
|
|
215
|
-
if (this._threeObject) this._threeObject?.toggleRenderBounds(shouldRender);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
@@ -1,386 +0,0 @@
|
|
|
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>
|