├── .DS_Store
├── .gitignore
├── LICENSE
├── README.md
├── css
└── base.css
├── dist
├── code block```
three.js min.js 3.0.js
├── index.css
├── index.html
└── index.js
├── favicon.ico
├── index.html
├── index2.html
├── index3.html
├── package.json
├── src
├── .DS_Store
├── RoundedBox.js
├── demo.js
├── index.html
├── rendering.js
├── style.css
├── utils.js
└── vite.config.js
├── vite.config.js
└── yarn.lock
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anemolo/ThreeJs-Instancing-mouse-effect/3fd620d99659f6598e51a4da8a20e7bdbd53a54c/.DS_Store
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .cache
3 | .parcel-cache
4 | package-lock.json
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2009 - 2022 [Codrops](https://tympanus.net/codrops)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Mouse Effect with Three.js Instancing
2 |
3 | Demo for tutorial on creating interactive mouse effects with Three.js instancing.
4 |
5 | 
6 |
7 | [Article on Codrops](https://tympanus.net/codrops/?p=74529)
8 |
9 | [Demo](http://tympanus.net/Tutorials/MouseInstancing/)
10 |
11 | ## Installation
12 |
13 |
14 | 1. Development mode. For developing the project internals
15 |
16 | ```
17 | yarn install
18 | yarn dev
19 | ```
20 |
21 | 2. Run mode -> Local server only to run the code directly without modifications.
22 | 1. Run this demo on a [local server](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/Tools_and_setup/set_up_a_local_testing_server).
23 | 2. Open index.html
24 |
25 | ### Files && comments
26 |
27 | | file | Description |
28 | | --- | --- |
29 | | demo.js | The meat of the demo |
30 | | rendering.js | All the threeJS rendering |
31 |
32 | ## Misc
33 |
34 | Follow *Daniel Velasquez*: [Twitter](https://twitter.com/Anemolito), [ThreeJS/Webgl Newsletter](https://offscreencanvas.com/), [GitHub](https://github.com/Anemolo)
35 |
36 | Follow Codrops: [Twitter](http://www.twitter.com/codrops), [Facebook](http://www.facebook.com/codrops), [GitHub](https://github.com/codrops), [Instagram](https://www.instagram.com/codropsss/)
37 |
38 | ## License
39 | [MIT](LICENSE)
40 |
41 | Made with :blue_heart: by [Codrops](http://www.codrops.com)
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/css/base.css:
--------------------------------------------------------------------------------
1 | *,
2 | *::after,
3 | *::before {
4 | box-sizing: border-box;
5 | }
6 |
7 | :root {
8 | font-size: 14px;
9 | --color-text: rgb(140, 146, 164);
10 | --color-bg: #000;
11 | --color-link: rgb(140, 146, 164);
12 | --color-link-hover: #fff;
13 | --page-padding: 1rem;
14 | }
15 |
16 | #canvas {
17 | width: 100%;
18 | height: 100%;
19 | }
20 |
21 | #canvas-wrapper {
22 | position: fixed;
23 | top: 0;
24 | left: 0;
25 | width: 100%;
26 | height: 100%;
27 | }
28 |
29 | html, body {
30 | width: 100vw;
31 | height: 100%;
32 | overflow: hidden;
33 | }
34 |
35 | body {
36 | margin: 0;
37 | color: var(--color-text);
38 | background-color: var(--color-bg);
39 | font-family: ui-monospace,SFMono-Regular,Menlo,Roboto Mono,monospace;
40 | -webkit-font-smoothing: antialiased;
41 | -moz-osx-font-smoothing: grayscale;
42 | }
43 |
44 | .demo-2 {
45 | --color-text: #000;
46 | --color-link: #000;
47 | --color-link-hover: #000;
48 | }
49 |
50 | .demo-3 {
51 | --color-text: #e5e2ec;
52 | --color-link: #cb0f40;
53 | }
54 |
55 | /* Page Loader */
56 | .js .loading::before,
57 | .js .loading::after {
58 | content: '';
59 | position: fixed;
60 | z-index: 1000;
61 | }
62 |
63 | .js .loading::before {
64 | top: 0;
65 | left: 0;
66 | width: 100%;
67 | height: 100%;
68 | background: var(--color-bg);
69 | }
70 |
71 | .js .loading::after {
72 | top: 50%;
73 | left: 50%;
74 | width: 60px;
75 | height: 60px;
76 | margin: -30px 0 0 -30px;
77 | opacity: 0.4;
78 | background: var(--color-link);
79 | animation: loaderAnim 0.7s linear infinite alternate forwards;
80 |
81 | }
82 |
83 | @keyframes loaderAnim {
84 | to {
85 | opacity: 1;
86 | transform: scale3d(0.7,0.7,1);
87 | }
88 | }
89 |
90 | a {
91 | text-decoration: underline;
92 | color: var(--color-link);
93 | outline: none;
94 | cursor: pointer;
95 | }
96 |
97 | a:hover {
98 | text-decoration: none;
99 | color: var(--color-link-hover);
100 | outline: none;
101 | }
102 |
103 | /* Better focus styles from https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible */
104 | a:focus {
105 | /* Provide a fallback style for browsers
106 | that don't support :focus-visible */
107 | outline: none;
108 | }
109 |
110 | a:focus-visible {
111 | /* Draw a very noticeable focus style for
112 | keyboard-focus on browsers that do support
113 | :focus-visible */
114 | outline: 2px solid red;
115 | }
116 |
117 | .unbutton {
118 | background: none;
119 | border: 0;
120 | padding: 0;
121 | margin: 0;
122 | font: inherit;
123 | cursor: pointer;
124 | }
125 |
126 | .unbutton:focus {
127 | outline: none;
128 | }
129 |
130 | .frame {
131 | padding: var(--page-padding);
132 | position: fixed;
133 | top: 0;
134 | left: 0;
135 | display: grid;
136 | z-index: 1000;
137 | width: 100%;
138 | height: 100%;
139 | grid-row-gap: 1rem;
140 | grid-column-gap: 2rem;
141 | pointer-events: none;
142 | justify-items: start;
143 | grid-template-columns: auto auto;
144 | grid-template-areas: 'title' 'prev' 'back' 'sub' 'sponsor' 'demos';
145 | }
146 |
147 | .frame #cdawrap {
148 | justify-self: start;
149 | }
150 |
151 | .frame a {
152 | pointer-events: auto;
153 | }
154 |
155 | .frame__title {
156 | grid-area: title;
157 | font-size: inherit;
158 | margin: 0;
159 | }
160 |
161 | .frame__back {
162 | grid-area: back;
163 | justify-self: start;
164 | }
165 |
166 | .frame__prev {
167 | grid-area: prev;
168 | justify-self: start;
169 | }
170 |
171 | .frame__sub {
172 | grid-area: sub;
173 | }
174 |
175 | .frame__demos {
176 | grid-area: demos;
177 | display: flex;
178 | gap: 1rem;
179 | }
180 |
181 | @media screen and (min-width: 53em) {
182 | body {
183 | --page-padding: 2rem 3rem;
184 | }
185 | .frame {
186 | grid-template-columns: auto auto auto 1fr;
187 | grid-template-rows: auto auto;
188 | align-content: space-between;
189 | grid-template-areas: 'title prev back sponsor' 'demos demos demos sub';
190 | }
191 | .frame #cdawrap, .frame__sub {
192 | justify-self: end;
193 | }
194 | }
195 |
196 |
--------------------------------------------------------------------------------
/dist/index.css:
--------------------------------------------------------------------------------
1 | #canvas{width:100%;height:100%}#canvas-wrapper{position:fixed;top:0;left:0;width:100%;height:100%}:root{font-family:sofia-pro,-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Open Sans,Arial,sans-serif}body{margin:0;width:100%;height:100vh;overflow:hidden;color:var(--text)}body,html{font-size:16px;line-height:1.5;letter-spacing:.005em}.ui{position:fixed;bottom:50px;left:0;right:0;text-align:center}.ui-logo{font-size:1rem;margin:0;margin-bottom:1rem!important;user-select:none;text-transform:uppercase}.ui-title{font-family:thunder2,Thunder2,thunder,sofia-pro,-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Open Sans,Arial,sans-serif;font-size:4rem;font-weight:800;line-height:.8;letter-spacing:.05em;width:100%!important;max-width:80%!important;user-select:none;text-align:center;margin:0 auto!important;text-transform:uppercase}
2 |
--------------------------------------------------------------------------------
/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Offscreen Canvas DEMO
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anemolo/ThreeJs-Instancing-mouse-effect/3fd620d99659f6598e51a4da8a20e7bdbd53a54c/favicon.ico
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Mouse Effect with Instancing in Three.js | Demo 1 | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
27 |
30 |
31 |
32 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/index2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Mouse Effect with Instancing in Three.js | Demo 2 | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
28 |
31 |
32 |
33 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/index3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Mouse Effect with Instancing in Three.js | Demo 3 | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
28 |
31 |
32 |
33 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "offscreen-three-template",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite ./src ",
8 | "build": "vite build ./src --target es2020 --outDir ../dist",
9 | "preview": "vite preview"
10 | },
11 | "devDependencies": {
12 | "vite": "^4.4.5"
13 | },
14 | "dependencies": {
15 | "glsl-easings": "^1.0.0",
16 | "gsap": "^3.12.2",
17 | "n8ao": "^1.7.0",
18 | "postprocessing": "^6.33.3",
19 | "stats-js": "^1.0.1",
20 | "three": "^0.155.0",
21 | "vite-plugin-glslify": "^2.0.2"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anemolo/ThreeJs-Instancing-mouse-effect/3fd620d99659f6598e51a4da8a20e7bdbd53a54c/src/.DS_Store
--------------------------------------------------------------------------------
/src/RoundedBox.js:
--------------------------------------------------------------------------------
1 | import * as THREE from "three";
2 |
3 | /**
4 | * @author pailhead / http://dusanbosnjak.com
5 | * @author benolayinka / github.com/benolayinka
6 | */
7 |
8 | class RoundedBoxGeometry extends THREE.BufferGeometry{
9 | constructor(
10 | width,
11 | height,
12 | depth,
13 | radius,
14 | radiusSegments
15 | ) {
16 |
17 | super()
18 |
19 | this.type = 'RoundedBoxGeometry';
20 |
21 |
22 | //validate params ===================================
23 |
24 | radiusSegments = !isNaN(radiusSegments) ? Math.max(1, Math.floor(radiusSegments)) : 1;
25 |
26 | width = !isNaN(width) ? width : 1;
27 | height = !isNaN(height) ? height : 1;
28 | depth = !isNaN(depth) ? depth : 1;
29 |
30 | radius = !isNaN(radius) ? radius : .15;
31 |
32 | radius = Math.min(radius, Math.min(width, Math.min(height, Math.min(depth))) / 2);
33 |
34 | var edgeHalfWidth = width / 2 - radius;
35 | var edgeHalfHeight = height / 2 - radius;
36 | var edgeHalfDepth = depth / 2 - radius;
37 |
38 |
39 | //not sure why this is needed, for querying? ========
40 |
41 | this.parameters = {
42 | width: width,
43 | height: height,
44 | depth: depth,
45 | radius: radius,
46 | radiusSegments: radiusSegments
47 | };
48 |
49 |
50 | //calculate vertices count ==========================
51 |
52 | var rs1 = radiusSegments + 1; //radius segments + 1
53 |
54 | var totalVertexCount = (rs1 * radiusSegments + 1) << 3;
55 |
56 |
57 | //make buffers ======================================
58 |
59 | var positions = new THREE.BufferAttribute(new Float32Array(totalVertexCount * 3), 3);
60 |
61 | var normals = new THREE.BufferAttribute(new Float32Array(totalVertexCount * 3), 3);
62 |
63 |
64 | //some vars =========================================
65 |
66 | var
67 | cornerVerts = [],
68 | cornerNormals = [],
69 | normal = new THREE.Vector3(),
70 | vertex = new THREE.Vector3(),
71 | vertexPool = [],
72 | normalPool = [],
73 | indices = []
74 | ;
75 |
76 | var
77 | lastVertex = rs1 * radiusSegments,
78 | cornerVertNumber = rs1 * radiusSegments + 1
79 | ;
80 |
81 | doVertices();
82 | doFaces();
83 | doCorners();
84 | doHeightEdges();
85 | doWidthEdges();
86 | doDepthEdges()
87 |
88 | // calculate vert positions =========================
89 |
90 | function doVertices() {
91 |
92 | //corner offsets
93 | var cornerLayout = [
94 | new THREE.Vector3(1, 1, 1),
95 | new THREE.Vector3(1, 1, -1),
96 | new THREE.Vector3(-1, 1, -1),
97 | new THREE.Vector3(-1, 1, 1),
98 | new THREE.Vector3(1, -1, 1),
99 | new THREE.Vector3(1, -1, -1),
100 | new THREE.Vector3(-1, -1, -1),
101 | new THREE.Vector3(-1, -1, 1)
102 | ];
103 |
104 | //corner holder
105 | for (var j = 0; j < 8; j++) {
106 |
107 | cornerVerts.push([]);
108 | cornerNormals.push([]);
109 |
110 | }
111 |
112 | //construct 1/8 sphere ==============================
113 |
114 | var PIhalf = Math.PI / 2;
115 |
116 | var cornerOffset = new THREE.Vector3(edgeHalfWidth, edgeHalfHeight, edgeHalfDepth);
117 |
118 | for (var y = 0; y <= radiusSegments; y++) {
119 |
120 | var v = y / radiusSegments;
121 |
122 | var va = v * PIhalf; //arrange in 90 deg
123 |
124 | var cosVa = Math.cos(va); //scale of vertical angle
125 |
126 | var sinVa = Math.sin(va);
127 |
128 | if (y == radiusSegments) {
129 |
130 | vertex.set(0, 1, 0);
131 |
132 | var vert = vertex.clone().multiplyScalar(radius).add(cornerOffset);
133 |
134 | cornerVerts[0].push(vert);
135 |
136 | vertexPool.push(vert);
137 |
138 | var norm = vertex.clone();
139 |
140 | cornerNormals[0].push(norm);
141 |
142 | normalPool.push(norm);
143 |
144 | continue; //skip row loop
145 |
146 | }
147 |
148 | for (var x = 0; x <= radiusSegments; x++) {
149 |
150 | var u = x / radiusSegments;
151 |
152 | var ha = u * PIhalf;
153 |
154 | //make 1/8 sphere points
155 | vertex.x = cosVa * Math.cos(ha);
156 | vertex.y = sinVa;
157 | vertex.z = cosVa * Math.sin(ha);
158 |
159 | //copy sphere point, scale by radius, offset by half whd
160 | var vert = vertex.clone().multiplyScalar(radius).add(cornerOffset);
161 |
162 | cornerVerts[0].push(vert);
163 |
164 | vertexPool.push(vert);
165 |
166 | //sphere already normalized, just clone
167 |
168 | var norm = vertex.clone().normalize();
169 | cornerNormals[0].push(norm);
170 | normalPool.push(norm);
171 |
172 | }
173 |
174 | }
175 |
176 | //distribute corner verts ===========================
177 |
178 | for (var i = 1; i < 8; i++) {
179 |
180 | for (var j = 0; j < cornerVerts[0].length; j++) {
181 |
182 | var vert = cornerVerts[0][j].clone().multiply(cornerLayout[i]);
183 |
184 | cornerVerts[i].push(vert);
185 |
186 | vertexPool.push(vert);
187 |
188 | var norm = cornerNormals[0][j].clone().multiply(cornerLayout[i]);
189 |
190 | cornerNormals[i].push(norm);
191 |
192 | normalPool.push(norm);
193 |
194 | }
195 |
196 | }
197 |
198 | }
199 |
200 |
201 | // weave corners ====================================
202 |
203 | function doCorners() {
204 |
205 | var indexInd = 0;
206 |
207 |
208 | var flips = [
209 | true,
210 | false,
211 | true,
212 | false,
213 | false,
214 | true,
215 | false,
216 | true
217 | ];
218 |
219 | var lastRowOffset = rs1 * (radiusSegments - 1);
220 |
221 | for (var i = 0; i < 8; i++) {
222 |
223 | var cornerOffset = cornerVertNumber * i;
224 |
225 | for (var v = 0; v < radiusSegments - 1; v++) {
226 |
227 | var r1 = v * rs1; //row offset
228 | var r2 = (v + 1) * rs1; //next row
229 |
230 | for (var u = 0; u < radiusSegments; u++) {
231 |
232 | var u1 = u + 1;
233 | var a = cornerOffset + r1 + u;
234 | var b = cornerOffset + r1 + u1;
235 | var c = cornerOffset + r2 + u;
236 | var d = cornerOffset + r2 + u1;
237 |
238 | if (!flips[i]) {
239 |
240 | indices.push(a);
241 | indices.push(b);
242 | indices.push(c);
243 |
244 | indices.push(b);
245 | indices.push(d);
246 | indices.push(c);
247 |
248 | } else {
249 |
250 | indices.push(a);
251 | indices.push(c);
252 | indices.push(b);
253 |
254 | indices.push(b);
255 | indices.push(c);
256 | indices.push(d);
257 |
258 | }
259 |
260 | }
261 |
262 | }
263 |
264 | for (var u = 0; u < radiusSegments; u++) {
265 |
266 | var a = cornerOffset + lastRowOffset + u;
267 | var b = cornerOffset + lastRowOffset + u + 1;
268 | var c = cornerOffset + lastVertex;
269 |
270 | if (!flips[i]) {
271 |
272 | indices.push(a);
273 | indices.push(b);
274 | indices.push(c);
275 |
276 | } else {
277 |
278 | indices.push(a);
279 | indices.push(c);
280 | indices.push(b);
281 |
282 | }
283 |
284 | }
285 |
286 | }
287 |
288 | }
289 |
290 |
291 | //plates ============================================
292 | //fix this loop matrices find pattern something
293 |
294 | function doFaces() {
295 |
296 | //top
297 | var a = lastVertex;// + cornerVertNumber * 0;
298 | var b = lastVertex + cornerVertNumber;// * 1;
299 | var c = lastVertex + cornerVertNumber * 2;
300 | var d = lastVertex + cornerVertNumber * 3;
301 |
302 | indices.push(a);
303 | indices.push(b);
304 | indices.push(c);
305 | indices.push(a);
306 | indices.push(c);
307 | indices.push(d);
308 |
309 | //bottom
310 | a = lastVertex + cornerVertNumber * 4;// + cornerVertNumber * 0;
311 | b = lastVertex + cornerVertNumber * 5;// * 1;
312 | c = lastVertex + cornerVertNumber * 6;
313 | d = lastVertex + cornerVertNumber * 7;
314 |
315 | indices.push(a);
316 | indices.push(c);
317 | indices.push(b);
318 | indices.push(a);
319 | indices.push(d);
320 | indices.push(c);
321 |
322 | //left
323 | a = 0;
324 | b = cornerVertNumber;
325 | c = cornerVertNumber * 4;
326 | d = cornerVertNumber * 5;
327 |
328 | indices.push(a);
329 | indices.push(c);
330 | indices.push(b);
331 | indices.push(b);
332 | indices.push(c);
333 | indices.push(d);
334 |
335 | //right
336 | a = cornerVertNumber * 2;
337 | b = cornerVertNumber * 3;
338 | c = cornerVertNumber * 6;
339 | d = cornerVertNumber * 7;
340 |
341 | indices.push(a);
342 | indices.push(c);
343 | indices.push(b);
344 | indices.push(b);
345 | indices.push(c);
346 | indices.push(d);
347 |
348 | //front
349 | a = radiusSegments;
350 | b = radiusSegments + cornerVertNumber * 3;
351 | c = radiusSegments + cornerVertNumber * 4;
352 | d = radiusSegments + cornerVertNumber * 7;
353 |
354 | indices.push(a);
355 | indices.push(b);
356 | indices.push(c);
357 | indices.push(b);
358 | indices.push(d);
359 | indices.push(c);
360 |
361 | //back
362 | a = radiusSegments + cornerVertNumber;
363 | b = radiusSegments + cornerVertNumber * 2;
364 | c = radiusSegments + cornerVertNumber * 5;
365 | d = radiusSegments + cornerVertNumber * 6;
366 |
367 | indices.push(a);
368 | indices.push(c);
369 | indices.push(b);
370 | indices.push(b);
371 | indices.push(c);
372 | indices.push(d);
373 |
374 | }
375 |
376 |
377 | // weave edges ======================================
378 |
379 | function doHeightEdges() {
380 |
381 | for (var i = 0; i < 4; i++) {
382 |
383 | var cOffset = i * cornerVertNumber;
384 | var cRowOffset = 4 * cornerVertNumber + cOffset;
385 | var needsFlip = i & 1 === 1;
386 | for (var u = 0; u < radiusSegments; u++) {
387 |
388 | var u1 = u + 1;
389 | var a = cOffset + u;
390 | var b = cOffset + u1;
391 | var c = cRowOffset + u;
392 | var d = cRowOffset + u1;
393 |
394 | if (!needsFlip) {
395 |
396 | indices.push(a);
397 | indices.push(b);
398 | indices.push(c);
399 | indices.push(b);
400 | indices.push(d);
401 | indices.push(c);
402 |
403 | } else {
404 |
405 | indices.push(a);
406 | indices.push(c);
407 | indices.push(b);
408 | indices.push(b);
409 | indices.push(c);
410 | indices.push(d);
411 |
412 | }
413 |
414 | }
415 |
416 | }
417 |
418 | }
419 |
420 | function doDepthEdges() {
421 |
422 | var cStarts = [0, 2, 4, 6];
423 | var cEnds = [1, 3, 5, 7];
424 |
425 | for (var i = 0; i < 4; i++) {
426 |
427 | var cStart = cornerVertNumber * cStarts[i];
428 | var cEnd = cornerVertNumber * cEnds[i];
429 |
430 | var needsFlip = 1 >= i;
431 |
432 | for (var u = 0; u < radiusSegments; u++) {
433 |
434 | var urs1 = u * rs1;
435 | var u1rs1 = (u + 1) * rs1;
436 |
437 | var a = cStart + urs1;
438 | var b = cStart + u1rs1;
439 | var c = cEnd + urs1;
440 | var d = cEnd + u1rs1
441 |
442 | if (needsFlip) {
443 |
444 | indices.push(a);
445 | indices.push(c);
446 | indices.push(b);
447 | indices.push(b);
448 | indices.push(c);
449 | indices.push(d);
450 |
451 | } else {
452 |
453 | indices.push(a);
454 | indices.push(b);
455 | indices.push(c);
456 | indices.push(b);
457 | indices.push(d);
458 | indices.push(c);
459 |
460 | }
461 |
462 | }
463 |
464 | }
465 |
466 | }
467 |
468 | function doWidthEdges() {
469 |
470 | var end = radiusSegments - 1;
471 |
472 | var cStarts = [0, 1, 4, 5];
473 | var cEnds = [3, 2, 7, 6];
474 | var needsFlip = [0, 1, 1, 0];
475 |
476 | for (var i = 0; i < 4; i++) {
477 |
478 | var cStart = cStarts[i] * cornerVertNumber;
479 | var cEnd = cEnds[i] * cornerVertNumber;
480 |
481 |
482 | for (var u = 0; u <= end; u++) {
483 |
484 | // var dInd = u != end ? radiusSegments + u * rs1 : cornerVertNumber - 1;
485 |
486 | var a = cStart + radiusSegments + u * rs1;
487 | var b = cStart + (u != end ? radiusSegments + (u + 1) * rs1 : cornerVertNumber - 1);
488 |
489 | var c = cEnd + radiusSegments + u * rs1;
490 | var d = cEnd + (u != end ? radiusSegments + (u + 1) * rs1 : cornerVertNumber - 1);
491 |
492 | if (!needsFlip[i]) {
493 |
494 | indices.push(a);
495 | indices.push(b);
496 | indices.push(c);
497 | indices.push(b);
498 | indices.push(d);
499 | indices.push(c);
500 |
501 | }
502 | else {
503 |
504 | indices.push(a);
505 | indices.push(c);
506 | indices.push(b);
507 | indices.push(b);
508 | indices.push(c);
509 | indices.push(d);
510 |
511 | }
512 |
513 | }
514 |
515 | }
516 |
517 | }
518 |
519 |
520 | //fill buffers ======================================
521 |
522 | var index = 0;
523 |
524 | for (var i = 0; i < vertexPool.length; i++) {
525 |
526 | positions.setXYZ(
527 | index,
528 | vertexPool[i].x,
529 | vertexPool[i].y,
530 | vertexPool[i].z
531 | );
532 |
533 | normals.setXYZ(
534 | index,
535 | normalPool[i].x,
536 | normalPool[i].y,
537 | normalPool[i].z
538 | );
539 |
540 | index++;
541 |
542 | }
543 |
544 | this.setIndex(new THREE.BufferAttribute(new Uint16Array(indices), 1));
545 |
546 | this.setAttribute('position', positions);
547 |
548 | this.setAttribute('normal', normals);
549 |
550 | };
551 | }
552 |
553 |
554 | export default RoundedBoxGeometry
555 |
--------------------------------------------------------------------------------
/src/demo.js:
--------------------------------------------------------------------------------
1 | import "./style.css"
2 | import { gsap } from "gsap"
3 |
4 | import { Rendering } from "./rendering"
5 |
6 | import * as THREE from "three";
7 | import RoundedBox from './RoundedBox'
8 |
9 | class InstancedMouseEffect {
10 | constructor(opts = {}, follower = null ){
11 |
12 |
13 | if(opts.speed == null) {
14 | opts.speed = 1
15 | }
16 | if(opts.frequency == null) {
17 | opts.frequency = 1
18 | }
19 | if(opts.mouseSize == null) {
20 | opts.mouseSize = 1
21 | }
22 | if(opts.rotationSpeed == null) {
23 | opts.rotationSpeed = 1
24 | }
25 | if(opts.rotationAmmount == null) {
26 | opts.rotationAmmount = 0
27 | }
28 | if(opts.mouseScaling == null) {
29 | opts.mouseScaling = 0
30 | }
31 | if(opts.mouseIndent == null) {
32 | opts.mouseIndent = 1
33 | }
34 | if(opts.color == null) {
35 | opts.color = "#1084ff"
36 | }
37 | if(opts.colorDegrade == null) {
38 | opts.colorDegrade = 1.
39 | }
40 | if(opts.shape == null) {
41 | opts.shape = "square"
42 | }
43 | // Renderer up
44 | let rendering = new Rendering(document.querySelector("#canvas"), false)
45 | rendering.renderer.shadowMap.enabled = true;
46 | rendering.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
47 | rendering.camera.position.z = 40
48 | rendering.camera.position.y = 40
49 | rendering.camera.position.x = 40
50 | rendering.camera.lookAt(new THREE.Vector3(0,0,0))
51 | this.rendering = rendering;
52 |
53 |
54 | // follower = new THREE.Mesh(
55 | // new THREE.BoxGeometry(),
56 | // new THREE.MeshPhysicalMaterial({
57 | // emissive: 0x000000,
58 | // color: "#ff4080",
59 | // color: "#2040bb",
60 | // roughness: 0,
61 | // metalness: 0.4
62 | // })
63 | // )
64 | // rendering.scene.add(follower)
65 |
66 | // let controls = new OrbitControls(rendering.camera, rendering.canvas)
67 |
68 | let uTime = { value: 0 };
69 |
70 | // Light Setup
71 | rendering.scene.add(new THREE.HemisphereLight(0x9f9f9f, 0xffffff, 1))
72 | rendering.scene.add(new THREE.AmbientLight(0xffffff, 1))
73 | let d2 = new THREE.DirectionalLight(0x909090, 1)
74 | rendering.scene.add(d2)
75 | d2.position.set( -1, 0.5, 1)
76 | d2.position.multiplyScalar(10)
77 |
78 | let d1 = new THREE.DirectionalLight(0xffffff, 4)
79 | rendering.scene.add(d1)
80 | d1.position.set( 1, 0.5, 1)
81 | d1.position.multiplyScalar(10)
82 |
83 | d1.castShadow = true
84 | d1.shadow.camera.left = -10
85 | d1.shadow.camera.right = 10
86 | d1.shadow.camera.top = 10
87 | d1.shadow.camera.bottom = -10
88 | d1.shadow.camera.far = 40
89 |
90 | d1.shadow.mapSize.width = 2048
91 | d1.shadow.mapSize.height = 2048
92 |
93 | // DEMO CODE
94 |
95 | let grid = 55;
96 | let size = .5;
97 | let gridSize = grid * size
98 |
99 | let geometry = new THREE.BoxGeometry(size, size, size);
100 | geometry = new RoundedBox(size, size, size, 0.1, 4);
101 | if(typeof(opts.shape) == "string"){
102 | switch(opts.shape){
103 | case "cylinder":
104 | geometry = new THREE.CylinderGeometry(size, size, size);
105 | break
106 | case "torus":
107 | geometry = new THREE.TorusGeometry(size * 0.5, size * 0.3)
108 | break
109 | case "icosahedron":
110 | geometry = new THREE.IcosahedronGeometry(size, 0)
111 | break
112 | }
113 | } else {
114 | geometry = opts.shape;
115 | }
116 |
117 |
118 | let material = new THREE.MeshPhysicalMaterial({ color: opts.color, metalness: 0., roughness: 0.0 })
119 | let mesh = new THREE.InstancedMesh(geometry, material, grid * grid);
120 |
121 | mesh.castShadow = true
122 | mesh.receiveShadow = true
123 |
124 |
125 | const totalColor = material.color.r + material.color.g + material.color.b;
126 | const color = new THREE.Vector3()
127 | const weights = new THREE.Vector3()
128 | weights.x = material.color.r
129 | weights.y = material.color.g
130 | weights.z = material.color.b
131 | weights.divideScalar(totalColor)
132 | weights.multiplyScalar(-0.5)
133 | weights.addScalar(1.)
134 |
135 | let dummy = new THREE.Object3D()
136 |
137 | let i =0;
138 | for(let x = 0; x < grid; x++)
139 | for(let y = 0; y < grid; y++){
140 |
141 |
142 | dummy.position.set(
143 | x * size - gridSize /2 + size / 2.,
144 | 0,
145 | y * size - gridSize/2 + size / 2.,
146 | );
147 |
148 | dummy.updateMatrix()
149 | mesh.setMatrixAt(i, dummy.matrix)
150 |
151 | let center = 1.- dummy.position.length() * 0.12 * opts.colorDegrade
152 | color.set( center * weights.x + (1.-weights.x) , center * weights.y + (1.-weights.y) , center * weights.z + (1.-weights.z))
153 | mesh.setColorAt(i,color)
154 |
155 | i++;
156 | }
157 | let vertexHead = glsl`
158 |
159 | uniform float uTime;
160 | uniform float uAnimate;
161 | uniform vec2 uPos0;
162 | uniform vec2 uPos1;
163 | uniform vec4 uConfig;
164 | uniform vec4 uConfig2;
165 |
166 | float map(float value, float min1, float max1, float min2, float max2) {
167 | return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
168 | }
169 | mat4 rotationMatrix(vec3 axis, float angle) {
170 | axis = normalize(axis);
171 | float s = sin(angle);
172 | float c = cos(angle);
173 | float oc = 1.0 - c;
174 |
175 | return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0,
176 | oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0,
177 | oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0,
178 | 0.0, 0.0, 0.0, 1.0);
179 | }
180 |
181 | vec3 rotate(vec3 v, vec3 axis, float angle) {
182 | mat4 m = rotationMatrix(axis, angle);
183 | return (m * vec4(v, 1.0)).xyz;
184 | }
185 | float sdSegment( in vec2 p, in vec2 a, in vec2 b )
186 | {
187 | vec2 pa = p-a, ba = b-a;
188 | float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
189 | return length( pa - ba*h );
190 | }
191 | #pragma glslify: ease = require(glsl-easings/cubic-in-out)
192 | #pragma glslify: ease = require(glsl-easings/cubic-out)
193 | void main(){
194 | `
195 | let projectVertex = glsl`
196 |
197 | vec4 position = instanceMatrix[3];
198 | float toCenter = length(position.xz) ;
199 |
200 |
201 | // float mouseTrail = length(position.xz- uPos0.xy);
202 | float mouseTrail = sdSegment(position.xz, uPos0, uPos1 );
203 | mouseTrail = smoothstep(2.0, 5. * uConfig.z , mouseTrail) ;
204 |
205 | // Mouse Scale
206 | transformed *= 1. + cubicOut(1.0-mouseTrail) * uConfig2.y;
207 |
208 |
209 | // Instance Animation
210 | float start = 0. + toCenter * 0.02;
211 | float end = start+ (toCenter + 1.5) * 0.06;
212 | float anim = (map(clamp(uAnimate, start,end) , start, end, 0., 1.));
213 |
214 |
215 | transformed = rotate(transformed, vec3(0., 1., 1. ),uConfig2.x * (anim * 3.14+ uTime * uConfig.x + toCenter * 0.4 * uConfig.w) );
216 |
217 | // Mouse Offset
218 | transformed.y += (-1.0 * (1.-mouseTrail)) * uConfig2.z;
219 |
220 | transformed.xyz *= cubicInOut(anim);
221 | transformed.y += cubicInOut(1.-anim) * 1.;
222 |
223 | transformed.y += sin(uTime * 2. * uConfig.x + toCenter * uConfig.y) * 0.1;
224 |
225 | vec4 mvPosition = vec4( transformed, 1.0 );
226 |
227 | #ifdef USE_INSTANCING
228 |
229 | mvPosition = instanceMatrix * mvPosition;
230 |
231 | #endif
232 |
233 | mvPosition = modelViewMatrix * mvPosition;
234 |
235 | gl_Position = projectionMatrix * mvPosition;
236 | `
237 | let uniforms = {
238 | uTime: uTime,
239 | uPos0: {value: new THREE.Vector2()},
240 | uPos1: {value: new THREE.Vector2()},
241 | uAnimate: {value: 0},
242 | uConfig: { value: new THREE.Vector4(opts.speed, opts.frequency, opts.mouseSize, opts.rotationSpeed)},
243 | uConfig2: { value: new THREE.Vector4(opts.rotationAmmount, opts.mouseScaling, opts.mouseIndent)}
244 | }
245 | mesh.material.onBeforeCompile = (shader)=>{
246 | shader.vertexShader = shader.vertexShader.replace("void main() {", vertexHead)
247 | shader.vertexShader = shader.vertexShader.replace("#include ", projectVertex)
248 | shader.uniforms = {
249 | ...shader.uniforms,
250 | ...uniforms,
251 | }
252 | }
253 |
254 |
255 | mesh.customDepthMaterial = new THREE.MeshDepthMaterial()
256 | mesh.customDepthMaterial.onBeforeCompile = (shader)=>{
257 | shader.vertexShader = shader.vertexShader.replace("void main() {", vertexHead)
258 | shader.vertexShader = shader.vertexShader.replace("#include ", projectVertex)
259 | shader.uniforms = {
260 | ...shader.uniforms,
261 | ...uniforms,
262 | }
263 | }
264 | mesh.customDepthMaterial.depthPacking = THREE.RGBADepthPacking
265 | rendering.scene.add(mesh)
266 |
267 |
268 | let t1= gsap.timeline()
269 | t1.to(uniforms.uAnimate, {
270 | value: 1,
271 | duration: 3.0,
272 | ease: "none"
273 | }, 0.0)
274 | if(follower){
275 |
276 | t1.from(follower.scale,
277 | {x: 0, y: 0, z: 0, duration: 1, ease: "back.out"},
278 | 1,
279 | )
280 | }
281 | this.animation = t1;
282 |
283 | // Events
284 | const hitplane = new THREE.Mesh(
285 | new THREE.PlaneGeometry(),
286 | new THREE.MeshBasicMaterial()
287 | )
288 | hitplane.scale.setScalar(20)
289 | hitplane.rotation.x = -Math.PI/2
290 | hitplane.updateMatrix()
291 | hitplane.updateMatrixWorld()
292 | let raycaster = new THREE.Raycaster()
293 |
294 | let mouse = new THREE.Vector2()
295 | let v2 = new THREE.Vector2()
296 | window.addEventListener('mousemove', (ev)=>{
297 | let x = ev.clientX / window.innerWidth - 0.5
298 | let y = ev.clientY / window.innerHeight - 0.5
299 |
300 | v2.x = x *2;
301 | v2.y = -y *2;
302 | raycaster.setFromCamera(v2,rendering.camera)
303 |
304 | let intersects = raycaster.intersectObject(hitplane)
305 |
306 | if(intersects.length > 0){
307 | let first = intersects[0]
308 | mouse.x = first.point.x
309 | mouse.y = first.point.z
310 | // mouse.copy(first.point)
311 | }
312 |
313 | })
314 |
315 | let vel = new THREE.Vector2()
316 | const tick = (t, delta)=>{
317 | uTime.value = t
318 |
319 | let v3 = new THREE.Vector2()
320 | v3.copy(mouse)
321 | v3.sub(uniforms.uPos0.value)
322 | v3.multiplyScalar(0.08)
323 | uniforms.uPos0.value.add(v3)
324 |
325 | // Calculate the change/velocity
326 | v3.copy(uniforms.uPos0.value)
327 | v3.sub(uniforms.uPos1.value)
328 | v3.multiplyScalar(0.05)
329 |
330 | // Lerp the change as well
331 | v3.sub(vel)
332 | v3.multiplyScalar(0.05)
333 | vel.add(v3)
334 |
335 | // Add the lerped velocity
336 | uniforms.uPos1.value.add(vel)
337 |
338 | if(follower ){
339 | follower.position.x = uniforms.uPos0.value.x
340 | follower.position.z = uniforms.uPos0.value.y
341 | follower.rotation.x = t
342 | follower.rotation.y = t
343 | }
344 |
345 | rendering.render()
346 |
347 | }
348 |
349 | gsap.ticker.add(tick)
350 |
351 | }
352 | }
353 |
354 | if(process.env.NODE_ENV === "development"){
355 | new InstancedMouseEffect()
356 | }
357 |
358 | export default InstancedMouseEffect
359 |
360 | window.InstancedMouseEffect = InstancedMouseEffect
361 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Offscreen Canvas DEMO
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/rendering.js:
--------------------------------------------------------------------------------
1 |
2 | import { BloomEffect, EffectComposer, EffectPass, NormalPass, OverrideMaterialManager, RenderPass, SSAOEffect, ToneMappingEffect } from "postprocessing";
3 | import * as THREE from "three";
4 | import Stats from 'stats-js'
5 |
6 | let stats = new Stats()
7 | // document.body.append(stats.dom)
8 |
9 | import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"
10 | import { N8AOPostPass } from "n8ao";
11 |
12 | export class Rendering {
13 | constructor(canvas, usePostProcess = false) {
14 | this.canvas = canvas;
15 | // let hex = "#"+ palette.highlight.getHexString()
16 | // document.documentElement.style.setProperty("--text", hex);
17 |
18 |
19 |
20 | this.vp = {
21 | canvas: {
22 | width: canvas.offsetWidth,
23 | height: canvas.offsetHeight,
24 | dpr: Math.min(window.devicePixelRatio, 1.5)
25 | },
26 | scene: {
27 | width: 1,
28 | height: 1
29 | },
30 | screen: {
31 | width: window.innerWidth,
32 | height: window.innerHeight,
33 | },
34 | }
35 | this.renderer = new THREE.WebGLRenderer({
36 | antialias: false,
37 | canvas,
38 | stencil: false,
39 | });
40 |
41 | this.renderer.setSize(this.vp.canvas.width, this.vp.canvas.height, false);
42 | this.renderer.setPixelRatio(this.vp.canvas.dpr);
43 |
44 | let size = 4
45 | let ratio = this.vp.canvas.width / this.vp.canvas.height;
46 | let ratioW = this.vp.canvas.height / this.vp.canvas.width;
47 |
48 | if(ratio > ratioW){
49 | ratioW = 1;
50 | } else {
51 | ratio = 1;
52 | }
53 |
54 | this.camera = new THREE.OrthographicCamera(-size * ratio, size * ratio,size * ratioW ,-size * ratioW , 0.001, 1000)
55 |
56 |
57 | this.scene = new THREE.Scene();
58 |
59 | // this.scene.background = palette.BG.clone()
60 |
61 | this.clock = new THREE.Clock();
62 |
63 | // this.vp.scene = this.getViewSizeAtDepth();
64 |
65 | this.disposed = false;
66 | // this.renderer.outputColorSpace = THREE.LinearSRGBColorSpace
67 | OverrideMaterialManager.workaroundEnabled = true;
68 | if(usePostProcess){
69 | const composer = new EffectComposer(this.renderer);
70 | composer.addPass(new RenderPass(this.scene, this.camera));
71 |
72 | // const normalPass = new NormalPass(this.scene, this.camera, {resolutionScale: 0.75});
73 | // normalPass.renderPass.overrideMaterialManager.render = function (renderer, scene, camera) {
74 | //
75 | //
76 | // // Ignore shadows.
77 | // const shadowMapEnabled = renderer.shadowMap.enabled;
78 | // renderer.shadowMap.enabled = false;
79 | //
80 | // if(OverrideMaterialManager.workaroundEnabled) {
81 | //
82 | //
83 | // const originalMaterials = this.originalMaterials;
84 | //
85 | // this.meshCount = 0;
86 | // scene.traverse((node) => {
87 | // this.replaceMaterial(node)
88 | // if(!node.isMesh) return;
89 | // if(node.customNormalMaterial){
90 | // node.material = node.customNormalMaterial;
91 | // }
92 | // });
93 | // renderer.render(scene, camera);
94 | //
95 | // for(const entry of originalMaterials) {
96 | //
97 | // entry[0].material = entry[1];
98 | //
99 | // }
100 | //
101 | // if(this.meshCount !== originalMaterials.size) {
102 | //
103 | // originalMaterials.clear();
104 | //
105 | // }
106 | //
107 | // } else {
108 | //
109 | // const overrideMaterial = scene.overrideMaterial;
110 | // scene.overrideMaterial = this.material;
111 | // renderer.render(scene, camera);
112 | // scene.overrideMaterial = overrideMaterial;
113 | //
114 | // }
115 | //
116 | // renderer.shadowMap.enabled = shadowMapEnabled;
117 | //
118 | // }
119 |
120 | // composer.addPass(normalPass)
121 | // composer.addPass(new EffectPass(this.camera, new SSAOEffect(this.camera, normalPass.texture, {resolutionScale: 0.75, intensity: 2, color: new THREE.Color(0x000000), radius: 0.020, samples: 10, rings: 4 })));
122 | //
123 | const n8aopass = new N8AOPostPass(
124 | this.scene,
125 | this.camera,
126 | this.vp.canvas.width ,
127 | this.vp.canvas.height
128 | );
129 | n8aopass.configuration.aoRadius = 0.2;
130 | n8aopass.configuration.distanceFalloff = 0.5;
131 | n8aopass.configuration.intensity = 20.0;
132 | n8aopass.configuration.color = new THREE.Color(0, 0, 0);
133 | n8aopass.configuration.aoSamples = 8;
134 | n8aopass.configuration.denoiseSamples = 4;
135 | n8aopass.configuration.denoiseRadius = 12;
136 | n8aopass.configuration.halfRes = true;
137 | n8aopass.setQualityMode("Medium")
138 |
139 | n8aopass.configuration.halfRes = true;
140 |
141 |
142 | n8aopass.screenSpaceRadius = true
143 | composer.addPass(n8aopass)
144 | // n8aopass.setDisplayMode("Split");
145 | // composer.addPass(new EffectPass(this.camera, new ToneMappingEffect({ mode: THREE.ACESFilmicToneMapping })));
146 |
147 |
148 | this.composer = composer
149 | }
150 | this.usePostProcess = usePostProcess;
151 |
152 |
153 | this.addEvents();
154 | }
155 | addEvents() {
156 | window.addEventListener("resize", this.onResize);
157 | }
158 | dispose() {}
159 | getViewSizeAtDepth(depth = 0) {
160 | const fovInRadians = (this.camera.fov * Math.PI) / 180;
161 | const height = Math.abs(
162 | (this.camera.position.z - depth) * Math.tan(fovInRadians / 2) * 2
163 | );
164 | return { width: height * this.camera.aspect, height };
165 | }
166 | init() { }
167 | render() {
168 | stats.begin()
169 | if(this.usePostProcess){
170 | this.composer.render()
171 | } else {
172 | this.renderer.render(this.scene, this.camera);
173 | }
174 | stats.end()
175 | }
176 | onResize = () => {
177 | let canvas = this.canvas
178 | this.vp.canvas.width = canvas.offsetWidth;
179 | this.vp.canvas.height = canvas.offsetHeight;
180 | this.vp.canvas.dpr = Math.min(window.devicePixelRatio, 2);
181 |
182 | this.vp.scene.width = window.innerWidth;
183 | this.vp.scene.height = window.innerHeight;
184 |
185 | this.renderer.setSize(this.vp.canvas.width, this.vp.canvas.height, false);
186 |
187 | let size = 4
188 | let ratio = this.vp.canvas.width / this.vp.canvas.height;
189 | let ratioW = this.vp.canvas.height / this.vp.canvas.width;
190 |
191 | if(ratio > ratioW){
192 | ratioW = 1;
193 | } else {
194 | ratio = 1;
195 | }
196 |
197 | this.camera.left = -size * ratio
198 | this.camera.right = size * ratio
199 | this.camera.top = size * ratioW
200 | this.camera.bottom = -size * ratioW
201 |
202 | // this.camera.aspect = this.vp.canvas.width / this.vp.canvas.height;
203 | this.camera.updateProjectionMatrix();
204 |
205 | this.vp.scene = this.getViewSizeAtDepth();
206 | }
207 | }
208 |
209 | // let a = new Demo(GL.canvas);
210 | // a.init();
211 |
--------------------------------------------------------------------------------
/src/style.css:
--------------------------------------------------------------------------------
1 |
2 | /* DEMO SPECIFIC CSS*/
3 |
4 |
5 | /* Canvas required*/
6 | #canvas {
7 | width: 100%;
8 | height: 100%;
9 | }
10 |
11 | #canvas-wrapper {
12 | position: fixed;
13 | top: 0;
14 | left: 0;
15 | width: 100%;
16 | height: 100%;
17 | }
18 |
19 | /* UI STUFF*/
20 |
21 | :root {
22 | font-family: sofia-pro, -apple-system, BlinkMacSystemFont, "Segoe UI",
23 | Helvetica, "Open Sans", Arial, sans-serif;
24 |
25 | }
26 |
27 | body {
28 | margin: 0;
29 | width: 100%;
30 | height: 100vh;
31 | overflow: hidden;
32 | color: var(--text);
33 | }
34 |
35 | body,
36 | html {
37 | font-size: 16px;
38 | line-height: 1.5;
39 | letter-spacing: 0.005em;
40 | }
41 | .ui {
42 | position: fixed;
43 | bottom: 50px;
44 | left: 0;
45 | right: 0;
46 | text-align: center;
47 | }
48 | .ui-logo {
49 | font-size: 1rem;
50 | margin: 0;
51 | margin-bottom: 1rem !important;
52 | user-select: none;
53 | text-transform: uppercase;
54 | }
55 | .ui-title {
56 | font-family: thunder2, "Thunder2", thunder, sofia-pro, -apple-system, BlinkMacSystemFont, "Segoe UI",
57 | Helvetica, "Open Sans", Arial, sans-serif;
58 | font-size: 4rem;
59 | font-weight: 800;
60 | line-height: 0.8;
61 | letter-spacing: .05em;
62 |
63 | margin-bottom: 0 !important;
64 | width: 100% !important;
65 | max-width: 80% !important;
66 |
67 | user-select: none;
68 | text-align: center;
69 | margin: 0 auto !important;
70 |
71 | text-transform: uppercase;
72 | }
73 |
--------------------------------------------------------------------------------
/src/utils.js:
--------------------------------------------------------------------------------
1 | export function getMousePos(e){
2 | const x = e.changedTouches ? e.changedTouches[0].clientX : e.clientX;
3 | const y = e.changedTouches ? e.changedTouches[0].clientY : e.clientY;
4 | const target = e.target;
5 |
6 | return {
7 | x,
8 | y,
9 | target,
10 | };
11 | }
12 |
13 | export const sinPaletteHead = `
14 | uniform vec3 c0;
15 | uniform vec3 c1;
16 | uniform vec3 c2;
17 | uniform vec3 c3;
18 |
19 | vec3 palette( in float t, in vec3 a, in vec3 b, in vec3 c, in vec3 d ){
20 | return a + b*cos( 6.28318*(c*t+d) );
21 | }
22 | `
23 |
24 |
25 | // Demo Utils
26 |
27 | export function getPaletteFromParams(defaultPalette = "black"){
28 | let search = new URLSearchParams(window.location.search)
29 | return search.get("palette") == null ? defaultPalette : search.get("palette")
30 | }
31 |
32 | let palettes = [
33 | "black",
34 | "pink",
35 | "aquamarine",
36 | "blue",
37 | "darkblue",
38 | "grey",
39 | "white",
40 | "orange"
41 | ]
42 |
43 | export function setupControls(palette){
44 | window.addEventListener("keydown",(ev)=>{
45 |
46 | let currentI = palettes.indexOf(palette);
47 |
48 | switch(ev.key){
49 | case "ArrowLeft":
50 | let prevPalette = (currentI - 1) < 0 ? palettes.length-1: currentI - 1;
51 | window.location.search = "?palette="+palettes[prevPalette]
52 | // window.location.reload()
53 | break;
54 | case "ArrowRight":
55 | let nextPalette = (currentI + 1) % palettes.length
56 | window.location.search = "?palette="+palettes[nextPalette]
57 | break;
58 | }
59 | })
60 | }
61 |
--------------------------------------------------------------------------------
/src/vite.config.js:
--------------------------------------------------------------------------------
1 | // vite.config.js
2 | import { defineConfig } from 'vite';
3 |
4 | import {glslify} from 'vite-plugin-glslify'
5 |
6 | export default defineConfig({
7 | plugins: [glslify()],
8 | build: {
9 | rollupOptions: {
10 | output: {
11 | entryFileNames: `[name].js`,
12 | chunkFileNames: `[name].js`,
13 | assetFileNames: `[name].[ext]`
14 | }
15 | }
16 | }
17 | });
18 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | // vite.config.js
2 | import { defineConfig } from 'vite';
3 |
4 | import {glslify} from 'vite-plugin-glslify'
5 |
6 | export default defineConfig({
7 | plugins: [glslify()]
8 | });
9 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@choojs/findup@^0.2.0":
6 | version "0.2.1"
7 | resolved "https://registry.yarnpkg.com/@choojs/findup/-/findup-0.2.1.tgz#ac13c59ae7be6e1da64de0779a0a7f03d75615a3"
8 | integrity sha512-YstAqNb0MCN8PjdLCDfRsBcGVRN41f3vgLvaI0IrIcBp4AqILRSS0DeWNGkicC+f/zRIPJLc+9RURVSepwvfBw==
9 | dependencies:
10 | commander "^2.15.1"
11 |
12 | "@esbuild/android-arm64@0.18.20":
13 | version "0.18.20"
14 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622"
15 | integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==
16 |
17 | "@esbuild/android-arm@0.18.20":
18 | version "0.18.20"
19 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682"
20 | integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==
21 |
22 | "@esbuild/android-x64@0.18.20":
23 | version "0.18.20"
24 | resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2"
25 | integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==
26 |
27 | "@esbuild/darwin-arm64@0.18.20":
28 | version "0.18.20"
29 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz#08172cbeccf95fbc383399a7f39cfbddaeb0d7c1"
30 | integrity sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==
31 |
32 | "@esbuild/darwin-x64@0.18.20":
33 | version "0.18.20"
34 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d"
35 | integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==
36 |
37 | "@esbuild/freebsd-arm64@0.18.20":
38 | version "0.18.20"
39 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54"
40 | integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==
41 |
42 | "@esbuild/freebsd-x64@0.18.20":
43 | version "0.18.20"
44 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e"
45 | integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==
46 |
47 | "@esbuild/linux-arm64@0.18.20":
48 | version "0.18.20"
49 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0"
50 | integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==
51 |
52 | "@esbuild/linux-arm@0.18.20":
53 | version "0.18.20"
54 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0"
55 | integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==
56 |
57 | "@esbuild/linux-ia32@0.18.20":
58 | version "0.18.20"
59 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7"
60 | integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==
61 |
62 | "@esbuild/linux-loong64@0.18.20":
63 | version "0.18.20"
64 | resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d"
65 | integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==
66 |
67 | "@esbuild/linux-mips64el@0.18.20":
68 | version "0.18.20"
69 | resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231"
70 | integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==
71 |
72 | "@esbuild/linux-ppc64@0.18.20":
73 | version "0.18.20"
74 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb"
75 | integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==
76 |
77 | "@esbuild/linux-riscv64@0.18.20":
78 | version "0.18.20"
79 | resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6"
80 | integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==
81 |
82 | "@esbuild/linux-s390x@0.18.20":
83 | version "0.18.20"
84 | resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071"
85 | integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==
86 |
87 | "@esbuild/linux-x64@0.18.20":
88 | version "0.18.20"
89 | resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz#c7690b3417af318a9b6f96df3031a8865176d338"
90 | integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==
91 |
92 | "@esbuild/netbsd-x64@0.18.20":
93 | version "0.18.20"
94 | resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1"
95 | integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==
96 |
97 | "@esbuild/openbsd-x64@0.18.20":
98 | version "0.18.20"
99 | resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae"
100 | integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==
101 |
102 | "@esbuild/sunos-x64@0.18.20":
103 | version "0.18.20"
104 | resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d"
105 | integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==
106 |
107 | "@esbuild/win32-arm64@0.18.20":
108 | version "0.18.20"
109 | resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9"
110 | integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==
111 |
112 | "@esbuild/win32-ia32@0.18.20":
113 | version "0.18.20"
114 | resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102"
115 | integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==
116 |
117 | "@esbuild/win32-x64@0.18.20":
118 | version "0.18.20"
119 | resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d"
120 | integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==
121 |
122 | "@rollup/pluginutils@^4.1.1":
123 | version "4.2.1"
124 | resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d"
125 | integrity sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==
126 | dependencies:
127 | estree-walker "^2.0.1"
128 | picomatch "^2.2.2"
129 |
130 | acorn@^7.1.1:
131 | version "7.4.1"
132 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
133 | integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
134 |
135 | astring@^1.7.5:
136 | version "1.8.6"
137 | resolved "https://registry.yarnpkg.com/astring/-/astring-1.8.6.tgz#2c9c157cf1739d67561c56ba896e6948f6b93731"
138 | integrity sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==
139 |
140 | bl@^2.2.1:
141 | version "2.2.1"
142 | resolved "https://registry.yarnpkg.com/bl/-/bl-2.2.1.tgz#8c11a7b730655c5d56898cdc871224f40fd901d5"
143 | integrity sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==
144 | dependencies:
145 | readable-stream "^2.3.5"
146 | safe-buffer "^5.1.1"
147 |
148 | buffer-from@^1.0.0:
149 | version "1.1.2"
150 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
151 | integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
152 |
153 | commander@^2.15.1:
154 | version "2.20.3"
155 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
156 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
157 |
158 | concat-stream@^1.5.2:
159 | version "1.6.2"
160 | resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
161 | integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==
162 | dependencies:
163 | buffer-from "^1.0.0"
164 | inherits "^2.0.3"
165 | readable-stream "^2.2.2"
166 | typedarray "^0.0.6"
167 |
168 | core-util-is@~1.0.0:
169 | version "1.0.3"
170 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
171 | integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
172 |
173 | deep-is@~0.1.3:
174 | version "0.1.4"
175 | resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
176 | integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
177 |
178 | duplexify@^3.4.5:
179 | version "3.7.1"
180 | resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309"
181 | integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==
182 | dependencies:
183 | end-of-stream "^1.0.0"
184 | inherits "^2.0.1"
185 | readable-stream "^2.0.0"
186 | stream-shift "^1.0.0"
187 |
188 | end-of-stream@^1.0.0:
189 | version "1.4.4"
190 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
191 | integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
192 | dependencies:
193 | once "^1.4.0"
194 |
195 | esbuild@^0.18.10:
196 | version "0.18.20"
197 | resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.20.tgz#4709f5a34801b43b799ab7d6d82f7284a9b7a7a6"
198 | integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==
199 | optionalDependencies:
200 | "@esbuild/android-arm" "0.18.20"
201 | "@esbuild/android-arm64" "0.18.20"
202 | "@esbuild/android-x64" "0.18.20"
203 | "@esbuild/darwin-arm64" "0.18.20"
204 | "@esbuild/darwin-x64" "0.18.20"
205 | "@esbuild/freebsd-arm64" "0.18.20"
206 | "@esbuild/freebsd-x64" "0.18.20"
207 | "@esbuild/linux-arm" "0.18.20"
208 | "@esbuild/linux-arm64" "0.18.20"
209 | "@esbuild/linux-ia32" "0.18.20"
210 | "@esbuild/linux-loong64" "0.18.20"
211 | "@esbuild/linux-mips64el" "0.18.20"
212 | "@esbuild/linux-ppc64" "0.18.20"
213 | "@esbuild/linux-riscv64" "0.18.20"
214 | "@esbuild/linux-s390x" "0.18.20"
215 | "@esbuild/linux-x64" "0.18.20"
216 | "@esbuild/netbsd-x64" "0.18.20"
217 | "@esbuild/openbsd-x64" "0.18.20"
218 | "@esbuild/sunos-x64" "0.18.20"
219 | "@esbuild/win32-arm64" "0.18.20"
220 | "@esbuild/win32-ia32" "0.18.20"
221 | "@esbuild/win32-x64" "0.18.20"
222 |
223 | escodegen@^1.11.1:
224 | version "1.14.3"
225 | resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503"
226 | integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==
227 | dependencies:
228 | esprima "^4.0.1"
229 | estraverse "^4.2.0"
230 | esutils "^2.0.2"
231 | optionator "^0.8.1"
232 | optionalDependencies:
233 | source-map "~0.6.1"
234 |
235 | esprima@^4.0.1:
236 | version "4.0.1"
237 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
238 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
239 |
240 | estraverse@^4.2.0:
241 | version "4.3.0"
242 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
243 | integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
244 |
245 | estree-walker@^2.0.1:
246 | version "2.0.2"
247 | resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
248 | integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
249 |
250 | esutils@^2.0.2:
251 | version "2.0.3"
252 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
253 | integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
254 |
255 | events@^3.2.0:
256 | version "3.3.0"
257 | resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
258 | integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
259 |
260 | falafel@^2.1.0:
261 | version "2.2.5"
262 | resolved "https://registry.yarnpkg.com/falafel/-/falafel-2.2.5.tgz#3ccb4970a09b094e9e54fead2deee64b4a589d56"
263 | integrity sha512-HuC1qF9iTnHDnML9YZAdCDQwT0yKl/U55K4XSUXqGAA2GLoafFgWRqdAbhWJxXaYD4pyoVxAJ8wH670jMpI9DQ==
264 | dependencies:
265 | acorn "^7.1.1"
266 | isarray "^2.0.1"
267 |
268 | fast-levenshtein@~2.0.6:
269 | version "2.0.6"
270 | resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
271 | integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
272 |
273 | from2@^2.3.0:
274 | version "2.3.0"
275 | resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af"
276 | integrity sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==
277 | dependencies:
278 | inherits "^2.0.1"
279 | readable-stream "^2.0.0"
280 |
281 | fsevents@~2.3.2:
282 | version "2.3.3"
283 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
284 | integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
285 |
286 | function-bind@^1.1.2:
287 | version "1.1.2"
288 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
289 | integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
290 |
291 | glsl-easings@^1.0.0:
292 | version "1.0.0"
293 | resolved "https://registry.yarnpkg.com/glsl-easings/-/glsl-easings-1.0.0.tgz#d4f7b499915e922921f4f03d0f8089724bdf5b8e"
294 | integrity sha512-blfWMqztNRVI4sJNyPlA9uV4T7xIm//Ie6fGGtnQPs3FpCj5YOWt/QIVFRMWpsBQhehRRGoaKG2yDw6tkAlmeA==
295 |
296 | glsl-inject-defines@^1.0.1:
297 | version "1.0.3"
298 | resolved "https://registry.yarnpkg.com/glsl-inject-defines/-/glsl-inject-defines-1.0.3.tgz#dd1aacc2c17fcb2bd3fc32411c6633d0d7b60fd4"
299 | integrity sha512-W49jIhuDtF6w+7wCMcClk27a2hq8znvHtlGnrYkSWEr8tHe9eA2dcnohlcAmxLYBSpSSdzOkRdyPTrx9fw49+A==
300 | dependencies:
301 | glsl-token-inject-block "^1.0.0"
302 | glsl-token-string "^1.0.1"
303 | glsl-tokenizer "^2.0.2"
304 |
305 | glsl-resolve@0.0.1:
306 | version "0.0.1"
307 | resolved "https://registry.yarnpkg.com/glsl-resolve/-/glsl-resolve-0.0.1.tgz#894bef73910d792c81b5143180035d0a78af76d3"
308 | integrity sha512-xxFNsfnhZTK9NBhzJjSBGX6IOqYpvBHxxmo+4vapiljyGNCY0Bekzn0firQkQrazK59c1hYxMDxYS8MDlhw4gA==
309 | dependencies:
310 | resolve "^0.6.1"
311 | xtend "^2.1.2"
312 |
313 | glsl-token-assignments@^2.0.0:
314 | version "2.0.2"
315 | resolved "https://registry.yarnpkg.com/glsl-token-assignments/-/glsl-token-assignments-2.0.2.tgz#a5d82ab78499c2e8a6b83cb69495e6e665ce019f"
316 | integrity sha512-OwXrxixCyHzzA0U2g4btSNAyB2Dx8XrztY5aVUCjRSh4/D0WoJn8Qdps7Xub3sz6zE73W3szLrmWtQ7QMpeHEQ==
317 |
318 | glsl-token-defines@^1.0.0:
319 | version "1.0.0"
320 | resolved "https://registry.yarnpkg.com/glsl-token-defines/-/glsl-token-defines-1.0.0.tgz#cb892aa959936231728470d4f74032489697fa9d"
321 | integrity sha512-Vb5QMVeLjmOwvvOJuPNg3vnRlffscq2/qvIuTpMzuO/7s5kT+63iL6Dfo2FYLWbzuiycWpbC0/KV0biqFwHxaQ==
322 | dependencies:
323 | glsl-tokenizer "^2.0.0"
324 |
325 | glsl-token-depth@^1.1.0, glsl-token-depth@^1.1.1:
326 | version "1.1.2"
327 | resolved "https://registry.yarnpkg.com/glsl-token-depth/-/glsl-token-depth-1.1.2.tgz#23c5e30ee2bd255884b4a28bc850b8f791e95d84"
328 | integrity sha512-eQnIBLc7vFf8axF9aoi/xW37LSWd2hCQr/3sZui8aBJnksq9C7zMeUYHVJWMhFzXrBU7fgIqni4EhXVW4/krpg==
329 |
330 | glsl-token-descope@^1.0.2:
331 | version "1.0.2"
332 | resolved "https://registry.yarnpkg.com/glsl-token-descope/-/glsl-token-descope-1.0.2.tgz#0fc90ab326186b82f597b2e77dc9e21efcd32076"
333 | integrity sha512-kS2PTWkvi/YOeicVjXGgX5j7+8N7e56srNDEHDTVZ1dcESmbmpmgrnpjPcjxJjMxh56mSXYoFdZqb90gXkGjQw==
334 | dependencies:
335 | glsl-token-assignments "^2.0.0"
336 | glsl-token-depth "^1.1.0"
337 | glsl-token-properties "^1.0.0"
338 | glsl-token-scope "^1.1.0"
339 |
340 | glsl-token-inject-block@^1.0.0:
341 | version "1.1.0"
342 | resolved "https://registry.yarnpkg.com/glsl-token-inject-block/-/glsl-token-inject-block-1.1.0.tgz#e1015f5980c1091824adaa2625f1dfde8bd00034"
343 | integrity sha512-q/m+ukdUBuHCOtLhSr0uFb/qYQr4/oKrPSdIK2C4TD+qLaJvqM9wfXIF/OOBjuSA3pUoYHurVRNao6LTVVUPWA==
344 |
345 | glsl-token-properties@^1.0.0:
346 | version "1.0.1"
347 | resolved "https://registry.yarnpkg.com/glsl-token-properties/-/glsl-token-properties-1.0.1.tgz#483dc3d839f0d4b5c6171d1591f249be53c28a9e"
348 | integrity sha512-dSeW1cOIzbuUoYH0y+nxzwK9S9O3wsjttkq5ij9ZGw0OS41BirKJzzH48VLm8qLg+au6b0sINxGC0IrGwtQUcA==
349 |
350 | glsl-token-scope@^1.1.0, glsl-token-scope@^1.1.1:
351 | version "1.1.2"
352 | resolved "https://registry.yarnpkg.com/glsl-token-scope/-/glsl-token-scope-1.1.2.tgz#a1728e78df24444f9cb93fd18ef0f75503a643b1"
353 | integrity sha512-YKyOMk1B/tz9BwYUdfDoHvMIYTGtVv2vbDSLh94PT4+f87z21FVdou1KNKgF+nECBTo0fJ20dpm0B1vZB1Q03A==
354 |
355 | glsl-token-string@^1.0.1:
356 | version "1.0.1"
357 | resolved "https://registry.yarnpkg.com/glsl-token-string/-/glsl-token-string-1.0.1.tgz#59441d2f857de7c3449c945666021ece358e48ec"
358 | integrity sha512-1mtQ47Uxd47wrovl+T6RshKGkRRCYWhnELmkEcUAPALWGTFe2XZpH3r45XAwL2B6v+l0KNsCnoaZCSnhzKEksg==
359 |
360 | glsl-token-whitespace-trim@^1.0.0:
361 | version "1.0.0"
362 | resolved "https://registry.yarnpkg.com/glsl-token-whitespace-trim/-/glsl-token-whitespace-trim-1.0.0.tgz#46d1dfe98c75bd7d504c05d7d11b1b3e9cc93b10"
363 | integrity sha512-ZJtsPut/aDaUdLUNtmBYhaCmhIjpKNg7IgZSfX5wFReMc2vnj8zok+gB/3Quqs0TsBSX/fGnqUUYZDqyuc2xLQ==
364 |
365 | glsl-tokenizer@^2.0.0, glsl-tokenizer@^2.0.2:
366 | version "2.1.5"
367 | resolved "https://registry.yarnpkg.com/glsl-tokenizer/-/glsl-tokenizer-2.1.5.tgz#1c2e78c16589933c274ba278d0a63b370c5fee1a"
368 | integrity sha512-XSZEJ/i4dmz3Pmbnpsy3cKh7cotvFlBiZnDOwnj/05EwNp2XrhQ4XKJxT7/pDt4kp4YcpRSKz8eTV7S+mwV6MA==
369 | dependencies:
370 | through2 "^0.6.3"
371 |
372 | glslify-bundle@^5.0.0:
373 | version "5.1.1"
374 | resolved "https://registry.yarnpkg.com/glslify-bundle/-/glslify-bundle-5.1.1.tgz#30d2ddf2e6b935bf44d1299321e3b729782c409a"
375 | integrity sha512-plaAOQPv62M1r3OsWf2UbjN0hUYAB7Aph5bfH58VxJZJhloRNbxOL9tl/7H71K7OLJoSJ2ZqWOKk3ttQ6wy24A==
376 | dependencies:
377 | glsl-inject-defines "^1.0.1"
378 | glsl-token-defines "^1.0.0"
379 | glsl-token-depth "^1.1.1"
380 | glsl-token-descope "^1.0.2"
381 | glsl-token-scope "^1.1.1"
382 | glsl-token-string "^1.0.1"
383 | glsl-token-whitespace-trim "^1.0.0"
384 | glsl-tokenizer "^2.0.2"
385 | murmurhash-js "^1.0.0"
386 | shallow-copy "0.0.1"
387 |
388 | glslify-deps@^1.2.5:
389 | version "1.3.2"
390 | resolved "https://registry.yarnpkg.com/glslify-deps/-/glslify-deps-1.3.2.tgz#c09ee945352bfc07ac2d8a1cc9e3de776328c72b"
391 | integrity sha512-7S7IkHWygJRjcawveXQjRXLO2FTjijPDYC7QfZyAQanY+yGLCFHYnPtsGT9bdyHiwPTw/5a1m1M9hamT2aBpag==
392 | dependencies:
393 | "@choojs/findup" "^0.2.0"
394 | events "^3.2.0"
395 | glsl-resolve "0.0.1"
396 | glsl-tokenizer "^2.0.0"
397 | graceful-fs "^4.1.2"
398 | inherits "^2.0.1"
399 | map-limit "0.0.1"
400 | resolve "^1.0.0"
401 |
402 | glslify@^7.1.1:
403 | version "7.1.1"
404 | resolved "https://registry.yarnpkg.com/glslify/-/glslify-7.1.1.tgz#454d9172b410cb49864029c86d5613947fefd30b"
405 | integrity sha512-bud98CJ6kGZcP9Yxcsi7Iz647wuDz3oN+IZsjCRi5X1PI7t/xPKeL0mOwXJjo+CRZMqvq0CkSJiywCcY7kVYog==
406 | dependencies:
407 | bl "^2.2.1"
408 | concat-stream "^1.5.2"
409 | duplexify "^3.4.5"
410 | falafel "^2.1.0"
411 | from2 "^2.3.0"
412 | glsl-resolve "0.0.1"
413 | glsl-token-whitespace-trim "^1.0.0"
414 | glslify-bundle "^5.0.0"
415 | glslify-deps "^1.2.5"
416 | minimist "^1.2.5"
417 | resolve "^1.1.5"
418 | stack-trace "0.0.9"
419 | static-eval "^2.0.5"
420 | through2 "^2.0.1"
421 | xtend "^4.0.0"
422 |
423 | graceful-fs@^4.1.2:
424 | version "4.2.11"
425 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
426 | integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
427 |
428 | gsap@^3.12.2:
429 | version "3.12.2"
430 | resolved "https://registry.yarnpkg.com/gsap/-/gsap-3.12.2.tgz#6e88203eed360761cbf2a2cb3a8d702aa87f3f6d"
431 | integrity sha512-EkYnpG8qHgYBFAwsgsGEqvT1WUidX0tt/ijepx7z8EUJHElykg91RvW1XbkT59T0gZzzszOpjQv7SE41XuIXyQ==
432 |
433 | hasown@^2.0.0:
434 | version "2.0.0"
435 | resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c"
436 | integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==
437 | dependencies:
438 | function-bind "^1.1.2"
439 |
440 | inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3:
441 | version "2.0.4"
442 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
443 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
444 |
445 | is-core-module@^2.13.0:
446 | version "2.13.1"
447 | resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384"
448 | integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==
449 | dependencies:
450 | hasown "^2.0.0"
451 |
452 | isarray@0.0.1:
453 | version "0.0.1"
454 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
455 | integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==
456 |
457 | isarray@^2.0.1:
458 | version "2.0.5"
459 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
460 | integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
461 |
462 | isarray@~1.0.0:
463 | version "1.0.0"
464 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
465 | integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==
466 |
467 | levn@~0.3.0:
468 | version "0.3.0"
469 | resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
470 | integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==
471 | dependencies:
472 | prelude-ls "~1.1.2"
473 | type-check "~0.3.2"
474 |
475 | magic-string@^0.25.7:
476 | version "0.25.9"
477 | resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c"
478 | integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==
479 | dependencies:
480 | sourcemap-codec "^1.4.8"
481 |
482 | map-limit@0.0.1:
483 | version "0.0.1"
484 | resolved "https://registry.yarnpkg.com/map-limit/-/map-limit-0.0.1.tgz#eb7961031c0f0e8d001bf2d56fab685d58822f38"
485 | integrity sha512-pJpcfLPnIF/Sk3taPW21G/RQsEEirGaFpCW3oXRwH9dnFHPHNGjNyvh++rdmC2fNqEaTw2MhYJraoJWAHx8kEg==
486 | dependencies:
487 | once "~1.3.0"
488 |
489 | minimist@^1.2.5:
490 | version "1.2.8"
491 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
492 | integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
493 |
494 | murmurhash-js@^1.0.0:
495 | version "1.0.0"
496 | resolved "https://registry.yarnpkg.com/murmurhash-js/-/murmurhash-js-1.0.0.tgz#b06278e21fc6c37fa5313732b0412bcb6ae15f51"
497 | integrity sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==
498 |
499 | n8ao@^1.7.0:
500 | version "1.7.0"
501 | resolved "https://registry.yarnpkg.com/n8ao/-/n8ao-1.7.0.tgz#43b42d66f3bb2333522d7fb8d8c6750ea5e8a32b"
502 | integrity sha512-0Ne+dnzlKByj4UR+OfPU04CanmbNPPtYcqJqWWcPw00CiMOLhkE23/gwoROLACKMRLuWsqhW2cMf5pYlywrIAQ==
503 |
504 | nanoid@^3.3.6:
505 | version "3.3.7"
506 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
507 | integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
508 |
509 | once@^1.4.0:
510 | version "1.4.0"
511 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
512 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
513 | dependencies:
514 | wrappy "1"
515 |
516 | once@~1.3.0:
517 | version "1.3.3"
518 | resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20"
519 | integrity sha512-6vaNInhu+CHxtONf3zw3vq4SP2DOQhjBvIa3rNcG0+P7eKWlYH6Peu7rHizSloRU2EwMz6GraLieis9Ac9+p1w==
520 | dependencies:
521 | wrappy "1"
522 |
523 | optionator@^0.8.1:
524 | version "0.8.3"
525 | resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495"
526 | integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==
527 | dependencies:
528 | deep-is "~0.1.3"
529 | fast-levenshtein "~2.0.6"
530 | levn "~0.3.0"
531 | prelude-ls "~1.1.2"
532 | type-check "~0.3.2"
533 | word-wrap "~1.2.3"
534 |
535 | path-parse@^1.0.7:
536 | version "1.0.7"
537 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
538 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
539 |
540 | picocolors@^1.0.0:
541 | version "1.0.0"
542 | resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
543 | integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
544 |
545 | picomatch@^2.2.2:
546 | version "2.3.1"
547 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
548 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
549 |
550 | postcss@^8.4.27:
551 | version "8.4.31"
552 | resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d"
553 | integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==
554 | dependencies:
555 | nanoid "^3.3.6"
556 | picocolors "^1.0.0"
557 | source-map-js "^1.0.2"
558 |
559 | postprocessing@^6.33.3:
560 | version "6.33.3"
561 | resolved "https://registry.yarnpkg.com/postprocessing/-/postprocessing-6.33.3.tgz#d80103f6e68581263557aa2e5d9e26af3e0d7cfd"
562 | integrity sha512-zQAVvcMf7bfeggQNQeVErD/UFd1XHBi2X6+yxwIv9PjhGCLAYKue3UuzVyu95O7ZUvkDwF0TyTzKdxoaVwYi7w==
563 |
564 | prelude-ls@~1.1.2:
565 | version "1.1.2"
566 | resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
567 | integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==
568 |
569 | process-nextick-args@~2.0.0:
570 | version "2.0.1"
571 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
572 | integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
573 |
574 | "readable-stream@>=1.0.33-1 <1.1.0-0":
575 | version "1.0.34"
576 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
577 | integrity sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==
578 | dependencies:
579 | core-util-is "~1.0.0"
580 | inherits "~2.0.1"
581 | isarray "0.0.1"
582 | string_decoder "~0.10.x"
583 |
584 | readable-stream@^2.0.0, readable-stream@^2.2.2, readable-stream@^2.3.5, readable-stream@~2.3.6:
585 | version "2.3.8"
586 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b"
587 | integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
588 | dependencies:
589 | core-util-is "~1.0.0"
590 | inherits "~2.0.3"
591 | isarray "~1.0.0"
592 | process-nextick-args "~2.0.0"
593 | safe-buffer "~5.1.1"
594 | string_decoder "~1.1.1"
595 | util-deprecate "~1.0.1"
596 |
597 | resolve@^0.6.1:
598 | version "0.6.3"
599 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-0.6.3.tgz#dd957982e7e736debdf53b58a4dd91754575dd46"
600 | integrity sha512-UHBY3viPlJKf85YijDUcikKX6tmF4SokIDp518ZDVT92JNDcG5uKIthaT/owt3Sar0lwtOafsQuwrg22/v2Dwg==
601 |
602 | resolve@^1.0.0, resolve@^1.1.5:
603 | version "1.22.8"
604 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
605 | integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
606 | dependencies:
607 | is-core-module "^2.13.0"
608 | path-parse "^1.0.7"
609 | supports-preserve-symlinks-flag "^1.0.0"
610 |
611 | rollup@^3.27.1:
612 | version "3.29.4"
613 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.4.tgz#4d70c0f9834146df8705bfb69a9a19c9e1109981"
614 | integrity sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==
615 | optionalDependencies:
616 | fsevents "~2.3.2"
617 |
618 | safe-buffer@^5.1.1:
619 | version "5.2.1"
620 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
621 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
622 |
623 | safe-buffer@~5.1.0, safe-buffer@~5.1.1:
624 | version "5.1.2"
625 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
626 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
627 |
628 | shallow-copy@0.0.1:
629 | version "0.0.1"
630 | resolved "https://registry.yarnpkg.com/shallow-copy/-/shallow-copy-0.0.1.tgz#415f42702d73d810330292cc5ee86eae1a11a170"
631 | integrity sha512-b6i4ZpVuUxB9h5gfCxPiusKYkqTMOjEbBs4wMaFbkfia4yFv92UKZ6Df8WXcKbn08JNL/abvg3FnMAOfakDvUw==
632 |
633 | source-map-js@^1.0.2:
634 | version "1.0.2"
635 | resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
636 | integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
637 |
638 | source-map@~0.6.1:
639 | version "0.6.1"
640 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
641 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
642 |
643 | sourcemap-codec@^1.4.8:
644 | version "1.4.8"
645 | resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
646 | integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
647 |
648 | stack-trace@0.0.9:
649 | version "0.0.9"
650 | resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.9.tgz#a8f6eaeca90674c333e7c43953f275b451510695"
651 | integrity sha512-vjUc6sfgtgY0dxCdnc40mK6Oftjo9+2K8H/NG81TMhgL392FtiPA9tn9RLyTxXmTLPJPjF3VyzFp6bsWFLisMQ==
652 |
653 | static-eval@^2.0.5:
654 | version "2.1.0"
655 | resolved "https://registry.yarnpkg.com/static-eval/-/static-eval-2.1.0.tgz#a16dbe54522d7fa5ef1389129d813fd47b148014"
656 | integrity sha512-agtxZ/kWSsCkI5E4QifRwsaPs0P0JmZV6dkLz6ILYfFYQGn+5plctanRN+IC8dJRiFkyXHrwEE3W9Wmx67uDbw==
657 | dependencies:
658 | escodegen "^1.11.1"
659 |
660 | stats-js@^1.0.1:
661 | version "1.0.1"
662 | resolved "https://registry.yarnpkg.com/stats-js/-/stats-js-1.0.1.tgz#377c36490c1935b9a4e68bf3acc3afeb59878f66"
663 | integrity sha512-EAwEFghGNv8mlYC4CZzI5kWghsnP8uBKXw6VLRHtXkOk5xySfUKLTqTkjgJFfDluIkf/O7eZwi5MXP50VeTbUg==
664 |
665 | stream-shift@^1.0.0:
666 | version "1.0.1"
667 | resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
668 | integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==
669 |
670 | string_decoder@~0.10.x:
671 | version "0.10.31"
672 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
673 | integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==
674 |
675 | string_decoder@~1.1.1:
676 | version "1.1.1"
677 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
678 | integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
679 | dependencies:
680 | safe-buffer "~5.1.0"
681 |
682 | supports-preserve-symlinks-flag@^1.0.0:
683 | version "1.0.0"
684 | resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
685 | integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
686 |
687 | three@^0.155.0:
688 | version "0.155.0"
689 | resolved "https://registry.yarnpkg.com/three/-/three-0.155.0.tgz#cca9b8ad817830c8b4fdd8f0d9a12a2e413a2672"
690 | integrity sha512-sNgCYmDijnIqkD/bMfk+1pHg3YzsxW7V2ChpuP6HCQ8NiZr3RufsXQr8M3SSUMjW4hG+sUk7YbyuY0DncaDTJQ==
691 |
692 | through2@^0.6.3:
693 | version "0.6.5"
694 | resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48"
695 | integrity sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg==
696 | dependencies:
697 | readable-stream ">=1.0.33-1 <1.1.0-0"
698 | xtend ">=4.0.0 <4.1.0-0"
699 |
700 | through2@^2.0.1:
701 | version "2.0.5"
702 | resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd"
703 | integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==
704 | dependencies:
705 | readable-stream "~2.3.6"
706 | xtend "~4.0.1"
707 |
708 | type-check@~0.3.2:
709 | version "0.3.2"
710 | resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
711 | integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==
712 | dependencies:
713 | prelude-ls "~1.1.2"
714 |
715 | typedarray@^0.0.6:
716 | version "0.0.6"
717 | resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
718 | integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==
719 |
720 | util-deprecate@~1.0.1:
721 | version "1.0.2"
722 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
723 | integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
724 |
725 | vite-plugin-glslify@^2.0.2:
726 | version "2.0.2"
727 | resolved "https://registry.yarnpkg.com/vite-plugin-glslify/-/vite-plugin-glslify-2.0.2.tgz#d04c7a960a19f015c0a91c238382131a45037eab"
728 | integrity sha512-b91F5PFkmYA21gSJF8iws4RvY1WbmJl9ewuAX/zm0JKV2vzAP8l2LzgRBbNVG96e0BDczJqFLNBG9A0dYALZyg==
729 | dependencies:
730 | "@rollup/pluginutils" "^4.1.1"
731 | astring "^1.7.5"
732 | glslify "^7.1.1"
733 | magic-string "^0.25.7"
734 |
735 | vite@^4.4.5:
736 | version "4.5.0"
737 | resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.0.tgz#ec406295b4167ac3bc23e26f9c8ff559287cff26"
738 | integrity sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==
739 | dependencies:
740 | esbuild "^0.18.10"
741 | postcss "^8.4.27"
742 | rollup "^3.27.1"
743 | optionalDependencies:
744 | fsevents "~2.3.2"
745 |
746 | word-wrap@~1.2.3:
747 | version "1.2.5"
748 | resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34"
749 | integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
750 |
751 | wrappy@1:
752 | version "1.0.2"
753 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
754 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
755 |
756 | "xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.1:
757 | version "4.0.2"
758 | resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
759 | integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
760 |
761 | xtend@^2.1.2:
762 | version "2.2.0"
763 | resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.2.0.tgz#eef6b1f198c1c8deafad8b1765a04dad4a01c5a9"
764 | integrity sha512-SLt5uylT+4aoXxXuwtQp5ZnMMzhDb1Xkg4pEqc00WUJCQifPfV9Ub1VrNhp9kXkrjZD2I2Hl8WnjP37jzZLPZw==
765 |
--------------------------------------------------------------------------------