├── .gitignore
├── README.md
├── bsconfig.json
├── css
└── codemirror.css
├── examples
├── pixiBasics
│ ├── example_001.js
│ ├── example_002.js
│ ├── example_003.js
│ ├── example_004.js
│ ├── example_005.js
│ ├── example_006.js
│ ├── example_007.js
│ ├── example_008.js
│ ├── example_009.js
│ ├── example_010.js
│ ├── example_011.js
│ └── example_012.js
└── pixiBasicsMega.txt
├── experiments
├── flowtest.js
└── types.sh
├── index-dev.html
├── index-dist.html
├── index.html
├── package-lock.json
├── package.json
├── src
├── Test.re
├── TestNode.re
├── example-node.txt
├── example.ast
├── example.txt
├── external.js
├── index.js
├── lib.js
├── listNodes.js
├── node.js
├── puppet.js
├── runtests.js
└── transpileExamples.sh
└── webpack.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | *.swp
2 | /dist/index.js
3 | /dist/test.js
4 | /dist/node.js
5 | /dist/runtests.js
6 | .DS_Store
7 | .merlin
8 | .bsb.lock
9 | npm-debug.log
10 | /lib/bs/
11 | /node_modules/
12 | /src/*.bs.js
13 | /rebuild/
14 | /src/Example*.re
15 | /.nyc_output/
16 | /src/Test.re
17 | /coverage/
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # JavaScript to ReasonML Transpiler
2 |
3 | Check it out [Live on GitHub
4 | Pages](https://emnh.github.io/js-to-reasonml-transpiler). Tested with:
5 | - Chrome 65
6 | - Firefox 59
7 | - Edge 41
8 |
9 | ## Table of contents
10 |
11 | - [Introduction](#introduction)
12 | - [Example transpilation](#example-transpilation)
13 | - [Manual labour](#manual-labour)
14 | - [Testing examples](#testing-examples)
15 | - [Running tests](#running-tests)
16 | - [Supported syntax](#supported-syntax)
17 | - [Alternatives](#alternatives)
18 |
19 | # Introduction
20 |
21 | This is a helper script to port small examples from JS to ReasonML. It should
22 | be mainly for generating a baseline for externals, unless it grows to something
23 | bigger :p . Requires to actually run the code with eval because it will inspect
24 | the types for declaration at runtime. Code path coverage in example must be
25 | 100% for now (TODO: implement partial transpilation with unresolvedAnyT if
26 | requested).
27 |
28 | Why eval and not flow? I tried flow and it wasn't able to infer much, while
29 | evaling the code gets all types without much effort. Conditional code paths may
30 | present complications though, so try to avoid them in example code, or if used
31 | you must ensure that all conditional paths are evaluated at least once for
32 | types to resolve. See "Manual labour" for more information.
33 |
34 | I am using :
35 | - Esprima (reading js)
36 | - Escodegen (writing js)
37 |
38 | # Example transpilation
39 |
40 | ## Input
41 |
42 | ```javascript
43 | var app = new PIXI.Application(800, 600, { backgroundColor: 0x1099bb });
44 | /*
45 | console.log(app.constructor.name);
46 | */
47 | document.body.appendChild(app.view);
48 |
49 | // Scale mode for all textures, will retain pixelation
50 | PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;
51 |
52 | var sprite = PIXI.Sprite.fromImage('http://pixijs.io/examples/required/assets/basics/bunny.png');
53 |
54 | // Set the initial position
55 | sprite.anchor.set(0.5);
56 | sprite.x = app.screen.width / 2;
57 | sprite.y = app.screen.height / 2;
58 |
59 | // Opt-in to interactivity
60 | sprite.interactive = true;
61 |
62 | // Shows hand cursor
63 | sprite.buttonMode = true;
64 |
65 | /* PS: Functions are not automatically lifted and must be in order for
66 | * generated script to use them correctly. */
67 | function onClick(evt) {
68 | /* PS: Make sure your event handlers are called at least once by script */
69 | console.log(evt);
70 | sprite.scale.x *= 1.25;
71 | sprite.scale.y *= 1.25;
72 | return 0;
73 | }
74 |
75 | // Pointers normalize touch and mouse
76 | sprite.on('pointerdown', onClick);
77 |
78 | /* PS: Make sure your event handlers are called at least once by script, and
79 | * done after function passed around, like in the following line: */
80 | onClick(new Event('test'));
81 |
82 | // Alternatively, use the mouse & touch events:
83 | // sprite.on('click', onClick); // mouse-only
84 | // sprite.on('tap', onClick); // touch-only
85 |
86 | app.stage.addChild(sprite);
87 |
88 | if (true) {
89 | console.log("hello");
90 | } else {
91 | console.log("blah");
92 | }
93 |
94 | var x = 3;
95 |
96 | x *= 2;
97 | ```
98 |
99 | ## Output
100 |
101 | ReasonML syntax, reformatted with refmt.
102 |
103 | ```ocaml
104 | type appApplicationT;
105 |
106 | type appHTMLDocumentT;
107 |
108 | type appHTMLBodyElementT;
109 |
110 | type appHTMLCanvasElementT;
111 |
112 | type usageFunSpriteT;
113 |
114 | type appSpriteT;
115 |
116 | type appObservablePointT;
117 |
118 | type appRectangleT;
119 |
120 | type appEventT;
121 |
122 | type appMemoryInfoT;
123 |
124 | type appContainerT;
125 |
126 | type smallObject0T = {. "backgroundColor": int};
127 |
128 | type smallObject21T = {. "RESOLUTION": int};
129 |
130 | type smallObject42T = {
131 | .
132 | "LINEAR": int,
133 | "NEAREST": int
134 | };
135 |
136 | type smallObject65T = {. "memory": appMemoryInfoT};
137 |
138 | type usageFunOnClickT = appEventT => int;
139 |
140 | [@bs.new] [@bs.module "pixi.js"]
141 | external newApplication3 : (int, int, smallObject0T) => appApplicationT =
142 | "Application";
143 |
144 | [@bs.val] external document : appHTMLDocumentT = "document";
145 |
146 | [@bs.get] external getBody : appHTMLDocumentT => appHTMLBodyElementT = "body";
147 |
148 | [@bs.get] external getView : appApplicationT => appHTMLCanvasElementT = "view";
149 |
150 | [@bs.send]
151 | external appendChild1 :
152 | (appHTMLBodyElementT, appHTMLCanvasElementT) => appHTMLCanvasElementT =
153 | "appendChild";
154 |
155 | [@bs.val] [@bs.module "pixi.js"]
156 | external getSettings : smallObject21T = "settings";
157 |
158 | [@bs.set]
159 | external setSCALE_MODE : (smallObject21T, int) => unit = "SCALE_MODE";
160 |
161 | [@bs.val] [@bs.module "pixi.js"] [@bs.scope "settings"]
162 | external getSCALE_MODE : int = "SCALE_MODE";
163 |
164 | [@bs.val] [@bs.module "pixi.js"]
165 | external getSCALE_MODES : smallObject42T = "SCALE_MODES";
166 |
167 | [@bs.val] [@bs.module "pixi.js"] [@bs.scope "SCALE_MODES"]
168 | external getNEAREST : int = "NEAREST";
169 |
170 | [@bs.val] [@bs.module "pixi.js"]
171 | external getSprite : usageFunSpriteT = "Sprite";
172 |
173 | [@bs.val] [@bs.module "pixi.js"] [@bs.scope "Sprite"]
174 | external fromImage1 : string => appSpriteT = "fromImage";
175 |
176 | [@bs.get] external getAnchor : appSpriteT => appObservablePointT = "anchor";
177 |
178 | [@bs.send] external set1 : (appObservablePointT, float) => unit = "set";
179 |
180 | [@bs.set] external setX : (appSpriteT, int) => unit = "x";
181 |
182 | [@bs.get] external getX : appSpriteT => int = "x";
183 |
184 | [@bs.get] external getScreen : appApplicationT => appRectangleT = "screen";
185 |
186 | [@bs.get] external getWidth : appRectangleT => int = "width";
187 |
188 | [@bs.set] external setY : (appSpriteT, int) => unit = "y";
189 |
190 | [@bs.get] external getY : appSpriteT => int = "y";
191 |
192 | [@bs.get] external getHeight : appRectangleT => int = "height";
193 |
194 | [@bs.set]
195 | external setInteractive : (appSpriteT, Js.boolean) => unit = "interactive";
196 |
197 | [@bs.get] external getInteractive : appSpriteT => Js.boolean = "interactive";
198 |
199 | [@bs.set]
200 | external setButtonMode : (appSpriteT, Js.boolean) => unit = "buttonMode";
201 |
202 | [@bs.get] external getButtonMode : appSpriteT => Js.boolean = "buttonMode";
203 |
204 | [@bs.val] external console : smallObject65T = "console";
205 |
206 | [@bs.get] external getScale : appSpriteT => appObservablePointT = "scale";
207 |
208 | [@bs.set]
209 | external setXappObservablePointTfloat : (appObservablePointT, float) => unit =
210 | "x";
211 |
212 | [@bs.get]
213 | external getXappObservablePointT : appObservablePointT => float = "x";
214 |
215 | [@bs.set]
216 | external setYappObservablePointTfloat : (appObservablePointT, float) => unit =
217 | "y";
218 |
219 | [@bs.get]
220 | external getYappObservablePointT : appObservablePointT => float = "y";
221 |
222 | [@bs.send]
223 | external on2 : (appSpriteT, string, usageFunOnClickT) => appSpriteT = "on";
224 |
225 | [@bs.new] external newEvent1 : string => appEventT = "Event";
226 |
227 | [@bs.get] external getStage : appApplicationT => appContainerT = "stage";
228 |
229 | [@bs.send]
230 | external addChild1 : (appContainerT, appSpriteT) => appSpriteT = "addChild";
231 |
232 | let app = newApplication3(800, 600, {"backgroundColor": 0x1099bb});
233 |
234 | /*
235 | console.log(app.constructor.name);
236 | */
237 | document |. getBody |. appendChild1(app |. getView);
238 |
239 | /* Scale mode for all textures, will retain pixelation */
240 | setSCALE_MODE(getSettings, getNEAREST);
241 |
242 | let sprite =
243 | fromImage1("http://pixijs.io/examples/required/assets/basics/bunny.png");
244 |
245 | /* Set the initial position */
246 | sprite |. getAnchor |. set1(0.5);
247 |
248 | setX(sprite, (app |. getScreen |. getWidth) / 2);
249 |
250 | setY(sprite, (app |. getScreen |. getHeight) / 2);
251 |
252 | /* Opt-in to interactivity */
253 | setInteractive(sprite, Js.true_);
254 |
255 | /* Shows hand cursor */
256 | setButtonMode(sprite, Js.true_);
257 |
258 | /* PS: Functions are not automatically lifted and must be in order for
259 | * generated script to use them correctly. */
260 | let onClick = evt => {
261 | /* PS: Make sure your event handlers are called at least once by script */
262 | Js.log(evt);
263 | setXappObservablePointTfloat(
264 | sprite |. getScale,
265 | (sprite |. getScale |. getXappObservablePointT) *. 1.25
266 | );
267 | setYappObservablePointTfloat(
268 | sprite |. getScale,
269 | (sprite |. getScale |. getYappObservablePointT) *. 1.25
270 | );
271 | 0;
272 | };
273 |
274 | /* Pointers normalize touch and mouse */
275 | sprite |. on2("pointerdown", onClick);
276 |
277 | /* PS: Make sure your event handlers are called at least once by script, and
278 | * done after function passed around, like in the following line: */
279 | onClick(newEvent1("test"));
280 |
281 | /* Alternatively, use the mouse & touch events:
282 | sprite.on('click', onClick); // mouse-only
283 | sprite.on('tap', onClick); // touch-only */
284 | app |. getStage |. addChild1(sprite);
285 |
286 | if (Js.to_bool(Js.true_)) {
287 | Js.log("hello");
288 | } else {
289 | Js.log("blah");
290 | };
291 |
292 | let xRef = ref(3);
293 |
294 | xRef := xRef^ * 2;
295 | ```
296 |
297 | # Manual labour
298 |
299 | This section lists workarounds for unimplemented features and transpilations.
300 |
301 | - It is up to you to ensure that all branches of if statements are evaluated
302 | at least once to get the types.
303 | - Control flow keywords like continue and break are not supported yet. Early
304 | return is not supported either: there should only be a single return
305 | statement at end of function.
306 | - Initialize all (non-int) variables. Default value is set to 0 if not
307 | initialized and a TODO comment is added.
308 | - Reorder functions so that they are called after they are declared.
309 | - Tweak integer values that should be floats, e.g. write 0.5 + 0.5 instead of
310 | 1 if you want the value to be considered float.
311 | - Call event handlers manually at least once, after they've been passed around
312 | to event registers. Alternatively, set a high timeout and
313 | trigger events manually in browser.
314 | - By default there is a 10 second timeout to allow for resource load,
315 | timer updates etc when evaluating example code. If all types are resolved
316 | before the grace period is done, transpilation proceeds at once. Adjust
317 | period in index.js if needed. TODO: create option for this on web page.
318 |
319 | After transpile:
320 | - Reorder type definitions if necessary. There is a TODO issue on sorting them
321 | topologically.
322 | - Add |> ignore or let _ = to avoid warnings. I don't do it automatically
323 | because it will be hard to detect when it's necessary and too many of them
324 | clutters the code.
325 |
326 | # Testing examples
327 |
328 | ## Node example
329 |
330 | Node support is basic so far, but an example can be found in
331 | src/example-node.txt.
332 |
333 | To run the example:
334 |
335 | ```bash
336 | npm run webpack # to compile dist/node.js
337 | node dist/node.js # will transpile src/example-node.txt to src/TestNode.re
338 | npm start # to compile src/TestNode.re
339 | node src/TestNode.bs.js
340 | ```
341 |
342 | ## Browser examples
343 |
344 | ```bash
345 | node src/puppet.js examples/pixiBasics/example_001.js >| src/Test.re
346 | npm start
347 | ```
348 |
349 | ### Caveats
350 | - Example 4. Need to add a |> ignore at end of function.
351 | - Example 9. Need to add a |> ignore at end of function.
352 |
353 | Go to http://localhost:8080/test .
354 |
355 | ## Running tests
356 |
357 | ```bash
358 | # run tests script
359 | npm run test
360 | ```
361 |
362 | # Supported syntax
363 |
364 | This list of ESprima syntax nodes is from
365 | [here](https://github.com/jquery/esprima/blob/master/src/syntax.ts) and
366 | annotated with whether transpilation is implemented or not yet. Create an issue
367 | if you want a syntax implemented.
368 |
369 | - YES:
370 | - NO:
371 |
372 | Feature | Supported
373 | --- | ---
374 | AssignmentExpression |
375 | AssignmentPattern |
376 | ArrayExpression |
377 | ArrayPattern |
378 | ArrowFunctionExpression |
379 | AwaitExpression |
380 | BlockStatement |
381 | BinaryExpression |
382 | BreakStatement |
383 | CallExpression |
384 | CatchClause |
385 | ClassBody |
386 | ClassDeclaration |
387 | ClassExpression |
388 | ConditionalExpression |
389 | ContinueStatement |
390 | DoWhileStatement |
391 | DebuggerStatement |
392 | EmptyStatement |
393 | ExportAllDeclaration |
394 | ExportDefaultDeclaration |
395 | ExportNamedDeclaration |
396 | ExportSpecifier |
397 | ExpressionStatement |
398 | ForStatement |
399 | ForOfStatement |
400 | ForInStatement |
401 | FunctionDeclaration |
402 | FunctionExpression |
403 | Identifier |
404 | IfStatement |
405 | Import |
406 | ImportDeclaration |
407 | ImportDefaultSpecifier |
408 | ImportNamespaceSpecifier |
409 | ImportSpecifier |
410 | Literal |
411 | LabeledStatement |
412 | LogicalExpression |
413 | MemberExpression |
414 | MetaProperty |
415 | MethodDefinition |
416 | NewExpression |
417 | ObjectExpression |
418 | ObjectPattern |
419 | Program |
420 | Property |
421 | RestElement |
422 | ReturnStatement |
423 | SequenceExpression |
424 | SpreadElement |
425 | Super |
426 | SwitchCase |
427 | SwitchStatement |
428 | TaggedTemplateExpression |
429 | TemplateElement |
430 | TemplateLiteral |
431 | ThisExpression |
432 | ThrowStatement |
433 | TryStatement |
434 | UnaryExpression |
435 | UpdateExpression |
436 | VariableDeclaration |
437 | VariableDeclarator |
438 | WhileStatement |
439 | WithStatement |
440 | YieldExpression |
441 |
442 | # Alternatives
443 |
444 | - [Jeason](https://github.com/chenglou/jeason) is another approach using Flow.
445 | Differences to my project are that flow cannot really infer many types at
446 | all without annotations. The code Jeason generates is also full of dynamic
447 | lookups, not using typed getters and setters as my project does. Also it is
448 | not as convenient to copy paste and quickly transpile live examples in
449 | browser.
450 | - [ReasonablyTyped](https://github.com/rrdelaney/ReasonablyTyped) I tried this
451 | a while ago to convert WebGL2 bindings (and three.js if I remember
452 | correctly) but I couldn't get it to work. Well, seems like it's a work in
453 | progress with last commit 4 days ago per 03.04.2018.
454 |
--------------------------------------------------------------------------------
/bsconfig.json:
--------------------------------------------------------------------------------
1 | // This is the configuration file used by BuckleScript's build system bsb. Its documentation lives here: http://bucklescript.github.io/bucklescript/docson/#build-schema.json
2 | // BuckleScript comes with its own parser for bsconfig.json, which is normal JSON, with the extra support of comments and trailing commas.
3 | {
4 | "name": "js-to-reasonml-transpiler",
5 | "version": "0.1.0",
6 | "sources": {
7 | "dir" : "src",
8 | "subdirs" : true
9 | },
10 | "package-specs": {
11 | "module": "commonjs",
12 | "in-source": true
13 | },
14 | "suffix": ".bs.js",
15 | "bs-dependencies": [
16 | // add your dependencies here. You'd usually install them normally through `npm install my-dependency`. If my-dependency has a bsconfig.json too, then everything will work seamlessly.
17 | ],
18 | "warnings": {
19 | "error" : "+101"
20 | },
21 | "namespace": true,
22 | "refmt": 3
23 | }
24 |
--------------------------------------------------------------------------------
/css/codemirror.css:
--------------------------------------------------------------------------------
1 | /* BASICS */
2 |
3 | .CodeMirror {
4 | /* Set height, width, borders, and global font properties here */
5 | font-family: monospace;
6 | height: 300px;
7 | color: black;
8 | direction: ltr;
9 | }
10 |
11 | /* PADDING */
12 |
13 | .CodeMirror-lines {
14 | padding: 4px 0; /* Vertical padding around content */
15 | }
16 | .CodeMirror pre {
17 | padding: 0 4px; /* Horizontal padding of content */
18 | }
19 |
20 | .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
21 | background-color: white; /* The little square between H and V scrollbars */
22 | }
23 |
24 | /* GUTTER */
25 |
26 | .CodeMirror-gutters {
27 | border-right: 1px solid #ddd;
28 | background-color: #f7f7f7;
29 | white-space: nowrap;
30 | }
31 | .CodeMirror-linenumbers {}
32 | .CodeMirror-linenumber {
33 | padding: 0 3px 0 5px;
34 | min-width: 20px;
35 | text-align: right;
36 | color: #999;
37 | white-space: nowrap;
38 | }
39 |
40 | .CodeMirror-guttermarker { color: black; }
41 | .CodeMirror-guttermarker-subtle { color: #999; }
42 |
43 | /* CURSOR */
44 |
45 | .CodeMirror-cursor {
46 | border-left: 1px solid black;
47 | border-right: none;
48 | width: 0;
49 | }
50 | /* Shown when moving in bi-directional text */
51 | .CodeMirror div.CodeMirror-secondarycursor {
52 | border-left: 1px solid silver;
53 | }
54 | .cm-fat-cursor .CodeMirror-cursor {
55 | width: auto;
56 | border: 0 !important;
57 | background: #7e7;
58 | }
59 | .cm-fat-cursor div.CodeMirror-cursors {
60 | z-index: 1;
61 | }
62 | .cm-fat-cursor-mark {
63 | background-color: rgba(20, 255, 20, 0.5);
64 | -webkit-animation: blink 1.06s steps(1) infinite;
65 | -moz-animation: blink 1.06s steps(1) infinite;
66 | animation: blink 1.06s steps(1) infinite;
67 | }
68 | .cm-animate-fat-cursor {
69 | width: auto;
70 | border: 0;
71 | -webkit-animation: blink 1.06s steps(1) infinite;
72 | -moz-animation: blink 1.06s steps(1) infinite;
73 | animation: blink 1.06s steps(1) infinite;
74 | background-color: #7e7;
75 | }
76 | @-moz-keyframes blink {
77 | 0% {}
78 | 50% { background-color: transparent; }
79 | 100% {}
80 | }
81 | @-webkit-keyframes blink {
82 | 0% {}
83 | 50% { background-color: transparent; }
84 | 100% {}
85 | }
86 | @keyframes blink {
87 | 0% {}
88 | 50% { background-color: transparent; }
89 | 100% {}
90 | }
91 |
92 | /* Can style cursor different in overwrite (non-insert) mode */
93 | .CodeMirror-overwrite .CodeMirror-cursor {}
94 |
95 | .cm-tab { display: inline-block; text-decoration: inherit; }
96 |
97 | .CodeMirror-rulers {
98 | position: absolute;
99 | left: 0; right: 0; top: -50px; bottom: -20px;
100 | overflow: hidden;
101 | }
102 | .CodeMirror-ruler {
103 | border-left: 1px solid #ccc;
104 | top: 0; bottom: 0;
105 | position: absolute;
106 | }
107 |
108 | /* DEFAULT THEME */
109 |
110 | .cm-s-default .cm-header {color: blue;}
111 | .cm-s-default .cm-quote {color: #090;}
112 | .cm-negative {color: #d44;}
113 | .cm-positive {color: #292;}
114 | .cm-header, .cm-strong {font-weight: bold;}
115 | .cm-em {font-style: italic;}
116 | .cm-link {text-decoration: underline;}
117 | .cm-strikethrough {text-decoration: line-through;}
118 |
119 | .cm-s-default .cm-keyword {color: #708;}
120 | .cm-s-default .cm-atom {color: #219;}
121 | .cm-s-default .cm-number {color: #164;}
122 | .cm-s-default .cm-def {color: #00f;}
123 | .cm-s-default .cm-variable,
124 | .cm-s-default .cm-punctuation,
125 | .cm-s-default .cm-property,
126 | .cm-s-default .cm-operator {}
127 | .cm-s-default .cm-variable-2 {color: #05a;}
128 | .cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #085;}
129 | .cm-s-default .cm-comment {color: #a50;}
130 | .cm-s-default .cm-string {color: #a11;}
131 | .cm-s-default .cm-string-2 {color: #f50;}
132 | .cm-s-default .cm-meta {color: #555;}
133 | .cm-s-default .cm-qualifier {color: #555;}
134 | .cm-s-default .cm-builtin {color: #30a;}
135 | .cm-s-default .cm-bracket {color: #997;}
136 | .cm-s-default .cm-tag {color: #170;}
137 | .cm-s-default .cm-attribute {color: #00c;}
138 | .cm-s-default .cm-hr {color: #999;}
139 | .cm-s-default .cm-link {color: #00c;}
140 |
141 | .cm-s-default .cm-error {color: #f00;}
142 | .cm-invalidchar {color: #f00;}
143 |
144 | .CodeMirror-composing { border-bottom: 2px solid; }
145 |
146 | /* Default styles for common addons */
147 |
148 | div.CodeMirror span.CodeMirror-matchingbracket {color: #0b0;}
149 | div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
150 | .CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
151 | .CodeMirror-activeline-background {background: #e8f2ff;}
152 |
153 | /* STOP */
154 |
155 | /* The rest of this file contains styles related to the mechanics of
156 | the editor. You probably shouldn't touch them. */
157 |
158 | .CodeMirror {
159 | position: relative;
160 | overflow: hidden;
161 | background: white;
162 | }
163 |
164 | .CodeMirror-scroll {
165 | overflow: scroll !important; /* Things will break if this is overridden */
166 | /* 30px is the magic margin used to hide the element's real scrollbars */
167 | /* See overflow: hidden in .CodeMirror */
168 | margin-bottom: -30px; margin-right: -30px;
169 | padding-bottom: 30px;
170 | height: 100%;
171 | outline: none; /* Prevent dragging from highlighting the element */
172 | position: relative;
173 | }
174 | .CodeMirror-sizer {
175 | position: relative;
176 | border-right: 30px solid transparent;
177 | }
178 |
179 | /* The fake, visible scrollbars. Used to force redraw during scrolling
180 | before actual scrolling happens, thus preventing shaking and
181 | flickering artifacts. */
182 | .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
183 | position: absolute;
184 | z-index: 6;
185 | display: none;
186 | }
187 | .CodeMirror-vscrollbar {
188 | right: 0; top: 0;
189 | overflow-x: hidden;
190 | overflow-y: scroll;
191 | }
192 | .CodeMirror-hscrollbar {
193 | bottom: 0; left: 0;
194 | overflow-y: hidden;
195 | overflow-x: scroll;
196 | }
197 | .CodeMirror-scrollbar-filler {
198 | right: 0; bottom: 0;
199 | }
200 | .CodeMirror-gutter-filler {
201 | left: 0; bottom: 0;
202 | }
203 |
204 | .CodeMirror-gutters {
205 | position: absolute; left: 0; top: 0;
206 | min-height: 100%;
207 | z-index: 3;
208 | }
209 | .CodeMirror-gutter {
210 | white-space: normal;
211 | height: 100%;
212 | display: inline-block;
213 | vertical-align: top;
214 | margin-bottom: -30px;
215 | }
216 | .CodeMirror-gutter-wrapper {
217 | position: absolute;
218 | z-index: 4;
219 | background: none !important;
220 | border: none !important;
221 | }
222 | .CodeMirror-gutter-background {
223 | position: absolute;
224 | top: 0; bottom: 0;
225 | z-index: 4;
226 | }
227 | .CodeMirror-gutter-elt {
228 | position: absolute;
229 | cursor: default;
230 | z-index: 4;
231 | }
232 | .CodeMirror-gutter-wrapper ::selection { background-color: transparent }
233 | .CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }
234 |
235 | .CodeMirror-lines {
236 | cursor: text;
237 | min-height: 1px; /* prevents collapsing before first draw */
238 | }
239 | .CodeMirror pre {
240 | /* Reset some styles that the rest of the page might have set */
241 | -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
242 | border-width: 0;
243 | background: transparent;
244 | font-family: inherit;
245 | font-size: inherit;
246 | margin: 0;
247 | white-space: pre;
248 | word-wrap: normal;
249 | line-height: inherit;
250 | color: inherit;
251 | z-index: 2;
252 | position: relative;
253 | overflow: visible;
254 | -webkit-tap-highlight-color: transparent;
255 | -webkit-font-variant-ligatures: contextual;
256 | font-variant-ligatures: contextual;
257 | }
258 | .CodeMirror-wrap pre {
259 | word-wrap: break-word;
260 | white-space: pre-wrap;
261 | word-break: normal;
262 | }
263 |
264 | .CodeMirror-linebackground {
265 | position: absolute;
266 | left: 0; right: 0; top: 0; bottom: 0;
267 | z-index: 0;
268 | }
269 |
270 | .CodeMirror-linewidget {
271 | position: relative;
272 | z-index: 2;
273 | padding: 0.1px; /* Force widget margins to stay inside of the container */
274 | }
275 |
276 | .CodeMirror-widget {}
277 |
278 | .CodeMirror-rtl pre { direction: rtl; }
279 |
280 | .CodeMirror-code {
281 | outline: none;
282 | }
283 |
284 | /* Force content-box sizing for the elements where we expect it */
285 | .CodeMirror-scroll,
286 | .CodeMirror-sizer,
287 | .CodeMirror-gutter,
288 | .CodeMirror-gutters,
289 | .CodeMirror-linenumber {
290 | -moz-box-sizing: content-box;
291 | box-sizing: content-box;
292 | }
293 |
294 | .CodeMirror-measure {
295 | position: absolute;
296 | width: 100%;
297 | height: 0;
298 | overflow: hidden;
299 | visibility: hidden;
300 | }
301 |
302 | .CodeMirror-cursor {
303 | position: absolute;
304 | pointer-events: none;
305 | }
306 | .CodeMirror-measure pre { position: static; }
307 |
308 | div.CodeMirror-cursors {
309 | visibility: hidden;
310 | position: relative;
311 | z-index: 3;
312 | }
313 | div.CodeMirror-dragcursors {
314 | visibility: visible;
315 | }
316 |
317 | .CodeMirror-focused div.CodeMirror-cursors {
318 | visibility: visible;
319 | }
320 |
321 | .CodeMirror-selected { background: #d9d9d9; }
322 | .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
323 | .CodeMirror-crosshair { cursor: crosshair; }
324 | .CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
325 | .CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
326 |
327 | .cm-searching {
328 | background-color: #ffa;
329 | background-color: rgba(255, 255, 0, .4);
330 | }
331 |
332 | /* Used to force a border model for a node */
333 | .cm-force-border { padding-right: .1px; }
334 |
335 | @media print {
336 | /* Hide the cursor when printing */
337 | .CodeMirror div.CodeMirror-cursors {
338 | visibility: hidden;
339 | }
340 | }
341 |
342 | /* See issue #2901 */
343 | .cm-tab-wrap-hack:after { content: ''; }
344 |
345 | /* Help users use markselection to safely style text background */
346 | span.CodeMirror-selectedtext { background: none; }
347 |
348 | /* Added by emh */
349 | .CodeMirror, .CodeMirror-scroll {
350 | height: auto;
351 | }
352 |
353 | .CodeMirror-code .marked {
354 | border: 1px solid red;
355 | line-height: 1.5em;
356 | }
357 |
--------------------------------------------------------------------------------
/examples/pixiBasics/example_001.js:
--------------------------------------------------------------------------------
1 | var app = new PIXI.Application(800, 600, {backgroundColor : 0x1099bb});
2 | document.body.appendChild(app.view);
3 |
4 | // create a new Sprite from an image path
5 | var bunny = PIXI.Sprite.fromImage('http://pixijs.io/examples/required/assets/basics/bunny.png')
6 |
7 | // center the sprite's anchor point
8 | bunny.anchor.set(0.5);
9 |
10 | // move the sprite to the center of the screen
11 | bunny.x = app.screen.width / 2;
12 | bunny.y = app.screen.height / 2;
13 |
14 | app.stage.addChild(bunny);
15 |
16 | var rotation = function(delta) {
17 | // just for fun, let's rotate mr rabbit a little
18 | // delta is 1 if running at 100% performance
19 | // creates frame-independent transformation
20 | bunny.rotation += 0.1 * delta;
21 | };
22 | rotation(0.01);
23 |
24 | // Listen for animate update
25 | app.ticker.add(rotation);
26 |
--------------------------------------------------------------------------------
/examples/pixiBasics/example_002.js:
--------------------------------------------------------------------------------
1 | var app = new PIXI.Application(800, 600, {backgroundColor : 0x1099bb});
2 | document.body.appendChild(app.view);
3 |
4 | var container = new PIXI.Container();
5 |
6 | app.stage.addChild(container);
7 |
8 | var texture = PIXI.Texture.fromImage('http://pixijs.io/examples/required/assets/basics/bunny.png');
9 |
10 | // Create a 5x5 grid of bunnies
11 | for (var i = 0; i < 25; i++) {
12 | var bunny = new PIXI.Sprite(texture);
13 | bunny.anchor.set(0.5);
14 | bunny.x = (i % 5) * 40;
15 | bunny.y = Math.floor(i / 5) * 40;
16 | container.addChild(bunny);
17 | }
18 |
19 | // Center on the screen
20 | container.x = (app.screen.width - container.width) / 2;
21 | container.y = (app.screen.height - container.height) / 2;
22 |
--------------------------------------------------------------------------------
/examples/pixiBasics/example_003.js:
--------------------------------------------------------------------------------
1 | var app = new PIXI.Application(800, 600, {backgroundColor : 0x1099bb});
2 | document.body.appendChild(app.view);
3 |
4 | var container = new PIXI.Container();
5 |
6 | app.stage.addChild(container);
7 |
8 | // Create a new texture
9 | var texture = PIXI.Texture.fromImage('http://pixijs.io/examples/required/assets/basics/bunny.png');
10 |
11 | // Create a 5x5 grid of bunnies
12 | for (var i = 0; i < 25; i++) {
13 | var bunny = new PIXI.Sprite(texture);
14 | bunny.anchor.set(0.5);
15 | bunny.x = (i % 5) * 40;
16 | bunny.y = Math.floor(i / 5) * 40;
17 | container.addChild(bunny);
18 | }
19 |
20 | // Move container to the center
21 | container.x = app.screen.width / 2;
22 | container.y = app.screen.height / 2;
23 |
24 | // Center bunny sprite in local container coordinates
25 | container.pivot.x = container.width / 2;
26 | container.pivot.y = container.height / 2;
27 |
28 | // Listen for animate update
29 | app.ticker.add(function(delta) {
30 | // rotate the container!
31 | // use delta to create frame-independent transform
32 | container.rotation -= 0.01 * delta;
33 | });
34 |
--------------------------------------------------------------------------------
/examples/pixiBasics/example_004.js:
--------------------------------------------------------------------------------
1 | var app = new PIXI.Application();
2 | document.body.appendChild(app.view);
3 |
4 | function onAssetsLoaded()
5 | {
6 | // create an array of textures from an image path
7 | var frames = [];
8 |
9 | for (var i = 0; i < 30; i++) {
10 | var val = i < 10 ? '0' + i : '' + i;
11 |
12 | // magically works since the spritesheet was loaded with the pixi loader
13 | frames.push(PIXI.Texture.fromFrame('rollSequence00' + val + '.png'));
14 | }
15 |
16 | // create an AnimatedSprite (brings back memories from the days of Flash, right ?)
17 | var anim = new PIXI.extras.AnimatedSprite(frames);
18 |
19 | /*
20 | * An AnimatedSprite inherits all the properties of a PIXI sprite
21 | * so you can change its position, its anchor, mask it, etc
22 | */
23 | anim.x = app.screen.width / 2;
24 | anim.y = app.screen.height / 2;
25 | anim.anchor.set(0.5);
26 | anim.animationSpeed = 0.5;
27 | anim.play();
28 |
29 | app.stage.addChild(anim);
30 |
31 | // Animate the rotation
32 | app.ticker.add(function(delta) {
33 | anim.rotation += 0.01;
34 | });
35 | }
36 |
37 | PIXI.loader
38 | .add('http://pixijs.io/examples/required/assets/basics/fighter.json')
39 | .load(onAssetsLoaded);
40 |
--------------------------------------------------------------------------------
/examples/pixiBasics/example_005.js:
--------------------------------------------------------------------------------
1 | var app = new PIXI.Application(800, 600, { backgroundColor: 0x1099bb });
2 | /*
3 | console.log(app.constructor.name);
4 | */
5 | document.body.appendChild(app.view);
6 |
7 | // Scale mode for all textures, will retain pixelation
8 | PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;
9 |
10 | var sprite = PIXI.Sprite.fromImage('http://pixijs.io/examples/required/assets/basics/bunny.png');
11 |
12 | // Set the initial position
13 | sprite.anchor.set(0.5);
14 | sprite.x = app.screen.width / 2;
15 | sprite.y = app.screen.height / 2;
16 |
17 | // Opt-in to interactivity
18 | sprite.interactive = true;
19 |
20 | // Shows hand cursor
21 | sprite.buttonMode = true;
22 |
23 | /* PS: Functions are not automatically lifted and must be in order for
24 | * generated script to use them correctly. */
25 | function onClick(evt) {
26 | /* PS: Make sure your event handlers are called at least once by script */
27 | console.log(evt);
28 | sprite.scale.x *= 1.25;
29 | sprite.scale.y *= 1.25;
30 | return 0;
31 | }
32 |
33 | // Pointers normalize touch and mouse
34 | sprite.on('pointerdown', onClick);
35 |
36 | /* PS: Make sure your event handlers are called at least once by script, and
37 | * done after function passed around, like in the following line: */
38 | onClick(new Event('test'));
39 |
40 | // Alternatively, use the mouse & touch events:
41 | // sprite.on('click', onClick); // mouse-only
42 | // sprite.on('tap', onClick); // touch-only
43 |
44 | app.stage.addChild(sprite);
45 |
46 |
47 | var x = 3;
48 |
49 | x *= 2;
50 |
--------------------------------------------------------------------------------
/examples/pixiBasics/example_006.js:
--------------------------------------------------------------------------------
1 | var app = new PIXI.Application();
2 | document.body.appendChild(app.view);
3 |
4 | // create a texture from an image path
5 | var texture = PIXI.Texture.fromImage('http://pixijs.io/examples/required/assets/p2.jpeg');
6 |
7 | /* create a tiling sprite ...
8 | * requires a texture, a width and a height
9 | * in WebGL the image size should preferably be a power of two
10 | */
11 | var tilingSprite = new PIXI.extras.TilingSprite(
12 | texture,
13 | app.screen.width,
14 | app.screen.height
15 | );
16 | app.stage.addChild(tilingSprite);
17 |
18 | var count = 0.005;
19 |
20 | app.ticker.add(function() {
21 |
22 | count += 0.005;
23 |
24 | tilingSprite.tileScale.x = 2 + Math.sin(count);
25 | tilingSprite.tileScale.y = 2 + Math.cos(count);
26 |
27 | tilingSprite.tilePosition.x += 1;
28 | tilingSprite.tilePosition.y += 1;
29 | });
30 |
--------------------------------------------------------------------------------
/examples/pixiBasics/example_007.js:
--------------------------------------------------------------------------------
1 | var app = new PIXI.Application(800, 600, {backgroundColor: 0x1099bb});
2 | document.body.appendChild(app.view);
3 |
4 | var basicText = new PIXI.Text('Basic text in pixi');
5 | basicText.x = 30;
6 | basicText.y = 90;
7 |
8 | app.stage.addChild(basicText);
9 |
10 | var style = new PIXI.TextStyle({
11 | fontFamily: 'Arial',
12 | fontSize: 36,
13 | fontStyle: 'italic',
14 | fontWeight: 'bold',
15 | fill: ['#ffffff', '#00ff99'], // gradient
16 | stroke: '#4a1850',
17 | strokeThickness: 5,
18 | dropShadow: true,
19 | dropShadowColor: '#000000',
20 | dropShadowBlur: 4,
21 | dropShadowAngle: Math.PI / 6,
22 | dropShadowDistance: 6,
23 | wordWrap: true,
24 | wordWrapWidth: 440
25 | });
26 |
27 | var richText = new PIXI.Text('Rich text with a lot of options and across multiple lines', style);
28 | richText.x = 30;
29 | richText.y = 180;
30 |
31 | app.stage.addChild(richText);
32 |
--------------------------------------------------------------------------------
/examples/pixiBasics/example_008.js:
--------------------------------------------------------------------------------
1 | var app = new PIXI.Application(800, 600, { antialias: true });
2 | document.body.appendChild(app.view);
3 |
4 | var graphics = new PIXI.Graphics();
5 |
6 | // set a fill and line style
7 | graphics.beginFill(0xFF3300);
8 | graphics.lineStyle(4, 0xffd900, 1);
9 |
10 | // draw a shape
11 | graphics.moveTo(50,50);
12 | graphics.lineTo(250, 50);
13 | graphics.lineTo(100, 100);
14 | graphics.lineTo(50, 50);
15 | graphics.endFill();
16 |
17 | // set a fill and a line style again and draw a rectangle
18 | graphics.lineStyle(2, 0x0000FF, 1);
19 | graphics.beginFill(0xFF700B, 1.01);
20 | graphics.drawRect(50, 250, 120, 120);
21 |
22 | // draw a rounded rectangle
23 | graphics.lineStyle(2, 0xFF00FF, 1);
24 | graphics.beginFill(0xFF00BB, 0.25);
25 | graphics.drawRoundedRect(150, 450, 300, 100, 15);
26 | graphics.endFill();
27 |
28 | // draw a circle, set the lineStyle to zero so the circle doesn't have an outline
29 | graphics.lineStyle(0);
30 | graphics.beginFill(0xFFFF0B, 0.5);
31 | graphics.drawCircle(470, 90,60);
32 | graphics.endFill();
33 |
34 | app.stage.addChild(graphics);
35 |
--------------------------------------------------------------------------------
/examples/pixiBasics/example_009.js:
--------------------------------------------------------------------------------
1 | var app = new PIXI.Application(800, 600, { transparent: true });
2 | document.body.appendChild(app.view);
3 |
4 | // Create play button that can be used to trigger the video
5 | var button = new PIXI.Graphics()
6 | .beginFill(0x0, 0.5)
7 | .drawRoundedRect(0, 0, 100, 100, 10)
8 | .endFill()
9 | .beginFill(0xffffff)
10 | .moveTo(36, 30)
11 | .lineTo(36, 70)
12 | .lineTo(70, 50);
13 |
14 | // Position the button
15 | button.x = (app.screen.width - button.width) / 2;
16 | button.y = (app.screen.height - button.height) / 2;
17 |
18 | // Enable interactivity on the button
19 | button.interactive = true;
20 | button.buttonMode = true;
21 |
22 | // Add to the stage
23 | app.stage.addChild(button);
24 |
25 | function onPlayVideo() {
26 |
27 | // Don't need the button anymore
28 | button.destroy();
29 |
30 | // create a video texture from a path
31 | var texture = PIXI.Texture.fromVideo('http://pixijs.io/examples/required/assets/testVideo.mp4');
32 |
33 | // create a new Sprite using the video texture (yes it's that easy)
34 | var videoSprite = new PIXI.Sprite(texture);
35 |
36 | // Stetch the fullscreen
37 | videoSprite.width = app.screen.width;
38 | videoSprite.height = app.screen.height;
39 |
40 | app.stage.addChild(videoSprite);
41 | }
42 |
43 | // Listen for a click/tap event to start playing the video
44 | // this is useful for some mobile platforms. For example:
45 | // ios9 and under cannot render videos in PIXI without a
46 | // polyfill - https://github.com/bfred-it/iphone-inline-video
47 | // ios10 and above require a click/tap event to render videos
48 | // that contain audio in PIXI. Videos with no audio track do
49 | // not have this requirement
50 | button.on('pointertap', onPlayVideo);
51 |
52 | onPlayVideo();
53 |
--------------------------------------------------------------------------------
/examples/pixiBasics/example_010.js:
--------------------------------------------------------------------------------
1 | var app = new PIXI.Application(800, 600, {backgroundColor : 0x1099bb});
2 | document.body.appendChild(app.view);
3 |
4 | var container = new PIXI.Container();
5 | app.stage.addChild(container);
6 |
7 | var texture = PIXI.Texture.fromImage('http://pixijs.io/examples/required/assets/basics/bunny.png');
8 |
9 | for (var i = 0; i < 25; i++) {
10 | var bunny = new PIXI.Sprite(texture);
11 | bunny.x = (i % 5) * 30;
12 | bunny.y = Math.floor(i / 5) * 30;
13 | bunny.rotation = Math.random() * (Math.PI * 2)
14 | container.addChild(bunny);
15 | }
16 |
17 | var brt = new PIXI.BaseRenderTexture(300, 300, PIXI.SCALE_MODES.LINEAR, 1);
18 | var rt = new PIXI.RenderTexture(brt);
19 |
20 | var sprite = new PIXI.Sprite(rt);
21 |
22 | sprite.x = 450;
23 | sprite.y = 60;
24 | app.stage.addChild(sprite);
25 |
26 | /*
27 | * All the bunnies are added to the container with the addChild method
28 | * when you do this, all the bunnies become children of the container, and when a container moves,
29 | * so do all its children.
30 | * This gives you a lot of flexibility and makes it easier to position elements on the screen
31 | */
32 | container.x = 100;
33 | container.y = 60;
34 |
35 | app.ticker.add(function() {
36 | app.renderer.render(container, rt);
37 | });
38 |
--------------------------------------------------------------------------------
/examples/pixiBasics/example_011.js:
--------------------------------------------------------------------------------
1 | var app = new PIXI.Application();
2 | document.body.appendChild(app.view);
3 |
4 | var count = 0.1;
5 |
6 | // build a rope!
7 | var ropeLength = 45;
8 |
9 | var points = [];
10 |
11 | for (var i = 0; i < 25; i++) {
12 | points.push(new PIXI.Point(i * ropeLength, 0));
13 | }
14 |
15 | var strip = new PIXI.mesh.Rope(PIXI.Texture.fromImage('http://pixijs.io/examples/required/assets/snake.png'), points);
16 |
17 | strip.x = -40;
18 | strip.y = 300;
19 |
20 | app.stage.addChild(strip);
21 |
22 | var g = new PIXI.Graphics();
23 | g.x = strip.x;
24 | g.y = strip.y;
25 | app.stage.addChild(g);
26 |
27 | function renderPoints () {
28 |
29 | g.clear();
30 |
31 | g.lineStyle(2,0xffc2c2);
32 | g.moveTo(points[0].x,points[0].y);
33 |
34 | for (var i = 1; i < points.length; i++) {
35 | g.lineTo(points[i].x,points[i].y);
36 | }
37 |
38 | for (var i = 1; i < points.length; i++) {
39 | g.beginFill(0xff0022);
40 | g.drawCircle(points[i].x,points[i].y,10);
41 | g.endFill();
42 | }
43 | }
44 |
45 | // start animating
46 | app.ticker.add(function() {
47 |
48 | count += 0.1;
49 |
50 | // make the snake
51 | for (var i = 0; i < points.length; i++) {
52 | points[i].y = Math.sin((i * 0.6) + count) * 30;
53 | points[i].x = i * ropeLength + Math.cos((i * 0.3) + count) * 20;
54 | }
55 | renderPoints();
56 | });
57 |
58 |
--------------------------------------------------------------------------------
/examples/pixiBasics/example_012.js:
--------------------------------------------------------------------------------
1 | var app = new PIXI.Application();
2 | document.body.appendChild(app.view);
3 |
4 | // Create background image
5 | var background = PIXI.Sprite.fromImage("http://pixijs.io/examples/required/assets/bkg-grass.jpg");
6 | background.width = app.screen.width;
7 | background.height = app.screen.height;
8 | app.stage.addChild(background);
9 |
10 | // Stop application wait for load to finish
11 | app.stop();
12 |
13 | var filter = new PIXI.Filter(null, null);
14 |
15 | // Handle the load completed
16 | function onLoaded (loader,res) {
17 |
18 | // Create the new filter, arguments: (vertexShader, framentSource)
19 | filter = new PIXI.Filter(null, res.shader.data);
20 |
21 | // Add the filter
22 | /* Workaround for refmt bug https://github.com/facebook/reason/issues/1895 */
23 | var filter2 = filter;
24 | background.filters = [filter2];
25 |
26 | // Resume application update
27 | app.start();
28 | }
29 |
30 | PIXI.loader.add('shader', 'http://pixijs.io/examples/required/assets/basics/shader.frag')
31 | .load(onLoaded);
32 |
33 | // Animate the filter
34 | app.ticker.add(function(delta) {
35 | filter.uniforms.customUniform += 0.04 * delta;
36 | });
37 |
38 |
--------------------------------------------------------------------------------
/examples/pixiBasicsMega.txt:
--------------------------------------------------------------------------------
1 | var app = new PIXI.Application(800, 600, {backgroundColor : 0x1099bb});
2 | document.body.appendChild(app.view);
3 |
4 | // create a new Sprite from an image path
5 | var bunny = PIXI.Sprite.fromImage('http://pixijs.io/examples/required/assets/basics/bunny.png')
6 |
7 | // center the sprite's anchor point
8 | bunny.anchor.set(0.5);
9 |
10 | // move the sprite to the center of the screen
11 | bunny.x = app.screen.width / 2;
12 | bunny.y = app.screen.height / 2;
13 |
14 | app.stage.addChild(bunny);
15 |
16 | var rotation = function(delta) {
17 | // just for fun, let's rotate mr rabbit a little
18 | // delta is 1 if running at 100% performance
19 | // creates frame-independent transformation
20 | bunny.rotation += 0.1 * delta;
21 | };
22 | rotation(0.01);
23 |
24 | // Listen for animate update
25 | app.ticker.add(rotation);
26 | var app = new PIXI.Application(800, 600, {backgroundColor : 0x1099bb});
27 | document.body.appendChild(app.view);
28 |
29 | var container = new PIXI.Container();
30 |
31 | app.stage.addChild(container);
32 |
33 | var texture = PIXI.Texture.fromImage('http://pixijs.io/examples/required/assets/basics/bunny.png');
34 |
35 | // Create a 5x5 grid of bunnies
36 | for (var i = 0; i < 25; i++) {
37 | var bunny = new PIXI.Sprite(texture);
38 | bunny.anchor.set(0.5);
39 | bunny.x = (i % 5) * 40;
40 | bunny.y = Math.floor(i / 5) * 40;
41 | container.addChild(bunny);
42 | }
43 |
44 | // Center on the screen
45 | container.x = (app.screen.width - container.width) / 2;
46 | container.y = (app.screen.height - container.height) / 2;
47 | var app = new PIXI.Application(800, 600, {backgroundColor : 0x1099bb});
48 | document.body.appendChild(app.view);
49 |
50 | var container = new PIXI.Container();
51 |
52 | app.stage.addChild(container);
53 |
54 | // Create a new texture
55 | var texture = PIXI.Texture.fromImage('http://pixijs.io/examples/required/assets/basics/bunny.png');
56 |
57 | // Create a 5x5 grid of bunnies
58 | for (var i = 0; i < 25; i++) {
59 | var bunny = new PIXI.Sprite(texture);
60 | bunny.anchor.set(0.5);
61 | bunny.x = (i % 5) * 40;
62 | bunny.y = Math.floor(i / 5) * 40;
63 | container.addChild(bunny);
64 | }
65 |
66 | // Move container to the center
67 | container.x = app.screen.width / 2;
68 | container.y = app.screen.height / 2;
69 |
70 | // Center bunny sprite in local container coordinates
71 | container.pivot.x = container.width / 2;
72 | container.pivot.y = container.height / 2;
73 |
74 | // Listen for animate update
75 | app.ticker.add(function(delta) {
76 | // rotate the container!
77 | // use delta to create frame-independent transform
78 | container.rotation -= 0.01 * delta;
79 | });
80 | var fighterApp = new PIXI.Application();
81 | document.body.appendChild(fighterApp.view);
82 |
83 | function onAssetsLoaded(loader, res)
84 | {
85 | var app = fighterApp;
86 |
87 | // create an array of textures from an image path
88 | var frames = [];
89 |
90 | for (var i = 0; i < 30; i++) {
91 | var val = i < 10 ? '0' + i : '' + i;
92 |
93 | // magically works since the spritesheet was loaded with the pixi loader
94 | frames.push(PIXI.Texture.fromFrame('rollSequence00' + val + '.png'));
95 | }
96 |
97 | // create an AnimatedSprite (brings back memories from the days of Flash, right ?)
98 | var anim = new PIXI.extras.AnimatedSprite(frames);
99 |
100 | /*
101 | * An AnimatedSprite inherits all the properties of a PIXI sprite
102 | * so you can change its position, its anchor, mask it, etc
103 | */
104 | anim.x = app.screen.width / 2;
105 | anim.y = app.screen.height / 2;
106 | anim.anchor.set(0.5);
107 | anim.animationSpeed = 0.5;
108 | anim.play();
109 |
110 | app.stage.addChild(anim);
111 |
112 | // Animate the rotation
113 | app.ticker.add(function(delta) {
114 | anim.rotation += 0.01;
115 | });
116 | }
117 |
118 | var fighterJson = 'http://pixijs.io/examples/required/assets/basics/fighter.json';
119 | /* Done near end of script instead */
120 | /*
121 | PIXI.loader
122 | .add('fighter', 'http://pixijs.io/examples/required/assets/basics/fighter.json')
123 | .load(onAssetsLoaded);
124 | */
125 | var app = new PIXI.Application(800, 600, { backgroundColor: 0x1099bb });
126 | /*
127 | console.log(app.constructor.name);
128 | */
129 | document.body.appendChild(app.view);
130 |
131 | // Scale mode for all textures, will retain pixelation
132 | PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;
133 |
134 | var sprite = PIXI.Sprite.fromImage('http://pixijs.io/examples/required/assets/basics/bunny.png');
135 |
136 | // Set the initial position
137 | sprite.anchor.set(0.5);
138 | sprite.x = app.screen.width / 2 + 0.01;
139 | sprite.y = app.screen.height / 2 + 0.01;
140 | sprite.scale.x = 1.01;
141 | sprite.scale.y = 1.01;
142 |
143 | // Opt-in to interactivity
144 | sprite.interactive = true;
145 |
146 | // Shows hand cursor
147 | sprite.buttonMode = true;
148 |
149 | /* PS: Functions are not automatically lifted and must be in order for
150 | * generated script to use them correctly. */
151 | function onClick(evt) {
152 | /* PS: Make sure your event handlers are called at least once by script */
153 | console.log(evt);
154 | sprite.scale.x *= 1.25;
155 | sprite.scale.y *= 1.25;
156 | return 0;
157 | }
158 |
159 | // Pointers normalize touch and mouse
160 | sprite.on('pointerdown', onClick);
161 |
162 | /* PS: Make sure your event handlers are called at least once by script, and
163 | * done after function passed around, like in the following line: */
164 | onClick(new Event('test'));
165 |
166 | // Alternatively, use the mouse & touch events:
167 | // sprite.on('click', onClick); // mouse-only
168 | // sprite.on('tap', onClick); // touch-only
169 |
170 | app.stage.addChild(sprite);
171 |
172 |
173 | var x = 3;
174 |
175 | x *= 2;
176 | var app = new PIXI.Application();
177 | document.body.appendChild(app.view);
178 |
179 | // create a texture from an image path
180 | var texture = PIXI.Texture.fromImage('http://pixijs.io/examples/required/assets/p2.jpeg');
181 |
182 | /* create a tiling sprite ...
183 | * requires a texture, a width and a height
184 | * in WebGL the image size should preferably be a power of two
185 | */
186 | var tilingSprite = new PIXI.extras.TilingSprite(
187 | texture,
188 | app.screen.width,
189 | app.screen.height
190 | );
191 | app.stage.addChild(tilingSprite);
192 |
193 | var count = 0.005;
194 |
195 | app.ticker.add(function() {
196 |
197 | count += 0.005;
198 |
199 | tilingSprite.tileScale.x = 2 + Math.sin(count);
200 | tilingSprite.tileScale.y = 2 + Math.cos(count);
201 |
202 | tilingSprite.tilePosition.x += 1;
203 | tilingSprite.tilePosition.y += 1;
204 | });
205 | var app = new PIXI.Application(800, 600, {backgroundColor: 0x1099bb});
206 | document.body.appendChild(app.view);
207 |
208 | var basicText = new PIXI.Text('Basic text in pixi');
209 | basicText.x = 30;
210 | basicText.y = 90;
211 |
212 | app.stage.addChild(basicText);
213 |
214 | var style = new PIXI.TextStyle({
215 | fontFamily: 'Arial',
216 | fontSize: 36,
217 | fontStyle: 'italic',
218 | fontWeight: 'bold',
219 | fill: ['#ffffff', '#00ff99'], // gradient
220 | stroke: '#4a1850',
221 | strokeThickness: 5,
222 | dropShadow: true,
223 | dropShadowColor: '#000000',
224 | dropShadowBlur: 4,
225 | dropShadowAngle: Math.PI / 6,
226 | dropShadowDistance: 6,
227 | wordWrap: true,
228 | wordWrapWidth: 440
229 | });
230 |
231 | var richText = new PIXI.Text('Rich text with a lot of options and across multiple lines', style);
232 | richText.x = 30;
233 | richText.y = 180;
234 |
235 | app.stage.addChild(richText);
236 | var app = new PIXI.Application(800, 600, { antialias: true });
237 | document.body.appendChild(app.view);
238 |
239 | var graphics = new PIXI.Graphics();
240 |
241 | // set a fill and line style
242 | graphics.beginFill(0xFF3300);
243 | graphics.lineStyle(4, 0xffd900, 1);
244 |
245 | // draw a shape
246 | graphics.moveTo(50,50);
247 | graphics.lineTo(250, 50);
248 | graphics.lineTo(100, 100);
249 | graphics.lineTo(50, 50);
250 | graphics.endFill();
251 |
252 | // set a fill and a line style again and draw a rectangle
253 | graphics.lineStyle(2, 0x0000FF, 1);
254 | graphics.beginFill(0xFF700B, 1.01);
255 | graphics.drawRect(50, 250, 120, 120);
256 |
257 | // draw a rounded rectangle
258 | graphics.lineStyle(2, 0xFF00FF, 1);
259 | graphics.beginFill(0xFF00BB, 0.25);
260 | graphics.drawRoundedRect(150, 450, 300, 100, 15);
261 | graphics.endFill();
262 |
263 | // draw a circle, set the lineStyle to zero so the circle doesn't have an outline
264 | graphics.lineStyle(0);
265 | graphics.beginFill(0xFFFF0B, 0.5);
266 | graphics.drawCircle(470, 90,60);
267 | graphics.endFill();
268 |
269 | app.stage.addChild(graphics);
270 | var app = new PIXI.Application(800, 600, { transparent: true });
271 | document.body.appendChild(app.view);
272 |
273 | // Create play button that can be used to trigger the video
274 | var button = new PIXI.Graphics()
275 | .beginFill(0x0, 0.5)
276 | .drawRoundedRect(0, 0, 100, 100, 10)
277 | .endFill()
278 | .beginFill(0xffffff)
279 | .moveTo(36, 30)
280 | .lineTo(36, 70)
281 | .lineTo(70, 50);
282 |
283 | // Position the button
284 | button.x = (app.screen.width - button.width) / 2;
285 | button.y = (app.screen.height - button.height) / 2;
286 |
287 | // Enable interactivity on the button
288 | button.interactive = true;
289 | button.buttonMode = true;
290 |
291 | // Add to the stage
292 | app.stage.addChild(button);
293 |
294 | function onPlayVideo() {
295 |
296 | // Don't need the button anymore
297 | button.destroy();
298 |
299 | // create a video texture from a path
300 | var texture = PIXI.Texture.fromVideo('http://pixijs.io/examples/required/assets/testVideo.mp4');
301 |
302 | // create a new Sprite using the video texture (yes it's that easy)
303 | var videoSprite = new PIXI.Sprite(texture);
304 |
305 | // Stetch the fullscreen
306 | videoSprite.width = app.screen.width;
307 | videoSprite.height = app.screen.height;
308 |
309 | app.stage.addChild(videoSprite);
310 | }
311 |
312 | // Listen for a click/tap event to start playing the video
313 | // this is useful for some mobile platforms. For example:
314 | // ios9 and under cannot render videos in PIXI without a
315 | // polyfill - https://github.com/bfred-it/iphone-inline-video
316 | // ios10 and above require a click/tap event to render videos
317 | // that contain audio in PIXI. Videos with no audio track do
318 | // not have this requirement
319 | button.on('pointertap', onPlayVideo);
320 |
321 | onPlayVideo();
322 | var app = new PIXI.Application(800, 600, {backgroundColor : 0x1099bb});
323 | document.body.appendChild(app.view);
324 |
325 | var container = new PIXI.Container();
326 | app.stage.addChild(container);
327 |
328 | var texture = PIXI.Texture.fromImage('http://pixijs.io/examples/required/assets/basics/bunny.png');
329 |
330 | for (var i = 0; i < 25; i++) {
331 | var bunny = new PIXI.Sprite(texture);
332 | bunny.x = (i % 5) * 30;
333 | bunny.y = Math.floor(i / 5) * 30;
334 | bunny.rotation = Math.random() * (Math.PI * 2)
335 | container.addChild(bunny);
336 | }
337 |
338 | var brt = new PIXI.BaseRenderTexture(300, 300, PIXI.SCALE_MODES.LINEAR, 1);
339 | var rt = new PIXI.RenderTexture(brt);
340 |
341 | var sprite = new PIXI.Sprite(rt);
342 |
343 | sprite.x = 450;
344 | sprite.y = 60;
345 | app.stage.addChild(sprite);
346 |
347 | /*
348 | * All the bunnies are added to the container with the addChild method
349 | * when you do this, all the bunnies become children of the container, and when a container moves,
350 | * so do all its children.
351 | * This gives you a lot of flexibility and makes it easier to position elements on the screen
352 | */
353 | container.x = 100;
354 | container.y = 60;
355 |
356 | app.ticker.add(function() {
357 | app.renderer.render(container, rt);
358 | });
359 | var app = new PIXI.Application();
360 | document.body.appendChild(app.view);
361 |
362 | var count = 0.1;
363 |
364 | // build a rope!
365 | var ropeLength = 45;
366 |
367 | var points = [];
368 |
369 | for (var i = 0; i < 25; i++) {
370 | points.push(new PIXI.Point(i * ropeLength, 0));
371 | }
372 |
373 | var strip = new PIXI.mesh.Rope(PIXI.Texture.fromImage('http://pixijs.io/examples/required/assets/snake.png'), points);
374 |
375 | strip.x = -40;
376 | strip.y = 300;
377 |
378 | app.stage.addChild(strip);
379 |
380 | var g = new PIXI.Graphics();
381 | g.x = strip.x;
382 | g.y = strip.y;
383 | app.stage.addChild(g);
384 |
385 | function renderPoints () {
386 |
387 | g.clear();
388 |
389 | g.lineStyle(2,0xffc2c2);
390 | g.moveTo(points[0].x,points[0].y);
391 |
392 | for (var i = 1; i < points.length; i++) {
393 | g.lineTo(points[i].x,points[i].y);
394 | }
395 |
396 | for (var i = 1; i < points.length; i++) {
397 | g.beginFill(0xff0022);
398 | g.drawCircle(points[i].x,points[i].y,10);
399 | g.endFill();
400 | }
401 | }
402 |
403 | // start animating
404 | app.ticker.add(function() {
405 |
406 | count += 0.1;
407 |
408 | // make the snake
409 | for (var i = 0; i < points.length; i++) {
410 | points[i].y = Math.sin((i * 0.6) + count) * 30;
411 | points[i].x = i * ropeLength + Math.cos((i * 0.3) + count) * 20;
412 | }
413 | renderPoints();
414 | });
415 |
416 | setTimeout(function() {
417 | var app = new PIXI.Application();
418 | document.body.appendChild(app.view);
419 |
420 | // Create background image
421 | var background = PIXI.Sprite.fromImage("http://pixijs.io/examples/required/assets/bkg-grass.jpg");
422 | background.width = app.screen.width;
423 | background.height = app.screen.height;
424 | app.stage.addChild(background);
425 |
426 | // Stop application wait for load to finish
427 | app.stop();
428 |
429 | var filter = new PIXI.Filter(null, null);
430 |
431 | // Handle the load completed
432 | function onLoaded(loader, res) {
433 | // Create the new filter, arguments: (vertexShader, framentSource)
434 | filter = new PIXI.Filter(null, res.shader.data);
435 |
436 | // Add the filter
437 | /* Workaround for refmt bug https://github.com/facebook/reason/issues/1895 */
438 | var filter2 = filter;
439 | background.filters = [filter2];
440 |
441 | // Resume application update
442 | app.start();
443 | }
444 |
445 | PIXI.loader
446 | .add('fighter', fighterJson)
447 | .add('shader', 'http://pixijs.io/examples/required/assets/basics/shader.frag')
448 | .load(function(loader, res) {
449 | onAssetsLoaded(loader, res);
450 | onLoaded(loader, res);
451 | });
452 |
453 | // Animate the filter
454 | app.ticker.add(function(delta) {
455 | filter.uniforms.customUniform += 0.04 * delta;
456 | });
457 | }, 0);
458 |
--------------------------------------------------------------------------------
/experiments/flowtest.js:
--------------------------------------------------------------------------------
1 | var app = new PIXI.Application(800, 600, { backgroundColor: 0x1099bb });
2 | /*
3 | console.log(app.constructor.name);
4 | */
5 | document.body.appendChild(app.view);
6 |
7 | // Scale mode for all textures, will retain pixelation
8 | PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;
9 |
10 | var sprite = PIXI.Sprite.fromImage('http://pixijs.io/examples/required/assets/basics/bunny.png');
11 |
12 | // Set the initial position
13 | sprite.anchor.set(0.5);
14 | sprite.x = app.screen.width / 2;
15 | sprite.y = app.screen.height / 2;
16 |
17 | // Opt-in to interactivity
18 | sprite.interactive = true;
19 |
20 | // Shows hand cursor
21 | sprite.buttonMode = true;
22 |
23 | /* PS: Functions are not automatically lifted and must be in order for
24 | * generated script to use them correctly. */
25 | function onClick(evt) {
26 | /* PS: Make sure your event handlers are called at least once by script */
27 | console.log(evt);
28 | sprite.scale.x *= 1.25;
29 | sprite.scale.y *= 1.25;
30 | return 0;
31 | }
32 |
33 | // Pointers normalize touch and mouse
34 | sprite.on('pointerdown', onClick);
35 |
36 | /* PS: Make sure your event handlers are called at least once by script, and
37 | * done after function passed around, like in the following line: */
38 | onClick(new Event('test'));
39 |
40 | // Alternatively, use the mouse & touch events:
41 | // sprite.on('click', onClick); // mouse-only
42 | // sprite.on('tap', onClick); // touch-only
43 |
44 | app.stage.addChild(sprite);
45 |
46 | if (true) {
47 | console.log("hello");
48 | } else {
49 | console.log("blah");
50 | }
51 |
52 | var x = 3;
53 |
54 | x *= 2;
55 |
--------------------------------------------------------------------------------
/experiments/types.sh:
--------------------------------------------------------------------------------
1 | file=flowtest.js
2 | lib=node_modules/pixi.js/dist/pixi.js
3 | cat $lib $file > flowtest-pixi.js
4 | baseline=$(wc -l $lib | cut -f1 -d" ")
5 | line=$baseline
6 | cat $file | while read lineContents; do
7 | line=$(($line + 1))
8 | char=0
9 | for char in `seq 0 $(echo $lineContents | wc -L)`; do
10 | echo node node_modules/.bin/flow type-at-pos $file $line $char
11 | # see https://github.com/facebook/flow/issues/248
12 | node node_modules/.bin/flow type-at-pos flowtest-pixi.js $line $char
13 | done
14 | done
15 |
--------------------------------------------------------------------------------
/index-dev.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Welcome to my very hacky JavaScript to ReasonML transpiler ' + 36 | '(Project on GitHub)! ' + 37 | 'If you do not see any code below, try reloading the page ' + 38 | '(bug due to race conditions resolved by cached files I suppose).' + 39 | 'You might also check out the alternative Jeason. ' + 40 | 'Paste your code in the Code to Transpile ' + 41 | 'and the script will try to convert it into ReasonML externs and code. ' + 42 | 'WARNING: Example code will be evaled in a rewritten form to fill in the types. ' + 43 | 'Untriggered event handlers and functions will not be translated. ' + 44 | 'Just some basics are supported for now, and it is sure to be buggy, ' + 45 | 'but it might be more helpful than starting from scratch.
' + 46 | 'Make sure your example code does not clear the DOM, or you will lose the output boxes.
' + 47 | 'While you are transpiling there will be a red border around ' + 48 | ' code with unresolved types in the editor.
' 49 | ); 50 | 51 | $('body').append('Paste extra library code here. ' + 62 | 'Will be evaluated for example code to use, but not attempted translated. ' + 63 | '