tela.js 1.0.0

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.
Files changed (178) hide show
  1. package/.eslintrc.yml +8 -0
  2. package/LICENSE +201 -0
  3. package/README.md +54 -0
  4. package/assets/bunny.obj +7474 -0
  5. package/assets/expand.svg +1 -0
  6. package/assets/great.jpg +0 -0
  7. package/assets/kakashi.jpg +0 -0
  8. package/assets/spot.obj +11999 -0
  9. package/assets/spot.png +0 -0
  10. package/assets/torus.obj +3137 -0
  11. package/assets/x.svg +1 -0
  12. package/bun.lockb +0 -0
  13. package/bundle.js +39 -0
  14. package/dist/node/index.js +37048 -0
  15. package/dist/web/index.js +1511 -0
  16. package/index.css +129 -0
  17. package/index.html +19 -0
  18. package/index.js +534 -0
  19. package/package.json +40 -0
  20. package/src/Animation/Animation.js +61 -0
  21. package/src/Box/Box.js +105 -0
  22. package/src/Camera/Camera.js +133 -0
  23. package/src/Canvas/Canvas.js +203 -0
  24. package/src/Canvas/README.md +83 -0
  25. package/src/Color/Color.js +77 -0
  26. package/src/DomBuilder/DomBuilder.js +126 -0
  27. package/src/IO/IO.js +120 -0
  28. package/src/Image/Image.js +138 -0
  29. package/src/Image/README.md +33 -0
  30. package/src/Monads/Monads.js +28 -0
  31. package/src/Ray/Ray.js +7 -0
  32. package/src/Scene/Mesh.js +103 -0
  33. package/src/Scene/NaiveScene.js +77 -0
  34. package/src/Scene/Point.js +109 -0
  35. package/src/Scene/PointCloud.js +51 -0
  36. package/src/Scene/Scene.js +200 -0
  37. package/src/Stream/Stream.js +10 -0
  38. package/src/Utils/Constants.js +1 -0
  39. package/src/Utils/Math.js +65 -0
  40. package/src/Utils/Utils.js +39 -0
  41. package/src/Vector/Vector.js +495 -0
  42. package/src/index.js +32 -0
  43. package/src/index.node.js +5 -0
  44. package/test/node/amazing_shader.js +56 -0
  45. package/test/node/bunny.js +55 -0
  46. package/test/node/bunny_parallel.js +102 -0
  47. package/test/node/image2rgb.js +57 -0
  48. package/test/node/image_test.js +38 -0
  49. package/test/node/lorentz.js +0 -0
  50. package/test/web/amazing_shader.js +60 -0
  51. package/test/web/amazing_shader_2.js +54 -0
  52. package/test/web/bunny.js +72 -0
  53. package/test/web/image2rgb.js +77 -0
  54. package/test/web/interactive_wave.js +108 -0
  55. package/test/web/lorenz.js +60 -0
  56. package/test/web/mandelbrot.js +59 -0
  57. package/test/web/rotating_grid.js +62 -0
  58. package/test/web/signed_bunny.js +139 -0
  59. package/test/web/signed_distance.js +95 -0
  60. package/test/web/simple_animation.js +39 -0
  61. package/test/web/simple_shader.js +14 -0
  62. package/test/web/six_spheres.js +102 -0
  63. package/test/web/wave_equation.js +93 -0
  64. package/vs-monaco/package/LICENSE +21 -0
  65. package/vs-monaco/package/ThirdPartyNotices.txt +448 -0
  66. package/vs-monaco/package/min/vs/base/browser/ui/codicons/codicon/codicon.ttf +0 -0
  67. package/vs-monaco/package/min/vs/base/common/worker/simpleWorker.nls.de.js +8 -0
  68. package/vs-monaco/package/min/vs/base/common/worker/simpleWorker.nls.es.js +8 -0
  69. package/vs-monaco/package/min/vs/base/common/worker/simpleWorker.nls.fr.js +8 -0
  70. package/vs-monaco/package/min/vs/base/common/worker/simpleWorker.nls.it.js +8 -0
  71. package/vs-monaco/package/min/vs/base/common/worker/simpleWorker.nls.ja.js +8 -0
  72. package/vs-monaco/package/min/vs/base/common/worker/simpleWorker.nls.js +8 -0
  73. package/vs-monaco/package/min/vs/base/common/worker/simpleWorker.nls.ko.js +8 -0
  74. package/vs-monaco/package/min/vs/base/common/worker/simpleWorker.nls.ru.js +8 -0
  75. package/vs-monaco/package/min/vs/base/common/worker/simpleWorker.nls.zh-cn.js +8 -0
  76. package/vs-monaco/package/min/vs/base/common/worker/simpleWorker.nls.zh-tw.js +8 -0
  77. package/vs-monaco/package/min/vs/base/worker/workerMain.js +27 -0
  78. package/vs-monaco/package/min/vs/basic-languages/abap/abap.js +10 -0
  79. package/vs-monaco/package/min/vs/basic-languages/apex/apex.js +10 -0
  80. package/vs-monaco/package/min/vs/basic-languages/azcli/azcli.js +10 -0
  81. package/vs-monaco/package/min/vs/basic-languages/bat/bat.js +10 -0
  82. package/vs-monaco/package/min/vs/basic-languages/bicep/bicep.js +11 -0
  83. package/vs-monaco/package/min/vs/basic-languages/cameligo/cameligo.js +10 -0
  84. package/vs-monaco/package/min/vs/basic-languages/clojure/clojure.js +10 -0
  85. package/vs-monaco/package/min/vs/basic-languages/coffee/coffee.js +10 -0
  86. package/vs-monaco/package/min/vs/basic-languages/cpp/cpp.js +10 -0
  87. package/vs-monaco/package/min/vs/basic-languages/csharp/csharp.js +10 -0
  88. package/vs-monaco/package/min/vs/basic-languages/csp/csp.js +10 -0
  89. package/vs-monaco/package/min/vs/basic-languages/css/css.js +12 -0
  90. package/vs-monaco/package/min/vs/basic-languages/cypher/cypher.js +10 -0
  91. package/vs-monaco/package/min/vs/basic-languages/dart/dart.js +10 -0
  92. package/vs-monaco/package/min/vs/basic-languages/dockerfile/dockerfile.js +10 -0
  93. package/vs-monaco/package/min/vs/basic-languages/ecl/ecl.js +10 -0
  94. package/vs-monaco/package/min/vs/basic-languages/elixir/elixir.js +10 -0
  95. package/vs-monaco/package/min/vs/basic-languages/flow9/flow9.js +10 -0
  96. package/vs-monaco/package/min/vs/basic-languages/freemarker2/freemarker2.js +12 -0
  97. package/vs-monaco/package/min/vs/basic-languages/fsharp/fsharp.js +10 -0
  98. package/vs-monaco/package/min/vs/basic-languages/go/go.js +10 -0
  99. package/vs-monaco/package/min/vs/basic-languages/graphql/graphql.js +10 -0
  100. package/vs-monaco/package/min/vs/basic-languages/handlebars/handlebars.js +10 -0
  101. package/vs-monaco/package/min/vs/basic-languages/hcl/hcl.js +10 -0
  102. package/vs-monaco/package/min/vs/basic-languages/html/html.js +10 -0
  103. package/vs-monaco/package/min/vs/basic-languages/ini/ini.js +10 -0
  104. package/vs-monaco/package/min/vs/basic-languages/java/java.js +10 -0
  105. package/vs-monaco/package/min/vs/basic-languages/javascript/javascript.js +10 -0
  106. package/vs-monaco/package/min/vs/basic-languages/julia/julia.js +10 -0
  107. package/vs-monaco/package/min/vs/basic-languages/kotlin/kotlin.js +10 -0
  108. package/vs-monaco/package/min/vs/basic-languages/less/less.js +11 -0
  109. package/vs-monaco/package/min/vs/basic-languages/lexon/lexon.js +10 -0
  110. package/vs-monaco/package/min/vs/basic-languages/liquid/liquid.js +10 -0
  111. package/vs-monaco/package/min/vs/basic-languages/lua/lua.js +10 -0
  112. package/vs-monaco/package/min/vs/basic-languages/m3/m3.js +10 -0
  113. package/vs-monaco/package/min/vs/basic-languages/markdown/markdown.js +10 -0
  114. package/vs-monaco/package/min/vs/basic-languages/mdx/mdx.js +10 -0
  115. package/vs-monaco/package/min/vs/basic-languages/mips/mips.js +10 -0
  116. package/vs-monaco/package/min/vs/basic-languages/msdax/msdax.js +10 -0
  117. package/vs-monaco/package/min/vs/basic-languages/mysql/mysql.js +10 -0
  118. package/vs-monaco/package/min/vs/basic-languages/objective-c/objective-c.js +10 -0
  119. package/vs-monaco/package/min/vs/basic-languages/pascal/pascal.js +10 -0
  120. package/vs-monaco/package/min/vs/basic-languages/pascaligo/pascaligo.js +10 -0
  121. package/vs-monaco/package/min/vs/basic-languages/perl/perl.js +10 -0
  122. package/vs-monaco/package/min/vs/basic-languages/pgsql/pgsql.js +10 -0
  123. package/vs-monaco/package/min/vs/basic-languages/php/php.js +10 -0
  124. package/vs-monaco/package/min/vs/basic-languages/pla/pla.js +10 -0
  125. package/vs-monaco/package/min/vs/basic-languages/postiats/postiats.js +10 -0
  126. package/vs-monaco/package/min/vs/basic-languages/powerquery/powerquery.js +10 -0
  127. package/vs-monaco/package/min/vs/basic-languages/powershell/powershell.js +10 -0
  128. package/vs-monaco/package/min/vs/basic-languages/protobuf/protobuf.js +11 -0
  129. package/vs-monaco/package/min/vs/basic-languages/pug/pug.js +10 -0
  130. package/vs-monaco/package/min/vs/basic-languages/python/python.js +10 -0
  131. package/vs-monaco/package/min/vs/basic-languages/qsharp/qsharp.js +10 -0
  132. package/vs-monaco/package/min/vs/basic-languages/r/r.js +10 -0
  133. package/vs-monaco/package/min/vs/basic-languages/razor/razor.js +10 -0
  134. package/vs-monaco/package/min/vs/basic-languages/redis/redis.js +10 -0
  135. package/vs-monaco/package/min/vs/basic-languages/redshift/redshift.js +10 -0
  136. package/vs-monaco/package/min/vs/basic-languages/restructuredtext/restructuredtext.js +10 -0
  137. package/vs-monaco/package/min/vs/basic-languages/ruby/ruby.js +10 -0
  138. package/vs-monaco/package/min/vs/basic-languages/rust/rust.js +10 -0
  139. package/vs-monaco/package/min/vs/basic-languages/sb/sb.js +10 -0
  140. package/vs-monaco/package/min/vs/basic-languages/scala/scala.js +10 -0
  141. package/vs-monaco/package/min/vs/basic-languages/scheme/scheme.js +10 -0
  142. package/vs-monaco/package/min/vs/basic-languages/scss/scss.js +12 -0
  143. package/vs-monaco/package/min/vs/basic-languages/shell/shell.js +10 -0
  144. package/vs-monaco/package/min/vs/basic-languages/solidity/solidity.js +10 -0
  145. package/vs-monaco/package/min/vs/basic-languages/sophia/sophia.js +10 -0
  146. package/vs-monaco/package/min/vs/basic-languages/sparql/sparql.js +10 -0
  147. package/vs-monaco/package/min/vs/basic-languages/sql/sql.js +10 -0
  148. package/vs-monaco/package/min/vs/basic-languages/st/st.js +10 -0
  149. package/vs-monaco/package/min/vs/basic-languages/swift/swift.js +13 -0
  150. package/vs-monaco/package/min/vs/basic-languages/systemverilog/systemverilog.js +10 -0
  151. package/vs-monaco/package/min/vs/basic-languages/tcl/tcl.js +10 -0
  152. package/vs-monaco/package/min/vs/basic-languages/twig/twig.js +10 -0
  153. package/vs-monaco/package/min/vs/basic-languages/typescript/typescript.js +10 -0
  154. package/vs-monaco/package/min/vs/basic-languages/vb/vb.js +10 -0
  155. package/vs-monaco/package/min/vs/basic-languages/wgsl/wgsl.js +307 -0
  156. package/vs-monaco/package/min/vs/basic-languages/xml/xml.js +10 -0
  157. package/vs-monaco/package/min/vs/basic-languages/yaml/yaml.js +10 -0
  158. package/vs-monaco/package/min/vs/editor/editor.main.css +6 -0
  159. package/vs-monaco/package/min/vs/editor/editor.main.js +745 -0
  160. package/vs-monaco/package/min/vs/editor/editor.main.nls.de.js +31 -0
  161. package/vs-monaco/package/min/vs/editor/editor.main.nls.es.js +31 -0
  162. package/vs-monaco/package/min/vs/editor/editor.main.nls.fr.js +29 -0
  163. package/vs-monaco/package/min/vs/editor/editor.main.nls.it.js +29 -0
  164. package/vs-monaco/package/min/vs/editor/editor.main.nls.ja.js +31 -0
  165. package/vs-monaco/package/min/vs/editor/editor.main.nls.js +29 -0
  166. package/vs-monaco/package/min/vs/editor/editor.main.nls.ko.js +29 -0
  167. package/vs-monaco/package/min/vs/editor/editor.main.nls.ru.js +31 -0
  168. package/vs-monaco/package/min/vs/editor/editor.main.nls.zh-cn.js +31 -0
  169. package/vs-monaco/package/min/vs/editor/editor.main.nls.zh-tw.js +29 -0
  170. package/vs-monaco/package/min/vs/language/css/cssMode.js +13 -0
  171. package/vs-monaco/package/min/vs/language/css/cssWorker.js +81 -0
  172. package/vs-monaco/package/min/vs/language/html/htmlMode.js +13 -0
  173. package/vs-monaco/package/min/vs/language/html/htmlWorker.js +453 -0
  174. package/vs-monaco/package/min/vs/language/json/jsonMode.js +15 -0
  175. package/vs-monaco/package/min/vs/language/json/jsonWorker.js +36 -0
  176. package/vs-monaco/package/min/vs/language/typescript/tsMode.js +20 -0
  177. package/vs-monaco/package/min/vs/language/typescript/tsWorker.js +37016 -0
  178. package/vs-monaco/package/min/vs/loader.js +11 -0
package/index.css ADDED
@@ -0,0 +1,129 @@
1
+ /* Normal screens */
2
+ :root {
3
+ --primary-color: rgb(52, 152, 219);
4
+ --secondary-color: rgb(231, 76, 60);
5
+ --tertiary-color: rgb(60, 231, 63);
6
+ --background-color: rgb(24, 24, 24);
7
+ --background-color-light: rgb(255, 255, 255);
8
+ --text-color: rgba(255, 255, 255, 0.9);
9
+ --text-color-light: rgba(24, 24, 24, 0.9);
10
+ --fast-transition: 0.3s;
11
+ --faster-transition: 0.1s;
12
+ }
13
+
14
+ /* GENERAL */
15
+
16
+ html {
17
+ scroll-behavior: smooth;
18
+ height: 100vh;
19
+ width: 100vw;
20
+ }
21
+
22
+ body {
23
+ background-color: var(--background-color);
24
+ color: var(--text-color);
25
+ font-size: 1.25rem;
26
+ font-weight: 400;
27
+ overflow-x: hidden;
28
+ font-family: Arial, Helvetica, sans-serif;
29
+ }
30
+
31
+ main {
32
+ height: inherit;
33
+ }
34
+
35
+ select {
36
+ border-radius: 0.25rem;
37
+ padding: 0.25rem
38
+ }
39
+
40
+ dialog {
41
+ border-radius: 0.5rem;
42
+ background-color: var(--background-color);
43
+ color: var(--text-color);
44
+ }
45
+
46
+ dialog button {
47
+ border: none;
48
+ background: inherit;
49
+ color: inherit;
50
+ width: 2.5rem;
51
+ transition: all 0.25s ease-in-out;
52
+ }
53
+
54
+ /* IDS */
55
+
56
+ #root {
57
+ opacity: 0.1;
58
+ transition: opacity var(--fast-transition) ease-in-out;
59
+ margin-left: auto;
60
+ margin-right: auto;
61
+ height: 100%;
62
+ width: 100%;
63
+ min-width: 333px;
64
+ }
65
+
66
+ #root.loaded {
67
+ opacity: 1;
68
+ }
69
+
70
+ /* Classes */
71
+
72
+ .divider {
73
+ background-color: #151515;
74
+ cursor: ew-resize;
75
+ width: 10px;
76
+ }
77
+
78
+ .monaco-line-error {
79
+ /* Make sure to use transparent colors for the selection to work */
80
+ background: rgba(255, 0, 0, 0.25);
81
+ }
82
+
83
+ /* Utils */
84
+
85
+ .y-overflow {
86
+ overflow-y: auto;
87
+ }
88
+
89
+ .x-overflow {
90
+ overflow-x: auto;
91
+ }
92
+
93
+ .flex {
94
+ display: flex;
95
+ }
96
+
97
+ .column {
98
+ flex-direction: column;
99
+ }
100
+
101
+ .row {
102
+ flex-direction: row;
103
+ }
104
+
105
+ .wrap {
106
+ flex-wrap: wrap;
107
+ }
108
+
109
+ .spaced-items {
110
+ justify-content: space-evenly;
111
+ }
112
+
113
+ .center {
114
+ text-align: center;
115
+ }
116
+
117
+ .margin {
118
+ margin: auto;
119
+ }
120
+
121
+ .grow {
122
+ flex-grow: 1;
123
+ }
124
+
125
+ .smooth-border {
126
+ border-radius: 0.25rem;
127
+ }
128
+ /* Small screens */
129
+ @media (max-width: 800px) {}
package/index.html ADDED
@@ -0,0 +1,19 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Tela.js Playground</title>
8
+ <link rel="stylesheet" href="./index.css">
9
+ </head>
10
+
11
+ <body>
12
+ <div id="root">
13
+ <!-- Elements to be injected here -->
14
+ </div>
15
+ </body>
16
+ <script src="./vs-monaco/package/min/vs/loader.js"></script>
17
+ <script type="module" src="./index.js"></script>
18
+
19
+ </html>
package/index.js ADDED
@@ -0,0 +1,534 @@
1
+ const isGithub = window.location.host === "pedroth.github.io";
2
+ const SOURCE = isGithub ? "/tela.js" : ""
3
+ // eslint-disable-next-line no-unused-vars
4
+ const { DOM, Monads } = await import(SOURCE + "/dist/web/index.js")
5
+ const { some, none, maybe } = Monads;
6
+ //========================================================================================
7
+ /* *
8
+ * UTILS *
9
+ * */
10
+ //========================================================================================
11
+ function toggleFullScreen(elem) {
12
+ if (!document.fullscreenElement && // alternative standard method
13
+ !document.mozFullScreenElement &&
14
+ !document.webkitFullscreenElement &&
15
+ !document.msFullscreenElement) { // current working methods
16
+ if (elem.requestFullscreen) {
17
+ elem.requestFullscreen();
18
+ } else if (elem.msRequestFullscreen) {
19
+ elem.msRequestFullscreen();
20
+ } else if (elem.mozRequestFullScreen) {
21
+ elem.mozRequestFullScreen();
22
+ } else if (elem.webkitRequestFullscreen) {
23
+ elem.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
24
+ }
25
+ }
26
+ }
27
+
28
+ const MAGIC_CODE_LINE_NUMBER_OFFSET = toggleFullScreen.toString().split("\n").length + 25;
29
+
30
+ async function svg(url) {
31
+ const data = await fetch(SOURCE + url);
32
+ return await data.text();
33
+ }
34
+
35
+ function debounce(lambda, debounceTimeInMillis = 500) {
36
+ let timerId;
37
+ return function (...vars) {
38
+ if (timerId) {
39
+ clearTimeout(timerId);
40
+ }
41
+ timerId = setTimeout(() => {
42
+ lambda(...vars);
43
+ }, debounceTimeInMillis);
44
+ return true;
45
+ };
46
+ }
47
+
48
+ const TelaLocalStorage = (() => {
49
+ const namespace = "tela.js";
50
+ return {
51
+ getItem: key => {
52
+ const ls = localStorage.getItem(namespace);
53
+ return !ls ? ls : JSON.parse(ls)[key];
54
+ },
55
+ setItem: (key, value) => {
56
+ const ls = JSON.parse(localStorage.getItem(namespace)) || {};
57
+ ls[key] = value;
58
+ localStorage.setItem(namespace, JSON.stringify(ls));
59
+ return this;
60
+ }
61
+ };
62
+ })();
63
+
64
+ let modal = undefined;
65
+ // eslint-disable-next-line no-unused-vars
66
+ function modalAlert(title, message) {
67
+ if (!modal) {
68
+ modal = DOM.of("dialog").style("position: relative");
69
+ document.body.appendChild(modal.build());
70
+ }
71
+ modal.removeChildren();
72
+ modal.appendChild(
73
+ DOM.of("button")
74
+ .style("position: absolute; top: 0; right: 0; margin: 0.5rem")
75
+ .inner(svg("/assets/x.svg"))
76
+ .event("click", () => modal.element.close()),
77
+ DOM.of("h2").inner(title),
78
+ DOM.of("p").inner(message)
79
+ )
80
+ modal.element.showModal()
81
+ }
82
+
83
+ function printErrorInCode(errorMessage, lineNumber) {
84
+ lineNumber = lineNumber - MAGIC_CODE_LINE_NUMBER_OFFSET;
85
+ const decorations = AppState.editor.map(editor => {
86
+ return editor.createDecorationsCollection([
87
+ {
88
+ // eslint-disable-next-line no-undef
89
+ range: new monaco.Range(lineNumber, 1, lineNumber, 1),
90
+ options: {
91
+ isWholeLine: true,
92
+ className: 'monaco-line-error',
93
+ hoverMessage: {
94
+ value: errorMessage,
95
+ isTrusted: true
96
+ }
97
+ }
98
+ },
99
+ ]);
100
+ })
101
+ .orElse({ clear: () => { } });
102
+ return decorations;
103
+ }
104
+
105
+ //========================================================================================
106
+ /* *
107
+ * UI *
108
+ * */
109
+ //========================================================================================
110
+
111
+ const getIframeDefaultBody = () => `
112
+ <style>
113
+ :root {
114
+ --primary-color: rgb(52, 152, 219);
115
+ --secondary-color: rgb(231, 76, 60);
116
+ --tertiary-color: rgb(60, 231, 63);
117
+ --background-color: rgb(24, 24, 24);
118
+ --background-color-light: rgb(255, 255, 255);
119
+ --text-color: rgba(255, 255, 255, 0.9);
120
+ --text-color-light: rgba(24, 24, 24, 0.9);
121
+ --fast-transition: 0.3s;
122
+ --faster-transition: 0.1s;
123
+ }
124
+
125
+ /* GENERAL */
126
+
127
+ html {
128
+ scroll-behavior: smooth;
129
+ height: 100vh;
130
+ width: 100vw;
131
+ }
132
+
133
+ body {
134
+ background-color: var(--background-color);
135
+ color: var(--text-color);
136
+ font-size: 1.25rem;
137
+ font-weight: 400;
138
+ overflow-x: hidden;
139
+ font-family: Arial, Helvetica, sans-serif;
140
+ }
141
+
142
+ #root {
143
+ display: flex;
144
+ flex-direction:column;
145
+ }
146
+
147
+ #canvasContainer {
148
+ margin: auto;
149
+ display: flex;
150
+ width: 73%;
151
+ }
152
+
153
+ #canvas {
154
+ flex-grow: 1;
155
+ }
156
+
157
+ #logger {
158
+ background-color: rgba(0,0,0, 0.75);
159
+ border-radius: 0.25rem;
160
+ max-height: 10rem;
161
+ overflow-y: auto;
162
+ width: 73%;
163
+ margin: 1rem auto;
164
+ }
165
+
166
+ #expandButton {
167
+ position: absolute;
168
+ bottom: 25px;
169
+ right: 25px;
170
+ color: white;
171
+ }
172
+
173
+ #expandButton svg {
174
+ height: 1.5rem;
175
+ width: 1.5rem;
176
+ cursor:pointer;
177
+ transition: all 0.1s ease-in-out;
178
+ }
179
+
180
+ #expandButton svg:hover {
181
+ transform: scale(1.5);
182
+ }
183
+ </style>
184
+ <div id="root">
185
+ <div id="canvasContainer">
186
+ <div id="expandButton">
187
+ <svg xmlns="http://www.w3.org/2000/svg" height="16" width="14" fill="currentColor" viewBox="0 0 448 512"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d="M32 32C14.3 32 0 46.3 0 64v96c0 17.7 14.3 32 32 32s32-14.3 32-32V96h64c17.7 0 32-14.3 32-32s-14.3-32-32-32H32zM64 352c0-17.7-14.3-32-32-32s-32 14.3-32 32v96c0 17.7 14.3 32 32 32h96c17.7 0 32-14.3 32-32s-14.3-32-32-32H64V352zM320 32c-17.7 0-32 14.3-32 32s14.3 32 32 32h64v64c0 17.7 14.3 32 32 32s32-14.3 32-32V64c0-17.7-14.3-32-32-32H320zM448 352c0-17.7-14.3-32-32-32s-32 14.3-32 32v64H320c-17.7 0-32 14.3-32 32s14.3 32 32 32h96c17.7 0 32-14.3 32-32V352z"/></svg>
188
+ </div>
189
+ <canvas id="canvas"></canvas>
190
+ </div>
191
+ <p id="logger"></p>
192
+ </div>
193
+ `;
194
+
195
+ function exampleSelector() {
196
+ const select = DOM.of("select")
197
+ .attr("title", "Examples")
198
+ .appendChild(...examples.map(({ title, path }) => {
199
+ const option = DOM.of("option")
200
+ .attr("value", path)
201
+ .attr("key", title)
202
+ .inner(title)
203
+ if (getSelectedExample() === title) option.attr("selected", "")
204
+ return option;
205
+ }));
206
+ select.event("change", ({ target: selectElem }) => {
207
+ const index = selectElem.selectedIndex;
208
+ const examplePath = selectElem.options[index].value;
209
+ const selectedExample = selectElem.options[index].text;
210
+ TelaLocalStorage.setItem("selectedExample", selectedExample);
211
+ AppState.editor.forEach(async editor => {
212
+ const exampleTxt = await getExampleFromPath(examplePath);
213
+ editor.setValue(exampleTxt)
214
+ })
215
+ });
216
+ return DOM.of("div")
217
+ .addClass("margin flex")
218
+ .style("margin-bottom: 0.25rem")
219
+ .appendChild(
220
+ DOM.of("span")
221
+ .style("margin-right: 0.5rem")
222
+ .inner("Example:"),
223
+ select
224
+ )
225
+ }
226
+
227
+ function headerTools() {
228
+ return DOM.of("div")
229
+ .appendChild(
230
+ exampleSelector(),
231
+ );
232
+ }
233
+
234
+ function header() {
235
+ return DOM.of("header")
236
+ .appendChild(
237
+ DOM.of("h2").inner("Tela.js playground"),
238
+ headerTools()
239
+ )
240
+ }
241
+
242
+ async function input() {
243
+ const container = DOM.of("div");
244
+ // eslint-disable-next-line no-undef
245
+ require.config({ paths: { vs: './vs-monaco/package/min/vs' } });
246
+ const editor = await new Promise((re) => {
247
+ // eslint-disable-next-line no-undef
248
+ require(['vs/editor/editor.main'], function () {
249
+ // eslint-disable-next-line no-undef
250
+ re(monaco.editor.create(container.build(), {
251
+ value: "",
252
+ fontSize: "16",
253
+ theme: "vs-dark",
254
+ lineNumbers: "on",
255
+ insertSpaces: false,
256
+ language: "javascript",
257
+ automaticLayout: true,
258
+ wordWrap: "wordWrapColumn",
259
+ }));
260
+ })
261
+ });
262
+ editor.onDidChangeModelContent(
263
+ debounce(() => {
264
+ const newInput = editor.getValue();
265
+ TelaLocalStorage.setItem("input", newInput);
266
+ execCode(newInput);
267
+ })
268
+ );
269
+ AppState.editor = some(editor);
270
+ return container.addClass("grow margin");
271
+ }
272
+
273
+ function output() {
274
+ const iframe = DOM.of("iframe")
275
+ .addClass("margin")
276
+ .style("height:inherit;width:97%;border:none");
277
+ AppState.outputIframe = some(iframe);
278
+ const iframeEl = iframe.element;
279
+ iframe.event("load", () => {
280
+ iframeEl.contentDocument.body.innerHTML = getIframeDefaultBody();
281
+ iframeEl.contentWindow.addEventListener("error", (e) => {
282
+ AppState.lineDecorations = some(printErrorInCode(e.message, e.lineno));
283
+ iframeEl.contentDocument.getElementById("root").innerHTML = `
284
+ <p style="color: red">Error:${e.message} at line ${e.lineno - MAGIC_CODE_LINE_NUMBER_OFFSET}</p>
285
+ `;
286
+ })
287
+ })
288
+ return DOM.of("div")
289
+ .appendChild(iframe)
290
+ .addClass("grow margin flex");
291
+ }
292
+
293
+ /**
294
+ * from https://github.com/phuocng/html-dom/blob/master/assets/demo/create-resizable-split-views/index.html
295
+ */
296
+ function createDraggableResizeHandler(left, divider, right) {
297
+ // The current position of mouse
298
+ let x = 0;
299
+ let leftWidth = 0;
300
+
301
+ // Handle the mousedown event
302
+ // that's triggered when user drags the divider
303
+ const mouseDownHandler = function (e) {
304
+ // Get the current mouse position
305
+ x = e.clientX;
306
+ leftWidth = left.getBoundingClientRect().width;
307
+
308
+ // Attach the listeners to `document`
309
+ document.addEventListener('mousemove', mouseMoveHandler);
310
+ document.addEventListener('mouseup', mouseUpHandler);
311
+ };
312
+
313
+ const mouseMoveHandler = function (e) {
314
+ // How far the mouse has been moved
315
+ const dx = e.clientX - x;
316
+
317
+ const newLeftWidth = ((leftWidth + dx) * 100) / divider.parentNode.getBoundingClientRect().width;
318
+ left.style.width = `${newLeftWidth}%`;
319
+
320
+ divider.style.cursor = 'col-resize';
321
+ document.body.style.cursor = 'col-resize';
322
+
323
+ left.style.userSelect = 'none';
324
+ left.style.pointerEvents = 'none';
325
+
326
+ right.style.userSelect = 'none';
327
+ right.style.pointerEvents = 'none';
328
+ };
329
+
330
+ const mouseUpHandler = function () {
331
+ divider.style.removeProperty('cursor');
332
+ document.body.style.removeProperty('cursor');
333
+
334
+ left.style.removeProperty('user-select');
335
+ left.style.removeProperty('pointer-events');
336
+
337
+ right.style.removeProperty('user-select');
338
+ right.style.removeProperty('pointer-events');
339
+
340
+ // Remove the handlers of `mousemove` and `mouseup`
341
+ document.removeEventListener('mousemove', mouseMoveHandler);
342
+ document.removeEventListener('mouseup', mouseUpHandler);
343
+ };
344
+
345
+ // Attach the handler
346
+ divider.addEventListener('mousedown', mouseDownHandler);
347
+ }
348
+
349
+ function onResize(container, input, output) {
350
+ const style = container.build().style;
351
+ if (window.innerWidth >= window.innerHeight) {
352
+ style["flex-direction"] = "row";
353
+ input.style(`width:${window.innerWidth / 2}px; height:${window.innerHeight * 0.79}px`);
354
+ output.style(`width:${window.innerWidth / 2}px; height:${window.innerHeight * 0.79}px`);
355
+ } else {
356
+ style["flex-direction"] = "column";
357
+ input.style(`width:${97}%; height:${window.innerHeight / 2}px`);
358
+ output.style(`width:${97}%; height:${window.innerHeight / 2}px`);
359
+ }
360
+ }
361
+
362
+ async function main() {
363
+ const container = DOM.of("main")
364
+ .addClass("flex spaced-items");
365
+ const editor = (await input())
366
+ const divider = DOM.of("div")
367
+ .addClass("divider");
368
+ const out = output();
369
+ createDraggableResizeHandler(
370
+ editor.build(),
371
+ divider.build(),
372
+ out.build()
373
+ );
374
+ onResize(
375
+ container,
376
+ editor,
377
+ out
378
+ );
379
+ window.addEventListener(
380
+ "resize",
381
+ () => onResize(container, editor, out)
382
+ );
383
+ return container
384
+ .appendChild(
385
+ editor,
386
+ divider,
387
+ out
388
+ )
389
+ }
390
+
391
+ function footer() {
392
+ return DOM.of("footer")
393
+ .appendChild(
394
+ DOM.of("hr"),
395
+ DOM.of("p")
396
+ .addClass("center")
397
+ .inner("© 2023 Pedroth")
398
+ )
399
+ }
400
+
401
+ async function renderUI() {
402
+ return DOM.ofId("root")
403
+ .appendChild(header())
404
+ .appendChild(await main())
405
+ .appendChild(footer())
406
+ .addClass("loaded")
407
+ }
408
+
409
+ //========================================================================================
410
+ /* *
411
+ * MAIN *
412
+ * */
413
+ //========================================================================================
414
+
415
+ const examples = [
416
+ {
417
+ title: "Simple shader",
418
+ path: "/test/web/simple_shader.js"
419
+ },
420
+ {
421
+ title: "Mandelbrot set shader",
422
+ path: "/test/web/mandelbrot.js"
423
+ },
424
+ {
425
+ title: "Simple animation shader",
426
+ path: "/test/web/simple_animation.js"
427
+ },
428
+ {
429
+ title: "Rotating grid shader",
430
+ path: "/test/web/rotating_grid.js"
431
+ },
432
+ {
433
+ title: "Amazing effects shader",
434
+ path: "/test/web/amazing_shader.js"
435
+ },
436
+ {
437
+ title: "Amazing effects shader 2",
438
+ path: "/test/web/amazing_shader_2.js"
439
+ },
440
+ {
441
+ title: "Wave simulation",
442
+ path: "/test/web/wave_equation.js"
443
+ },
444
+ {
445
+ title: "Wave Interaction",
446
+ path: "/test/web/interactive_wave.js"
447
+ },
448
+ {
449
+ title: "6 points",
450
+ path: "/test/web/six_spheres.js"
451
+ },
452
+ {
453
+ title: "Point cloud bunny",
454
+ path: "/test/web/bunny.js"
455
+ },
456
+ {
457
+ title: "SDF test",
458
+ path: "/test/web/signed_distance.js"
459
+ },
460
+ {
461
+ title: "bunny SDF test",
462
+ path: "/test/web/signed_bunny.js"
463
+ },
464
+ {
465
+ title: "image to rgb space",
466
+ path: "/test/web/image2rgb.js"
467
+ }
468
+ ];
469
+
470
+ const AppState = {
471
+ editor: none(),
472
+ lineDecorations: none(),
473
+ outputIframe: none(),
474
+ }
475
+
476
+ function getExampleFromPath(path) {
477
+ return fetch(SOURCE + path).then(f => f.text());
478
+ }
479
+
480
+ function execCode(code) {
481
+ AppState
482
+ .outputIframe
483
+ .forEach(iframe => {
484
+ AppState.lineDecorations.forEach(decorations => decorations.clear())
485
+ DOM.of(iframe.element.contentDocument.body)
486
+ .removeChildren()
487
+ .inner(getIframeDefaultBody());
488
+ // seems like the only way to run a script inside iframe
489
+ const script = DOM.of("script").build();
490
+ script.type = "module";
491
+ script.textContent = `
492
+ import {Canvas, DOM, Color, Animation, Scene, Camera, Vec2, Vec3, Vec, Box, Point, Mesh, NaiveScene} from "/dist/web/index.js"
493
+ Animation.globalAnimationIds.forEach(id => {
494
+ window.cancelAnimationFrame(id)
495
+ });
496
+ ${toggleFullScreen.toString()}
497
+ const canvasDOM = document.getElementsByTagName("canvas")[0];
498
+ const canvas = Canvas.ofDOM(canvasDOM);
499
+ document.getElementById("expandButton").addEventListener('click', () => {
500
+ toggleFullScreen(canvasDOM);
501
+ });
502
+ const logger = {
503
+ print: (message) => {
504
+ document.getElementById("logger").innerText = message;
505
+ },
506
+ log: (message) => {
507
+ document.getElementById("logger").innerText += \`\${message}\\n\`;
508
+ }
509
+ }
510
+ const fps = (() => {
511
+ let meanAverage = 0;
512
+ return (dt, it) => {
513
+ meanAverage = meanAverage + (dt - meanAverage) / it;
514
+ logger.print("FPS: " + (1 / meanAverage));
515
+ }
516
+ })();
517
+ (${code})(canvas, fps, logger)
518
+ `;
519
+ iframe.element.contentDocument.body.appendChild(script);
520
+ })
521
+ }
522
+
523
+ function getSelectedExample() {
524
+ return TelaLocalStorage.getItem("selectedExample") || "Simple shader";
525
+ }
526
+
527
+ (async () => {
528
+ await renderUI()
529
+ AppState.editor.forEach(async editor => {
530
+ const examplePath = examples.filter(({ title }) => getSelectedExample() === title)[0].path;
531
+ const exampleTxt = TelaLocalStorage.getItem("input") || await getExampleFromPath(examplePath);
532
+ editor.setValue(exampleTxt)
533
+ });
534
+ })()