├── .babelrc
├── .eslintignore
├── .eslintrc.js
├── .github
└── workflows
│ ├── test-phaser-3.yml
│ └── test-phaser-ce.yml
├── .gitignore
├── LICENSE
├── README.md
├── assets
├── diagram.png
├── diagram_column.png
├── diagram_quantitybar.png
├── diagram_row.png
├── diagram_valuebar.png
└── diagram_wheel3D.png
├── docs
├── assets
│ ├── anchor.js
│ ├── bass-addons.css
│ ├── bass.css
│ ├── fonts
│ │ ├── EOT
│ │ │ ├── SourceCodePro-Bold.eot
│ │ │ └── SourceCodePro-Regular.eot
│ │ ├── LICENSE.txt
│ │ ├── OTF
│ │ │ ├── SourceCodePro-Bold.otf
│ │ │ └── SourceCodePro-Regular.otf
│ │ ├── TTF
│ │ │ ├── SourceCodePro-Bold.ttf
│ │ │ └── SourceCodePro-Regular.ttf
│ │ ├── WOFF
│ │ │ ├── OTF
│ │ │ │ ├── SourceCodePro-Bold.otf.woff
│ │ │ │ └── SourceCodePro-Regular.otf.woff
│ │ │ └── TTF
│ │ │ │ ├── SourceCodePro-Bold.ttf.woff
│ │ │ │ └── SourceCodePro-Regular.ttf.woff
│ │ ├── WOFF2
│ │ │ ├── OTF
│ │ │ │ ├── SourceCodePro-Bold.otf.woff2
│ │ │ │ └── SourceCodePro-Regular.otf.woff2
│ │ │ └── TTF
│ │ │ │ ├── SourceCodePro-Bold.ttf.woff2
│ │ │ │ └── SourceCodePro-Regular.ttf.woff2
│ │ └── source-code-pro.css
│ ├── github.css
│ ├── site.js
│ ├── split.css
│ ├── split.js
│ └── style.css
├── examples
│ ├── assets
│ │ ├── horizontal
│ │ │ ├── bar.png
│ │ │ ├── sprite.png
│ │ │ └── track.png
│ │ ├── modal
│ │ │ ├── background.png
│ │ │ └── button.png
│ │ ├── quantitybar
│ │ │ ├── add.png
│ │ │ ├── horizontal
│ │ │ │ ├── bar.png
│ │ │ │ └── track.png
│ │ │ ├── subtract.png
│ │ │ └── vertical
│ │ │ │ ├── bar.png
│ │ │ │ └── track.png
│ │ ├── textover
│ │ │ ├── button.png
│ │ │ └── header.png
│ │ ├── valuebar
│ │ │ ├── alpha.png
│ │ │ ├── background.png
│ │ │ ├── bar.png
│ │ │ ├── pointer.png
│ │ │ ├── track.png
│ │ │ └── vtrack.png
│ │ ├── vertical
│ │ │ ├── bar.png
│ │ │ ├── sprite.png
│ │ │ └── track.png
│ │ └── wheel3D
│ │ │ ├── icon.png
│ │ │ ├── mmDown.png
│ │ │ └── mmUp.png
│ ├── html
│ │ ├── phaser3
│ │ │ ├── hscrollbar.html
│ │ │ ├── modal.html
│ │ │ ├── quantitybar.html
│ │ │ ├── textover.html
│ │ │ ├── valuebar.html
│ │ │ ├── vscrollbar.html
│ │ │ └── wheel3D.html
│ │ └── phaserce
│ │ │ ├── hscrollbar.html
│ │ │ ├── modal.html
│ │ │ ├── quantitybar.html
│ │ │ ├── quantitybar_column.html
│ │ │ ├── textover.html
│ │ │ ├── valuebar.html
│ │ │ ├── valuebar_column.html
│ │ │ ├── vscrollbar.html
│ │ │ └── wheel3D.html
│ ├── js
│ │ ├── phaser3
│ │ │ ├── hscrollbar.js
│ │ │ ├── modal.js
│ │ │ ├── quantitybar.js
│ │ │ ├── textover.js
│ │ │ ├── valuebar.js
│ │ │ ├── vscrollbar.js
│ │ │ └── wheel3D.js
│ │ └── phaserce
│ │ │ ├── hscrollbar.js
│ │ │ ├── modal.js
│ │ │ ├── quantitybar.js
│ │ │ ├── quantitybar_column.js
│ │ │ ├── textover.js
│ │ │ ├── valuebar.js
│ │ │ ├── valuebar_column.js
│ │ │ ├── vscrollbar.js
│ │ │ └── wheel3D.js
│ └── lib
│ │ ├── phaser-ui-tools.js
│ │ ├── phaser.min.js
│ │ └── phaser3.min.js
└── index.html
├── package-lock.json
├── package.json
├── src
├── bars
│ ├── bar.js
│ ├── draggable_bar.js
│ ├── quantitybar.js
│ ├── ranges.js
│ ├── scrollbar.js
│ └── valuebar.js
├── buttons.js
├── const.js
├── containers
│ ├── column.js
│ ├── frame.js
│ ├── row.js
│ └── viewport.js
├── entry.js
├── keyboard_group.js
├── phaserObjects
│ ├── button.js
│ ├── easing.js
│ ├── graphics.js
│ ├── group.js
│ ├── index.js
│ ├── keyboard.js
│ ├── keycodes.js
│ ├── rectangle.js
│ ├── sprite.js
│ ├── tween.js
│ └── viewport_mask.js
├── utils.js
└── wheel3D.js
├── tests
├── column.spec.js
├── frame.spec.js
├── row.spec.js
├── testrunner.html
├── testrunner_phaser3.html
├── viewport.spec.js
└── wheel3D.spec.js
└── webpack.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["@babel/preset-env", {
4 | "modules": false
5 | }]
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | /dist
2 | /docs
3 | /node_modules
4 | /tests
5 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "extends": "airbnb-base",
3 | "rules": {
4 | "indent": ["error", 4],
5 | "linebreak-style": 0,
6 | "no-plusplus": ["error", {"allowForLoopAfterthoughts": true}],
7 | "import/prefer-default-export": "off",
8 | "max-len": ["error", {"ignoreComments": true}],
9 | "object-curly-newline": ["error", {"ObjectPattern": {"multiline": true}}],
10 | "no-lonely-if": "off",
11 | "max-len": "off",
12 | "max-classes-per-file": "off",
13 | },
14 | "parserOptions": {
15 | "sourceType": "module",
16 | },
17 | "globals": {
18 | "Phaser": true,
19 | }
20 | };
21 |
--------------------------------------------------------------------------------
/.github/workflows/test-phaser-3.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | name: test-phaser-3
4 |
5 | on:
6 | push:
7 | branches:
8 | - master
9 | pull_request:
10 | branches:
11 | - master
12 |
13 | jobs:
14 | build:
15 | runs-on: ubuntu-latest
16 | name: unit-tests
17 |
18 | strategy:
19 | matrix:
20 | node-version: [14.x]
21 |
22 | steps:
23 | - name: Checkout Repository
24 | uses: actions/checkout@v2
25 | with:
26 | fetch-depth: 1
27 |
28 | - name: Setup Node ${{ matrix.node-version }}
29 | uses: actions/setup-node@v2
30 | with:
31 | always-auth: false
32 | node-version: ${{ matrix.node-version }}
33 |
34 | - name: Run npm install
35 | run: npm install
36 |
37 | - name: Build js
38 | run: npm run build:js
39 |
40 | - name: Run tests
41 | run: npm run test3
42 | env:
43 | CI: true
44 |
--------------------------------------------------------------------------------
/.github/workflows/test-phaser-ce.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | name: test-phaser-ce
4 |
5 | on:
6 | push:
7 | branches:
8 | - master
9 | pull_request:
10 | branches:
11 | - master
12 |
13 | jobs:
14 | build:
15 | runs-on: ubuntu-latest
16 | name: unit-tests
17 |
18 | strategy:
19 | matrix:
20 | node-version: [14.x]
21 |
22 | steps:
23 | - name: Checkout Repository
24 | uses: actions/checkout@v2
25 | with:
26 | fetch-depth: 1
27 |
28 | - name: Setup Node ${{ matrix.node-version }}
29 | uses: actions/setup-node@v2
30 | with:
31 | always-auth: false
32 | node-version: ${{ matrix.node-version }}
33 |
34 | - name: Run npm install
35 | run: npm install
36 |
37 | - name: Build js
38 | run: npm run build:js
39 |
40 | - name: Run tests
41 | run: npm run test
42 | env:
43 | CI: true
44 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dist/*
2 | node_modules/
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Joshua Fehler
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Phaser UI Tools
2 |
3 | [](https://github.com/jsfehler/phaser-ui-tools/actions/workflows/test-phaser-3.yml)
4 |
5 | [](https://github.com/jsfehler/phaser-ui-tools/actions/workflows/test-phaser-ce.yml)
6 |
7 |
8 | I really wanted a viewport with a scrollbar. Things escalated.
9 |
10 | 
11 |
12 | ### Documentation
13 | https://jsfehler.github.io/phaser-ui-tools/
14 |
15 | ### References
16 | Scrollbar math:
17 | http://csdgn.org/article/scrollbar
18 |
19 |
20 | ### Getting Started
21 |
22 | #### Using NPM
23 | On the command line, type:
24 | ```
25 | npm i phaser-ui-tools
26 | ```
27 |
28 | The objects are now available via import:
29 | ```
30 | import { Column } from 'phaser-ui-tools';
31 |
32 | var column = new Column(...)
33 |
34 | ```
35 |
36 | #### Adding the file directly to your project
37 | Get phaser-ui-tools.js from the releases and add it to your project's index.html.
38 | It should look something like:
39 | ```
40 |
41 | ```
42 |
43 | The objects can now be used directly:
44 |
45 | ```
46 | var column = new uiWidgets.Column(...)
47 | ```
48 |
49 |
50 | ### The Tools
51 |
52 | #### Text Overlays
53 |
54 | ##### TextSprite
55 | A sprite that can have text on top.
56 |
57 | Text is added with the setText() method.
58 |
59 | ```javascript
60 | var textSprite = new uiWidgets.TextSprite(
61 | game, x, y, key,
62 | );
63 | textSprite.setText(label, style);
64 | ```
65 |
66 | ##### TextButton
67 | A button that can have text on top.
68 |
69 | Text is added with the setText() method.
70 |
71 | ```javascript
72 | var textButton = new uiWidgets.TextButton(
73 | game, x, y, key, callback, callbackContext, overKey, outKey, downKey, upKey,
74 | );
75 | textButton.setText(label, style);
76 | ```
77 |
78 | ##### Examples
79 |
80 | ###### Phaser CE
81 | [Header & Buttons](https://jsfehler.github.io/phaser-ui-tools/examples/html/phaserce/textover.html) | [Code](https://jsfehler.github.io/phaser-ui-tools/examples/js/phaserce/textover.js)
82 |
83 | ###### Phaser 3
84 | [Header & Buttons](https://jsfehler.github.io/phaser-ui-tools/examples/html/phaser3/textover.html) | [Code](https://jsfehler.github.io/phaser-ui-tools/examples/js/phaser3/textover.js)
85 |
86 | #### Containers
87 |
88 | ##### Column
89 |
90 | Columns are Phaser Groups where each child added to the group is placed directly under the previous child. If an object can be a child of a Group, it can likewise be in a Column.
91 |
92 | 
93 | ```javascript
94 | var column = new uiWidgets.Column(game, 8, 8);
95 | column.addNode(sprite_a, 8, 8);
96 | column.addNode(sprite_b, 8, 8);
97 | column.addNode(sprite_c, 8, 8);
98 | ```
99 |
100 | ##### Row
101 |
102 | Rows are Phaser Groups where each child added to the group is placed directly next to the previous child. If an object can be a child of a Group, it can likewise be in a Row.
103 |
104 | 
105 | ```javascript
106 | var row = new uiWidgets.Row(game, 8, 8);
107 | row.addNode(sprite_a, 8, 8);
108 | row.addNode(sprite_b, 8, 8);
109 | row.addNode(sprite_c, 8, 8);
110 | ```
111 |
112 | ##### Viewport
113 | Viewports are Phaser Groups where the children in the group are only visible if they're within the viewport's area.
114 | If an object can be a child of a Group, it can likewise be in a Viewport.
115 |
116 | Viewports can be combined with a Scrollbar to create a scrollable display.
117 |
118 | Placing a Column or Row inside a Viewport is a simple way to align content.
119 |
120 | ```javascript
121 | var viewport = new uiWidgets.Viewport(game, 75, 75, 600, 260);
122 | viewport.addNode(column);
123 | ```
124 |
125 | #### Bars
126 |
127 | ##### Scrollbar
128 | Scrollbars are used to move the objects in a Viewport. They must be used with a Viewport.
129 | A tweening duration and easing can be specified. This will be triggered when moving the bar.
130 |
131 | ```javascript
132 | var scrollbar = new uiWidgets.Scrollbar(
133 | game,
134 | viewport,
135 | true,
136 | true,
137 | true,
138 | trackImage,
139 | barImage,
140 | {'duration': 300, 'ease': Phaser.Easing.Quadratic.Out}
141 | );
142 | ```
143 |
144 | ##### Examples
145 |
146 | ###### Phaser CE
147 |
148 | [Vertical](https://jsfehler.github.io/phaser-ui-tools/examples/html/phaserce/vscrollbar.html) | [Code](https://jsfehler.github.io/phaser-ui-tools/examples/js/phaserce/vscrollbar.js)
149 |
150 | [Horizontal](https://jsfehler.github.io/phaser-ui-tools/examples/html/phaserce/hscrollbar.html) | [Code](https://jsfehler.github.io/phaser-ui-tools/examples/js/phaserce/hscrollbar.js)
151 |
152 | ###### Phaser 3
153 |
154 | [Vertical](https://jsfehler.github.io/phaser-ui-tools/examples/html/phaser3/vscrollbar.html) | [Code](https://jsfehler.github.io/phaser-ui-tools/examples/js/phaser3/vscrollbar.js)
155 |
156 | [Horizontal](https://jsfehler.github.io/phaser-ui-tools/examples/html/phaser3/hscrollbar.html) | [Code](https://jsfehler.github.io/phaser-ui-tools/examples/js/phaser3/hscrollbar.js)
157 |
158 |
159 | ##### ValueBar
160 | Valuebars are like Scrollbars, but instead of moving content, they increase/decrease a number.
161 | Valuebars always have a minimum number of 0, but the starting and maximum number can be set.
162 | A tweening duration and easing can be specified. This will be triggered when moving the bar.
163 |
164 | 
165 |
166 | ```javascript
167 | var valuebar = new uiWidgets.ValueBar(
168 | game,
169 | {'x': 50, 'y': 10},
170 | {'step': 1, 'startValue': 0, 'maxValue': 100},
171 | true,
172 | false,
173 | true,
174 | trackImage,
175 | barImage,
176 | {'duration': 100, 'ease': Phaser.Easing.Quadratic.Out}
177 | );
178 | ```
179 |
180 | ##### Examples
181 |
182 | ###### Phaser CE
183 |
184 | [ValueBar](https://jsfehler.github.io/phaser-ui-tools/examples/html/phaserce/valuebar.html) | [Code](https://jsfehler.github.io/phaser-ui-tools/examples/js/phaserce/valuebar.js)
185 |
186 | [Multiple ValueBar inside a Column, with background image and keyboard events](https://jsfehler.github.io/phaser-ui-tools/examples/html/phaserce/valuebar_column.html) | [Code](https://jsfehler.github.io/phaser-ui-tools/examples/js/phaserce/valuebar_column.js)
187 |
188 | ###### Phaser 3
189 |
190 | [ValueBar](https://jsfehler.github.io/phaser-ui-tools/examples/html/phaser3/valuebar.html) | [Code](https://jsfehler.github.io/phaser-ui-tools/examples/js/phaser3/valuebar.js)
191 |
192 |
193 | ##### QuantityBar
194 | QuantityBars do not adjust a value, they get adjusted by a value. The bar grows and shrinks based on a value.
195 | They can be used for health bars, stamina bars, etc.
196 | A tweening duration and easing can be specified. This will be triggered when moving the bar.
197 |
198 | 
199 |
200 | ```javascript
201 | var quantitybar = new uiWidgets.QuantityBar(
202 | game,
203 | {'x': 50, 'y': 10},
204 | {'startValue': 50, 'maxValue': 100},
205 | false,
206 | false,
207 | trackImage,
208 | barImage,
209 | {'duration': 400, 'ease': Phaser.Easing.Quadratic.Out}
210 | );
211 | ```
212 |
213 | ##### Examples
214 |
215 | ###### Phaser CE
216 |
217 | [QuantityBar](https://jsfehler.github.io/phaser-ui-tools/examples/html/phaserce/quantitybar.html) | [Code](https://jsfehler.github.io/phaser-ui-tools/examples/js/phaserce/quantitybar.js)
218 |
219 | ###### Phaser 3
220 |
221 | [QuantityBar](https://jsfehler.github.io/phaser-ui-tools/examples/html/phaser3/quantitybar.html) | [Code](https://jsfehler.github.io/phaser-ui-tools/examples/js/phaser3/quantitybar.js)
222 |
223 |
224 | #### Wheel3D
225 | A collection of sprites that are arranged around a three dimensional wheel.
226 | The wheel can be adjusted and rotated along the x, y, or z axis.
227 |
228 | 
229 |
230 | ```javascript
231 | var wheel = new uiWidgets.Wheel3D(
232 | game,
233 | {"x": game.world.centerX - 100, "y": game.world.centerY},
234 | [sprite1, sprite2, sprite3, sprite4],
235 | 0,
236 | 90,
237 | "y",
238 | {"x":0, "y": 0, "z": 0}
239 | );
240 | ```
241 |
242 | ##### Examples
243 |
244 | ###### Phaser CE
245 |
246 | [Wheel3D](https://jsfehler.github.io/phaser-ui-tools/examples/html/phaserce/wheel3D.html) | [Code](https://jsfehler.github.io/phaser-ui-tools/examples/js/phaserce/wheel3D.js)
247 |
248 | ###### Phaser 3
249 |
250 | [Wheel3D](https://jsfehler.github.io/phaser-ui-tools/examples/html/phaser3/wheel3D.html) | [Code](https://jsfehler.github.io/phaser-ui-tools/examples/js/phaser3/wheel3D.js)
251 |
--------------------------------------------------------------------------------
/assets/diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/assets/diagram.png
--------------------------------------------------------------------------------
/assets/diagram_column.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/assets/diagram_column.png
--------------------------------------------------------------------------------
/assets/diagram_quantitybar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/assets/diagram_quantitybar.png
--------------------------------------------------------------------------------
/assets/diagram_row.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/assets/diagram_row.png
--------------------------------------------------------------------------------
/assets/diagram_valuebar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/assets/diagram_valuebar.png
--------------------------------------------------------------------------------
/assets/diagram_wheel3D.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/assets/diagram_wheel3D.png
--------------------------------------------------------------------------------
/docs/assets/bass-addons.css:
--------------------------------------------------------------------------------
1 | .input {
2 | font-family: inherit;
3 | display: block;
4 | width: 100%;
5 | height: 2rem;
6 | padding: .5rem;
7 | margin-bottom: 1rem;
8 | border: 1px solid #ccc;
9 | font-size: .875rem;
10 | border-radius: 3px;
11 | box-sizing: border-box;
12 | }
13 |
--------------------------------------------------------------------------------
/docs/assets/fonts/EOT/SourceCodePro-Bold.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/assets/fonts/EOT/SourceCodePro-Bold.eot
--------------------------------------------------------------------------------
/docs/assets/fonts/EOT/SourceCodePro-Regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/assets/fonts/EOT/SourceCodePro-Regular.eot
--------------------------------------------------------------------------------
/docs/assets/fonts/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
2 |
3 | This Font Software is licensed under the SIL Open Font License, Version 1.1.
4 |
5 | This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
6 |
7 |
8 | -----------------------------------------------------------
9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10 | -----------------------------------------------------------
11 |
12 | PREAMBLE
13 | The goals of the Open Font License (OFL) are to stimulate worldwide
14 | development of collaborative font projects, to support the font creation
15 | efforts of academic and linguistic communities, and to provide a free and
16 | open framework in which fonts may be shared and improved in partnership
17 | with others.
18 |
19 | The OFL allows the licensed fonts to be used, studied, modified and
20 | redistributed freely as long as they are not sold by themselves. The
21 | fonts, including any derivative works, can be bundled, embedded,
22 | redistributed and/or sold with any software provided that any reserved
23 | names are not used by derivative works. The fonts and derivatives,
24 | however, cannot be released under any other type of license. The
25 | requirement for fonts to remain under this license does not apply
26 | to any document created using the fonts or their derivatives.
27 |
28 | DEFINITIONS
29 | "Font Software" refers to the set of files released by the Copyright
30 | Holder(s) under this license and clearly marked as such. This may
31 | include source files, build scripts and documentation.
32 |
33 | "Reserved Font Name" refers to any names specified as such after the
34 | copyright statement(s).
35 |
36 | "Original Version" refers to the collection of Font Software components as
37 | distributed by the Copyright Holder(s).
38 |
39 | "Modified Version" refers to any derivative made by adding to, deleting,
40 | or substituting -- in part or in whole -- any of the components of the
41 | Original Version, by changing formats or by porting the Font Software to a
42 | new environment.
43 |
44 | "Author" refers to any designer, engineer, programmer, technical
45 | writer or other person who contributed to the Font Software.
46 |
47 | PERMISSION & CONDITIONS
48 | Permission is hereby granted, free of charge, to any person obtaining
49 | a copy of the Font Software, to use, study, copy, merge, embed, modify,
50 | redistribute, and sell modified and unmodified copies of the Font
51 | Software, subject to the following conditions:
52 |
53 | 1) Neither the Font Software nor any of its individual components,
54 | in Original or Modified Versions, may be sold by itself.
55 |
56 | 2) Original or Modified Versions of the Font Software may be bundled,
57 | redistributed and/or sold with any software, provided that each copy
58 | contains the above copyright notice and this license. These can be
59 | included either as stand-alone text files, human-readable headers or
60 | in the appropriate machine-readable metadata fields within text or
61 | binary files as long as those fields can be easily viewed by the user.
62 |
63 | 3) No Modified Version of the Font Software may use the Reserved Font
64 | Name(s) unless explicit written permission is granted by the corresponding
65 | Copyright Holder. This restriction only applies to the primary font name as
66 | presented to the users.
67 |
68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69 | Software shall not be used to promote, endorse or advertise any
70 | Modified Version, except to acknowledge the contribution(s) of the
71 | Copyright Holder(s) and the Author(s) or with their explicit written
72 | permission.
73 |
74 | 5) The Font Software, modified or unmodified, in part or in whole,
75 | must be distributed entirely under this license, and must not be
76 | distributed under any other license. The requirement for fonts to
77 | remain under this license does not apply to any document created
78 | using the Font Software.
79 |
80 | TERMINATION
81 | This license becomes null and void if any of the above conditions are
82 | not met.
83 |
84 | DISCLAIMER
85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93 | OTHER DEALINGS IN THE FONT SOFTWARE.
94 |
--------------------------------------------------------------------------------
/docs/assets/fonts/OTF/SourceCodePro-Bold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/assets/fonts/OTF/SourceCodePro-Bold.otf
--------------------------------------------------------------------------------
/docs/assets/fonts/OTF/SourceCodePro-Regular.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/assets/fonts/OTF/SourceCodePro-Regular.otf
--------------------------------------------------------------------------------
/docs/assets/fonts/TTF/SourceCodePro-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/assets/fonts/TTF/SourceCodePro-Bold.ttf
--------------------------------------------------------------------------------
/docs/assets/fonts/TTF/SourceCodePro-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/assets/fonts/TTF/SourceCodePro-Regular.ttf
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2
--------------------------------------------------------------------------------
/docs/assets/fonts/source-code-pro.css:
--------------------------------------------------------------------------------
1 | @font-face{
2 | font-family: 'Source Code Pro';
3 | font-weight: 400;
4 | font-style: normal;
5 | font-stretch: normal;
6 | src: url('EOT/SourceCodePro-Regular.eot') format('embedded-opentype'),
7 | url('WOFF2/TTF/SourceCodePro-Regular.ttf.woff2') format('woff2'),
8 | url('WOFF/OTF/SourceCodePro-Regular.otf.woff') format('woff'),
9 | url('OTF/SourceCodePro-Regular.otf') format('opentype'),
10 | url('TTF/SourceCodePro-Regular.ttf') format('truetype');
11 | }
12 |
13 | @font-face{
14 | font-family: 'Source Code Pro';
15 | font-weight: 700;
16 | font-style: normal;
17 | font-stretch: normal;
18 | src: url('EOT/SourceCodePro-Bold.eot') format('embedded-opentype'),
19 | url('WOFF2/TTF/SourceCodePro-Bold.ttf.woff2') format('woff2'),
20 | url('WOFF/OTF/SourceCodePro-Bold.otf.woff') format('woff'),
21 | url('OTF/SourceCodePro-Bold.otf') format('opentype'),
22 | url('TTF/SourceCodePro-Bold.ttf') format('truetype');
23 | }
24 |
--------------------------------------------------------------------------------
/docs/assets/github.css:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | github.com style (c) Vasily Polovnyov
4 |
5 | */
6 |
7 | .hljs {
8 | display: block;
9 | overflow-x: auto;
10 | padding: 0.5em;
11 | color: #333;
12 | background: #f8f8f8;
13 | -webkit-text-size-adjust: none;
14 | }
15 |
16 | .hljs-comment,
17 | .diff .hljs-header,
18 | .hljs-javadoc {
19 | color: #998;
20 | font-style: italic;
21 | }
22 |
23 | .hljs-keyword,
24 | .css .rule .hljs-keyword,
25 | .hljs-winutils,
26 | .nginx .hljs-title,
27 | .hljs-subst,
28 | .hljs-request,
29 | .hljs-status {
30 | color: #1184CE;
31 | }
32 |
33 | .hljs-number,
34 | .hljs-hexcolor,
35 | .ruby .hljs-constant {
36 | color: #ed225d;
37 | }
38 |
39 | .hljs-string,
40 | .hljs-tag .hljs-value,
41 | .hljs-phpdoc,
42 | .hljs-dartdoc,
43 | .tex .hljs-formula {
44 | color: #ed225d;
45 | }
46 |
47 | .hljs-title,
48 | .hljs-id,
49 | .scss .hljs-preprocessor {
50 | color: #900;
51 | font-weight: bold;
52 | }
53 |
54 | .hljs-list .hljs-keyword,
55 | .hljs-subst {
56 | font-weight: normal;
57 | }
58 |
59 | .hljs-class .hljs-title,
60 | .hljs-type,
61 | .vhdl .hljs-literal,
62 | .tex .hljs-command {
63 | color: #458;
64 | font-weight: bold;
65 | }
66 |
67 | .hljs-tag,
68 | .hljs-tag .hljs-title,
69 | .hljs-rules .hljs-property,
70 | .django .hljs-tag .hljs-keyword {
71 | color: #000080;
72 | font-weight: normal;
73 | }
74 |
75 | .hljs-attribute,
76 | .hljs-variable,
77 | .lisp .hljs-body {
78 | color: #008080;
79 | }
80 |
81 | .hljs-regexp {
82 | color: #009926;
83 | }
84 |
85 | .hljs-symbol,
86 | .ruby .hljs-symbol .hljs-string,
87 | .lisp .hljs-keyword,
88 | .clojure .hljs-keyword,
89 | .scheme .hljs-keyword,
90 | .tex .hljs-special,
91 | .hljs-prompt {
92 | color: #990073;
93 | }
94 |
95 | .hljs-built_in {
96 | color: #0086b3;
97 | }
98 |
99 | .hljs-preprocessor,
100 | .hljs-pragma,
101 | .hljs-pi,
102 | .hljs-doctype,
103 | .hljs-shebang,
104 | .hljs-cdata {
105 | color: #999;
106 | font-weight: bold;
107 | }
108 |
109 | .hljs-deletion {
110 | background: #fdd;
111 | }
112 |
113 | .hljs-addition {
114 | background: #dfd;
115 | }
116 |
117 | .diff .hljs-change {
118 | background: #0086b3;
119 | }
120 |
121 | .hljs-chunk {
122 | color: #aaa;
123 | }
124 |
--------------------------------------------------------------------------------
/docs/assets/site.js:
--------------------------------------------------------------------------------
1 | /* global anchors */
2 |
3 | // add anchor links to headers
4 | anchors.options.placement = 'left';
5 | anchors.add('h3');
6 |
7 | // Filter UI
8 | var tocElements = document.getElementById('toc').getElementsByTagName('li');
9 |
10 | document.getElementById('filter-input').addEventListener('keyup', function(e) {
11 | var i, element, children;
12 |
13 | // enter key
14 | if (e.keyCode === 13) {
15 | // go to the first displayed item in the toc
16 | for (i = 0; i < tocElements.length; i++) {
17 | element = tocElements[i];
18 | if (!element.classList.contains('display-none')) {
19 | location.replace(element.firstChild.href);
20 | return e.preventDefault();
21 | }
22 | }
23 | }
24 |
25 | var match = function() {
26 | return true;
27 | };
28 |
29 | var value = this.value.toLowerCase();
30 |
31 | if (!value.match(/^\s*$/)) {
32 | match = function(element) {
33 | var html = element.firstChild.innerHTML;
34 | return html && html.toLowerCase().indexOf(value) !== -1;
35 | };
36 | }
37 |
38 | for (i = 0; i < tocElements.length; i++) {
39 | element = tocElements[i];
40 | children = Array.from(element.getElementsByTagName('li'));
41 | if (match(element) || children.some(match)) {
42 | element.classList.remove('display-none');
43 | } else {
44 | element.classList.add('display-none');
45 | }
46 | }
47 | });
48 |
49 | var items = document.getElementsByClassName('toggle-sibling');
50 | for (var j = 0; j < items.length; j++) {
51 | items[j].addEventListener('click', toggleSibling);
52 | }
53 |
54 | function toggleSibling() {
55 | var stepSibling = this.parentNode.getElementsByClassName('toggle-target')[0];
56 | var icon = this.getElementsByClassName('icon')[0];
57 | var klass = 'display-none';
58 | if (stepSibling.classList.contains(klass)) {
59 | stepSibling.classList.remove(klass);
60 | icon.innerHTML = '▾';
61 | } else {
62 | stepSibling.classList.add(klass);
63 | icon.innerHTML = '▸';
64 | }
65 | }
66 |
67 | function showHashTarget(targetId) {
68 | if (targetId) {
69 | var hashTarget = document.getElementById(targetId);
70 | // new target is hidden
71 | if (
72 | hashTarget &&
73 | hashTarget.offsetHeight === 0 &&
74 | hashTarget.parentNode.parentNode.classList.contains('display-none')
75 | ) {
76 | hashTarget.parentNode.parentNode.classList.remove('display-none');
77 | }
78 | }
79 | }
80 |
81 | function scrollIntoView(targetId) {
82 | // Only scroll to element if we don't have a stored scroll position.
83 | if (targetId && !history.state) {
84 | var hashTarget = document.getElementById(targetId);
85 | if (hashTarget) {
86 | hashTarget.scrollIntoView();
87 | }
88 | }
89 | }
90 |
91 | function gotoCurrentTarget() {
92 | showHashTarget(location.hash.substring(1));
93 | scrollIntoView(location.hash.substring(1));
94 | }
95 |
96 | window.addEventListener('hashchange', gotoCurrentTarget);
97 | gotoCurrentTarget();
98 |
99 | var toclinks = document.getElementsByClassName('pre-open');
100 | for (var k = 0; k < toclinks.length; k++) {
101 | toclinks[k].addEventListener('mousedown', preOpen, false);
102 | }
103 |
104 | function preOpen() {
105 | showHashTarget(this.hash.substring(1));
106 | }
107 |
108 | var split_left = document.querySelector('#split-left');
109 | var split_right = document.querySelector('#split-right');
110 | var split_parent = split_left.parentNode;
111 | var cw_with_sb = split_left.clientWidth;
112 | split_left.style.overflow = 'hidden';
113 | var cw_without_sb = split_left.clientWidth;
114 | split_left.style.overflow = '';
115 |
116 | Split(['#split-left', '#split-right'], {
117 | elementStyle: function(dimension, size, gutterSize) {
118 | return {
119 | 'flex-basis': 'calc(' + size + '% - ' + gutterSize + 'px)'
120 | };
121 | },
122 | gutterStyle: function(dimension, gutterSize) {
123 | return {
124 | 'flex-basis': gutterSize + 'px'
125 | };
126 | },
127 | gutterSize: 20,
128 | sizes: [33, 67]
129 | });
130 |
131 | // Chrome doesn't remember scroll position properly so do it ourselves.
132 | // Also works on Firefox and Edge.
133 |
134 | function updateState() {
135 | history.replaceState(
136 | {
137 | left_top: split_left.scrollTop,
138 | right_top: split_right.scrollTop
139 | },
140 | document.title
141 | );
142 | }
143 |
144 | function loadState(ev) {
145 | if (ev) {
146 | // Edge doesn't replace change history.state on popstate.
147 | history.replaceState(ev.state, document.title);
148 | }
149 | if (history.state) {
150 | split_left.scrollTop = history.state.left_top;
151 | split_right.scrollTop = history.state.right_top;
152 | }
153 | }
154 |
155 | window.addEventListener('load', function() {
156 | // Restore after Firefox scrolls to hash.
157 | setTimeout(function() {
158 | loadState();
159 | // Update with initial scroll position.
160 | updateState();
161 | // Update scroll positions only after we've loaded because Firefox
162 | // emits an initial scroll event with 0.
163 | split_left.addEventListener('scroll', updateState);
164 | split_right.addEventListener('scroll', updateState);
165 | }, 1);
166 | });
167 |
168 | window.addEventListener('popstate', loadState);
169 |
--------------------------------------------------------------------------------
/docs/assets/split.css:
--------------------------------------------------------------------------------
1 | .gutter {
2 | background-color: #f5f5f5;
3 | background-repeat: no-repeat;
4 | background-position: 50%;
5 | }
6 |
7 | .gutter.gutter-vertical {
8 | background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFAQMAAABo7865AAAABlBMVEVHcEzMzMzyAv2sAAAAAXRSTlMAQObYZgAAABBJREFUeF5jOAMEEAIEEFwAn3kMwcB6I2AAAAAASUVORK5CYII=');
9 | cursor: ns-resize;
10 | }
11 |
12 | .gutter.gutter-horizontal {
13 | background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==');
14 | cursor: ew-resize;
15 | }
16 |
--------------------------------------------------------------------------------
/docs/assets/style.css:
--------------------------------------------------------------------------------
1 | .documentation {
2 | font-family: Helvetica, sans-serif;
3 | color: #666;
4 | line-height: 1.5;
5 | background: #f5f5f5;
6 | }
7 |
8 | .black {
9 | color: #666;
10 | }
11 |
12 | .bg-white {
13 | background-color: #fff;
14 | }
15 |
16 | h4 {
17 | margin: 20px 0 10px 0;
18 | }
19 |
20 | .documentation h3 {
21 | color: #000;
22 | }
23 |
24 | .border-bottom {
25 | border-color: #ddd;
26 | }
27 |
28 | a {
29 | color: #1184ce;
30 | text-decoration: none;
31 | }
32 |
33 | .documentation a[href]:hover {
34 | text-decoration: underline;
35 | }
36 |
37 | a:hover {
38 | cursor: pointer;
39 | }
40 |
41 | .py1-ul li {
42 | padding: 5px 0;
43 | }
44 |
45 | .max-height-100 {
46 | max-height: 100%;
47 | }
48 |
49 | .height-viewport-100 {
50 | height: 100vh;
51 | }
52 |
53 | section:target h3 {
54 | font-weight: 700;
55 | }
56 |
57 | .documentation td,
58 | .documentation th {
59 | padding: 0.25rem 0.25rem;
60 | }
61 |
62 | h1:hover .anchorjs-link,
63 | h2:hover .anchorjs-link,
64 | h3:hover .anchorjs-link,
65 | h4:hover .anchorjs-link {
66 | opacity: 1;
67 | }
68 |
69 | .fix-3 {
70 | width: 25%;
71 | max-width: 244px;
72 | }
73 |
74 | .fix-3 {
75 | width: 25%;
76 | max-width: 244px;
77 | }
78 |
79 | @media (min-width: 52em) {
80 | .fix-margin-3 {
81 | margin-left: 25%;
82 | }
83 | }
84 |
85 | .pre,
86 | pre,
87 | code,
88 | .code {
89 | font-family: Source Code Pro, Menlo, Consolas, Liberation Mono, monospace;
90 | font-size: 14px;
91 | }
92 |
93 | .fill-light {
94 | background: #f9f9f9;
95 | }
96 |
97 | .width2 {
98 | width: 1rem;
99 | }
100 |
101 | .input {
102 | font-family: inherit;
103 | display: block;
104 | width: 100%;
105 | height: 2rem;
106 | padding: 0.5rem;
107 | margin-bottom: 1rem;
108 | border: 1px solid #ccc;
109 | font-size: 0.875rem;
110 | border-radius: 3px;
111 | box-sizing: border-box;
112 | }
113 |
114 | table {
115 | border-collapse: collapse;
116 | }
117 |
118 | .prose table th,
119 | .prose table td {
120 | text-align: left;
121 | padding: 8px;
122 | border: 1px solid #ddd;
123 | }
124 |
125 | .prose table th:nth-child(1) {
126 | border-right: none;
127 | }
128 | .prose table th:nth-child(2) {
129 | border-left: none;
130 | }
131 |
132 | .prose table {
133 | border: 1px solid #ddd;
134 | }
135 |
136 | .prose-big {
137 | font-size: 18px;
138 | line-height: 30px;
139 | }
140 |
141 | .quiet {
142 | opacity: 0.7;
143 | }
144 |
145 | .minishadow {
146 | box-shadow: 2px 2px 10px #f3f3f3;
147 | }
148 |
--------------------------------------------------------------------------------
/docs/examples/assets/horizontal/bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/horizontal/bar.png
--------------------------------------------------------------------------------
/docs/examples/assets/horizontal/sprite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/horizontal/sprite.png
--------------------------------------------------------------------------------
/docs/examples/assets/horizontal/track.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/horizontal/track.png
--------------------------------------------------------------------------------
/docs/examples/assets/modal/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/modal/background.png
--------------------------------------------------------------------------------
/docs/examples/assets/modal/button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/modal/button.png
--------------------------------------------------------------------------------
/docs/examples/assets/quantitybar/add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/quantitybar/add.png
--------------------------------------------------------------------------------
/docs/examples/assets/quantitybar/horizontal/bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/quantitybar/horizontal/bar.png
--------------------------------------------------------------------------------
/docs/examples/assets/quantitybar/horizontal/track.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/quantitybar/horizontal/track.png
--------------------------------------------------------------------------------
/docs/examples/assets/quantitybar/subtract.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/quantitybar/subtract.png
--------------------------------------------------------------------------------
/docs/examples/assets/quantitybar/vertical/bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/quantitybar/vertical/bar.png
--------------------------------------------------------------------------------
/docs/examples/assets/quantitybar/vertical/track.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/quantitybar/vertical/track.png
--------------------------------------------------------------------------------
/docs/examples/assets/textover/button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/textover/button.png
--------------------------------------------------------------------------------
/docs/examples/assets/textover/header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/textover/header.png
--------------------------------------------------------------------------------
/docs/examples/assets/valuebar/alpha.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/valuebar/alpha.png
--------------------------------------------------------------------------------
/docs/examples/assets/valuebar/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/valuebar/background.png
--------------------------------------------------------------------------------
/docs/examples/assets/valuebar/bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/valuebar/bar.png
--------------------------------------------------------------------------------
/docs/examples/assets/valuebar/pointer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/valuebar/pointer.png
--------------------------------------------------------------------------------
/docs/examples/assets/valuebar/track.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/valuebar/track.png
--------------------------------------------------------------------------------
/docs/examples/assets/valuebar/vtrack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/valuebar/vtrack.png
--------------------------------------------------------------------------------
/docs/examples/assets/vertical/bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/vertical/bar.png
--------------------------------------------------------------------------------
/docs/examples/assets/vertical/sprite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/vertical/sprite.png
--------------------------------------------------------------------------------
/docs/examples/assets/vertical/track.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/vertical/track.png
--------------------------------------------------------------------------------
/docs/examples/assets/wheel3D/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/wheel3D/icon.png
--------------------------------------------------------------------------------
/docs/examples/assets/wheel3D/mmDown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/wheel3D/mmDown.png
--------------------------------------------------------------------------------
/docs/examples/assets/wheel3D/mmUp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsfehler/phaser-ui-tools/f3306cf9aa5e95ea746001e8c48448d24c9c4af4/docs/examples/assets/wheel3D/mmUp.png
--------------------------------------------------------------------------------
/docs/examples/html/phaser3/hscrollbar.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/examples/html/phaser3/modal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/examples/html/phaser3/quantitybar.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/examples/html/phaser3/textover.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/examples/html/phaser3/valuebar.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/examples/html/phaser3/vscrollbar.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/examples/html/phaser3/wheel3D.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/examples/html/phaserce/hscrollbar.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/examples/html/phaserce/modal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/examples/html/phaserce/quantitybar.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/examples/html/phaserce/quantitybar_column.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/examples/html/phaserce/textover.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/examples/html/phaserce/valuebar.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/examples/html/phaserce/valuebar_column.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/examples/html/phaserce/vscrollbar.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/examples/html/phaserce/wheel3D.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/examples/js/phaser3/hscrollbar.js:
--------------------------------------------------------------------------------
1 | var config = {
2 | type: Phaser.AUTO,
3 | width: 400,
4 | height: 300,
5 | scene: {
6 | preload: preload,
7 | create: create,
8 | update: update
9 | }
10 | };
11 |
12 | var game = new Phaser.Game(config);
13 |
14 | function preload() {
15 | var assetRoot = '../../assets/horizontal/';
16 | this.load.image('dummyButton', `${assetRoot}sprite.png`);
17 | this.load.image('track', `${assetRoot}track.png`);
18 | this.load.spritesheet('bar', `${assetRoot}bar.png`, { frameWidth: 44, frameHeight: 22 });
19 | }
20 |
21 | function create() {
22 | var viewport = new uiWidgets.Viewport(this, 75, 75, 260, 128);
23 | var row = new uiWidgets.Row(this, 0, 0);
24 |
25 | viewport.addNode(row);
26 |
27 | // Add things to the row.
28 | var dummy_sprite_a = this.add.image(0, 0, 'dummyButton');
29 | var dummy_sprite_b = this.add.image(0, 0, 'dummyButton');
30 | var dummy_sprite_c = this.add.image(0, 0, 'dummyButton');
31 | var dummy_sprite_d = this.add.image(0, 0, 'dummyButton');
32 | var dummy_sprite_e = this.add.image(0, 0, 'dummyButton');
33 | var dummy_sprite_f = this.add.image(0, 0, 'dummyButton');
34 | var dummy_sprite_g = this.add.image(0, 0, 'dummyButton');
35 | var dummy_sprite_h = this.add.image(0, 0, 'dummyButton');
36 | var dummy_sprite_i = this.add.image(0, 0, 'dummyButton');
37 |
38 | row.addNode(dummy_sprite_a);
39 | row.addNode(dummy_sprite_b);
40 | row.addNode(dummy_sprite_c);
41 | row.addNode(dummy_sprite_d);
42 | row.addNode(dummy_sprite_e);
43 | row.addNode(dummy_sprite_f);
44 | row.addNode(dummy_sprite_g);
45 | row.addNode(dummy_sprite_h);
46 | row.addNode(dummy_sprite_i);
47 |
48 | var scrollbar = new uiWidgets.Scrollbar(
49 | this,
50 | viewport,
51 | true,
52 | false,
53 | "track",
54 | "bar",
55 | {'duration': 300, 'ease': Phaser.Math.Easing.Quadratic.Out}
56 | );
57 |
58 | Phaser.Display.Align.To.BottomCenter(scrollbar, viewport, 0, 128 + 10);
59 |
60 | }
61 |
62 | function update() {}
63 |
--------------------------------------------------------------------------------
/docs/examples/js/phaser3/modal.js:
--------------------------------------------------------------------------------
1 | var config = {
2 | type: Phaser.AUTO,
3 | width: 400,
4 | height: 300,
5 | scene: {
6 | preload: preload,
7 | create: create,
8 | }
9 | };
10 |
11 | var game = new Phaser.Game(config);
12 |
13 | var textStyle = {'fill': '#FFF', 'font': '16px Courier New'};
14 |
15 | function preload() {
16 | var assetRoot = '../../assets/modal/';
17 | this.load.image("modalBg", assetRoot + "background.png");
18 | this.load.spritesheet('button', assetRoot + 'button.png', { frameWidth: 128, frameHeight: 48 });
19 | }
20 |
21 | function create() {
22 | var openButton = new uiWidgets.TextButton(this, 100, 50, "button", createModal, this, 1, 0, 2, 1)
23 | .setText("Open", textStyle)
24 | .eventTextYAdjustment(3);
25 | }
26 |
27 | function createModal() {
28 | var closeButton = new uiWidgets.TextButton(this, 0, 0, "button", closeCallback, this, 1, 0, 2, 1)
29 | .setText("Close", textStyle)
30 | .eventTextYAdjustment(3);
31 |
32 | this.modal = new uiWidgets.Column(this, 100, 100, bg="modalBg", modal=true);
33 | this.modal.addNode(closeButton, paddingX=0, paddingY=10);
34 | }
35 |
36 | function closeCallback() {
37 | this.modal.dismiss();
38 | }
39 |
--------------------------------------------------------------------------------
/docs/examples/js/phaser3/quantitybar.js:
--------------------------------------------------------------------------------
1 | var config = {
2 | type: Phaser.AUTO,
3 | width: 600,
4 | height: 400,
5 | scene: {
6 | preload: preload,
7 | create: create,
8 | }
9 | };
10 |
11 | var game = new Phaser.Game(config);
12 |
13 | function preload() {
14 | var assetRoot = '../../assets/quantitybar/';
15 | this.load.image("track", assetRoot + "horizontal/track.png");
16 | this.load.spritesheet('bar', assetRoot + 'horizontal/bar.png', { frameWidth: 260, frameHeight: 32 });
17 |
18 | this.load.image("vtrack", assetRoot + "vertical/track.png");
19 | this.load.spritesheet('vbar', assetRoot + 'vertical/bar.png', { frameWidth: 32, frameHeight: 260 });
20 |
21 | this.load.image("add", assetRoot + "add.png");
22 | this.load.image("subtract", assetRoot + "subtract.png");
23 | }
24 |
25 | var healthbar,
26 | healthbarText,
27 | vhealthbar,
28 | vhealthbarText,
29 | rhealthbar,
30 | rhealthbarText,
31 | rvhealthbar,
32 | rvhealthbarText,
33 | decreaseHealth,
34 | increaseHealth,
35 | vdecreaseHealth,
36 | vincreaseHealth,
37 | rdecreaseHealth,
38 | rincreaseHealth,
39 | rvdecreaseHealth,
40 | rvincreaseHealth,
41 | textStyle;
42 |
43 | function create() {
44 |
45 | textStyle = {
46 | font: "65px Arial",
47 | fill: "#ff0044",
48 | align: "center"
49 | };
50 |
51 | // Create a quantitybar starting at 50.
52 | healthbar = new uiWidgets.QuantityBar(
53 | this,
54 | {"x": 50, "y": 10},
55 | {"startValue": 50, maxValue: 100},
56 | false,
57 | false,
58 | "track",
59 | "bar",
60 | {'duration': 400, 'ease': Phaser.Math.Easing.Quadratic.Out}
61 | );
62 |
63 | // Display the quantitybar's value.
64 | healthbarText = this.add.text(50, 50, healthbar.valueRange.startValue, textStyle);
65 |
66 | // Add buttons to modify the value.
67 | var lessHealth = new uiWidgets.Button(this, 150, 10, 'subtract', decreaseHealth, this);
68 | var moreHealth = new uiWidgets.Button(this, 200, 10, 'add', increaseHealth, this);
69 |
70 | // Create a reverse quantitybar starting at 30.
71 | rhealthbar = new uiWidgets.QuantityBar(
72 | this,
73 | {"x": 350, "y": 10},
74 | {"startValue": 30, maxValue: 100},
75 | false,
76 | true,
77 | "track",
78 | "bar",
79 | {'duration': 400, 'ease': Phaser.Math.Easing.Quadratic.Out}
80 | );
81 |
82 | rhealthbarText = this.add.text(350, 50, rhealthbar.valueRange.startValue, textStyle);
83 |
84 | var rlessHealth = new uiWidgets.Button(this, 450, 10, 'subtract', rdecreaseHealth, this);
85 | var rmoreHealth = new uiWidgets.Button(this, 500, 10, 'add', rincreaseHealth, this);
86 |
87 | // Create a vertical quantitybar starting at 50.
88 | vhealthbar = new uiWidgets.QuantityBar(
89 | this,
90 | {"x": 30, "y": 130},
91 | {"startValue": 32, maxValue: 100},
92 | true,
93 | false,
94 | "vtrack",
95 | "vbar",
96 | {'duration': 400, 'ease': Phaser.Math.Easing.Quadratic.Out}
97 | );
98 |
99 | vhealthbarText = this.add.text(100, 150, vhealthbar.valueRange.startValue, textStyle);
100 |
101 | var vlessHealth = new uiWidgets.Button(this, 100, 250, 'subtract', vdecreaseHealth, this);
102 | var vmoreHealth = new uiWidgets.Button(this, 150, 250, 'add', vincreaseHealth, this);
103 |
104 | // Create a reverse vertical quantitybar starting at 50.
105 | rvhealthbar = new uiWidgets.QuantityBar(
106 | this,
107 | {"x": 250, "y": 130},
108 | {"startValue": 30, maxValue: 100},
109 | true,
110 | true,
111 | "vtrack",
112 | "vbar",
113 | {'duration': 400, 'ease': Phaser.Math.Easing.Quadratic.Out}
114 | );
115 |
116 | rvhealthbarText = this.add.text(300, 150, rvhealthbar.valueRange.startValue, textStyle);
117 |
118 | var vlessHealth = new uiWidgets.Button(this, 300, 250, 'subtract', rvdecreaseHealth, this);
119 | var vmoreHealth = new uiWidgets.Button(this, 350, 250, 'add', rvincreaseHealth, this);
120 |
121 | }
122 |
123 | function increaseHealth() {
124 | healthbar.adjustBar(10);
125 | healthbarText.setText(healthbar.valueRange.getCurrentValue());
126 | }
127 |
128 | function decreaseHealth() {
129 | healthbar.adjustBar(-10);
130 | healthbarText.setText(healthbar.valueRange.getCurrentValue());
131 | }
132 |
133 | function vincreaseHealth() {
134 | vhealthbar.adjustBar(1);
135 | vhealthbarText.setText(vhealthbar.valueRange.getCurrentValue());
136 | }
137 |
138 | function vdecreaseHealth() {
139 | vhealthbar.adjustBar(-1);
140 | vhealthbarText.setText(vhealthbar.valueRange.getCurrentValue());
141 | }
142 |
143 | function rincreaseHealth() {
144 | rhealthbar.adjustBar(10);
145 | rhealthbarText.setText(rhealthbar.valueRange.getCurrentValue());
146 | }
147 |
148 | function rdecreaseHealth() {
149 | rhealthbar.adjustBar(-10);
150 | rhealthbarText.setText(rhealthbar.valueRange.getCurrentValue());
151 | }
152 |
153 | function rvincreaseHealth() {
154 | rvhealthbar.adjustBar(10);
155 | rvhealthbarText.setText(rvhealthbar.valueRange.getCurrentValue());
156 | }
157 |
158 | function rvdecreaseHealth() {
159 | rvhealthbar.adjustBar(-10);
160 | rvhealthbarText.setText(rvhealthbar.valueRange.getCurrentValue());
161 | }
162 |
--------------------------------------------------------------------------------
/docs/examples/js/phaser3/textover.js:
--------------------------------------------------------------------------------
1 | var config = {
2 | type: Phaser.AUTO,
3 | width: 400,
4 | height: 300,
5 | scene: {
6 | preload: preload,
7 | create: create,
8 | }
9 | };
10 |
11 | var game = new Phaser.Game(config);
12 |
13 | var textStyle = {'fill': '#FFF', 'font': '16px Courier New'};
14 |
15 | function preload() {
16 | var assetRoot = '../../assets/textover/';
17 | this.load.image("header", assetRoot + "header.png");
18 | this.load.spritesheet('button', assetRoot + 'button.png', { frameWidth: 128, frameHeight: 48 });
19 | }
20 |
21 | function create() {
22 | this.header = new uiWidgets.TextSprite(this, 0, 0, "header").setText('Header', textStyle).setOrigin(0.0, 0.0);
23 |
24 | var buttonOne = new uiWidgets.TextButton(this, 0, 0, "button", newGameCallback, this, 1, 0, 2, 1)
25 | .setText("New Game", textStyle)
26 | .eventTextYAdjustment(3);
27 | var buttonTwo = new uiWidgets.TextButton(this, 0, 0, "button", continueCallback, this, 1, 0, 2, 1)
28 | .setText("Continue", textStyle)
29 | .eventTextYAdjustment(3);
30 | var buttonThree = new uiWidgets.TextButton(this, 0, 0, "button", optionsCallback, this, 1, 0, 2, 1)
31 | .setText("Options", textStyle)
32 | .eventTextYAdjustment(3);
33 |
34 | var column = new uiWidgets.Column(this, 200, 100);
35 | column.addNode(buttonOne, paddingX=0, paddingY=10);
36 | column.addNode(buttonTwo, paddingX=0, paddingY=10);
37 | column.addNode(buttonThree, paddingX=0, paddingY=10);
38 |
39 | }
40 |
41 | function newGameCallback() {
42 | this.header.text.setText('You clicked the New Game button');
43 | }
44 |
45 |
46 | function continueCallback() {
47 | this.header.text.setText('You clicked the Continue button');
48 | }
49 |
50 |
51 | function optionsCallback() {
52 | this.header.text.setText('You clicked the Options button');
53 | }
54 |
--------------------------------------------------------------------------------
/docs/examples/js/phaser3/valuebar.js:
--------------------------------------------------------------------------------
1 | var config = {
2 | type: Phaser.AUTO,
3 | width: 600,
4 | height: 400,
5 | scene: {
6 | preload: preload,
7 | create: create,
8 | }
9 | };
10 |
11 | var game = new Phaser.Game(config);
12 |
13 | function preload() {
14 | var assetRoot = '../../assets/valuebar/';
15 | this.load.image("track", assetRoot + "track.png");
16 | this.load.spritesheet('bar', assetRoot + 'bar.png', { frameWidth: 32, frameHeight: 32 });
17 | this.load.image("vtrack", assetRoot + "vtrack.png");
18 | this.load.image("alphaImage", assetRoot + "alpha.png");
19 | }
20 |
21 | var valuebar0;
22 | var valuebar50;
23 | var vvaluebar50;
24 | var valuebar0_text;
25 | var valuebar50_text;
26 | var vvaluebar50_text;
27 | var alphaImage;
28 |
29 | function create() {
30 |
31 | // Create a valuebar starting at 0.
32 | valuebar0 = new uiWidgets.ValueBar(
33 | this,
34 | {"x": 50, "y": 10},
35 | {"step": 1, "startValue": 0, maxValue: 100},
36 | true,
37 | false,
38 | "track",
39 | "bar",
40 | {'duration': 100, 'ease': Phaser.Math.Easing.Quadratic.Out}
41 | );
42 |
43 | valuebar0_text = this.add.text(50, 50, valuebar0.valueRange.startValue, {
44 | font: "65px Arial",
45 | fill: "#ff0044",
46 | align: "center"
47 | });
48 |
49 | valuebar0.valueDisplay = valuebar0_text;
50 |
51 | // Use the onMovement signal to update the display of text when the bar is moved.
52 | valuebar0.emitter.on('movement', updateValueDisplay);
53 |
54 | // Create a valuebar starting at 50.
55 | valuebar50 = new uiWidgets.ValueBar(
56 | this,
57 | {"x": 50, "y": 150},
58 | {"step": 25, "startValue": 50, maxValue: 100},
59 | true,
60 | false,
61 | "track",
62 | "bar",
63 | {'duration': 100, 'ease': Phaser.Math.Easing.Quadratic.Out}
64 | );
65 |
66 | valuebar50_text = this.add.text(50, 200, valuebar50.valueRange.startValue, {
67 | font: "65px Arial",
68 | fill: "#ff0044",
69 | align: "center"
70 | });
71 |
72 | valuebar50.valueDisplay = valuebar50_text;
73 | valuebar50.emitter.on('movement', updateValueDisplay);
74 |
75 | // Create a vertical valuebar starting at 50.
76 | vvaluebar50 = new uiWidgets.ValueBar(
77 | this,
78 | {"x": 350, "y": 50},
79 | {"step": 25, "startValue": 50, maxValue: 100},
80 | true,
81 | true,
82 | "vtrack",
83 | "bar",
84 | {'duration': 100, 'ease': Phaser.Math.Easing.Quadratic.Out}
85 | );
86 |
87 | vvaluebar50_text = this.add.text(400, 200, valuebar50.valueRange.startValue, {
88 | font: "65px Arial",
89 | fill: "#ff0044",
90 | align: "center"
91 | });
92 |
93 | vvaluebar50.valueDisplay = vvaluebar50_text;
94 | vvaluebar50.emitter.on('movement', updateValueDisplay);
95 |
96 | alphaImage = this.add.sprite(500, 100, "alphaImage");
97 | alphaImage.alpha = vvaluebar50.valueRange.getCurrentValue() / 100;
98 |
99 | // Use the onMovement signal to updte the sprite's opacity whenever the bar is moved.
100 | vvaluebar50.emitter.on('movement', updateAlpha);
101 | }
102 |
103 | function updateValueDisplay(bar) {
104 | bar.valueDisplay.setText(bar.valueRange.getCurrentValue());
105 | }
106 |
107 | function updateAlpha(bar) {
108 | alphaImage.alpha = bar.valueRange.getCurrentValue() / 100;
109 | }
110 |
--------------------------------------------------------------------------------
/docs/examples/js/phaser3/vscrollbar.js:
--------------------------------------------------------------------------------
1 | var config = {
2 | type: Phaser.AUTO,
3 | width: 600,
4 | height: 400,
5 | scene: {
6 | preload: preload,
7 | create: create,
8 | }
9 | };
10 |
11 | var game = new Phaser.Game(config);
12 |
13 | function preload() {
14 | var assetRoot = '../../assets/vertical/';
15 | this.load.image("dummyButton", assetRoot + "sprite.png");
16 | this.load.image("track", assetRoot + "track.png");
17 | this.load.spritesheet('bar', assetRoot + 'bar.png', { frameWidth: 22, frameHeight: 44 });
18 |
19 | }
20 |
21 | function create() {
22 |
23 | // Create a viewport. A "window" with a limited area of view.
24 | var viewport = new uiWidgets.Viewport(this, 75, 75, 600, 260);
25 |
26 | // Create a column. Anything added to a column is placed under the previous thing added.
27 | var column = new uiWidgets.Column(this);
28 |
29 | // Put the column inside the viewport.
30 | viewport.addNode(column);
31 |
32 | // Add things to the column.
33 | var dummy_sprite_a = this.add.image(0, 0, "dummyButton");
34 | var dummy_sprite_b = this.add.image(0, 0, "dummyButton");
35 | var dummy_sprite_c = this.add.image(0, 0, "dummyButton");
36 | var dummy_sprite_d = this.add.image(0, 0, "dummyButton");
37 | var dummy_sprite_e = this.add.image(0, 0, "dummyButton");
38 | var dummy_sprite_f = this.add.image(0, 0, "dummyButton");
39 |
40 | column.addNode(dummy_sprite_a);
41 | column.addNode(dummy_sprite_b);
42 | column.addNode(dummy_sprite_c);
43 | column.addNode(dummy_sprite_d);
44 | column.addNode(dummy_sprite_e);
45 | column.addNode(dummy_sprite_f);
46 |
47 | // Create a scrollbar for the viewport.
48 | var scrollbar = new uiWidgets.Scrollbar(
49 | this,
50 | viewport,
51 | true,
52 | true,
53 | "track",
54 | "bar",
55 | {'duration': 300, 'ease': Phaser.Math.Easing.Quadratic.Out}
56 | );
57 |
58 | // Place scrollbar next to viewport.
59 | Phaser.Display.Align.To.RightCenter(scrollbar, viewport, 300 + 10, 0);
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/docs/examples/js/phaser3/wheel3D.js:
--------------------------------------------------------------------------------
1 | var config = {
2 | type: Phaser.AUTO,
3 | width: 600,
4 | height: 400,
5 | scene: {
6 | preload: preload,
7 | create: create,
8 | }
9 | };
10 |
11 | var game = new Phaser.Game(config);
12 |
13 | function preload() {
14 | var assetRoot = '../../assets/wheel3D/';
15 | this.load.image("icon", assetRoot + "icon.png");
16 | this.load.image("mmUp", assetRoot + "mmUp.png");
17 | this.load.image("mmDown", assetRoot + "mmDown.png");
18 | }
19 |
20 | function create() {
21 |
22 | var centerX = this.cameras.main.centerX;
23 | var centerY = this.cameras.main.centerY;
24 |
25 | // Example 1: Rotate around the Y axis
26 |
27 | // Build a list of sprites for the wheel.
28 | var menuListY = [];
29 |
30 | for (var i = 0; i < 12; i++) {
31 | var icon = this.add.sprite(0, 0, 'icon');
32 | menuListY.push(icon);
33 | }
34 |
35 | // Create the wheel.
36 | menuWheelY = new uiWidgets.Wheel3D(
37 | this,
38 | {"x": centerX - 100, "y": centerY},
39 | menuListY,
40 | 0,
41 | 90,
42 | "y",
43 | {"x":0, "y": -90, "z": 0}
44 | );
45 |
46 | // Tint the active item after each movement.
47 | menuWheelY.emitter.on('complete',
48 | function(wheel) {
49 | for (var i = 0; i < 12; i++) {
50 | wheel.sprites[i].tint = 0xFFFFFF;
51 | }
52 | wheel.active.tint = 0xdc21ff;
53 | }
54 | );
55 |
56 | menuWheelY.activate();
57 |
58 | // Scroll Buttons
59 | var scrollLeftButtonY = new uiWidgets.Button(
60 | this,
61 | 0,
62 | centerY,
63 | "mmUp",
64 | scrollTheWheel,
65 | null,
66 | );
67 | scrollLeftButtonY.wheel = menuWheelY;
68 | scrollLeftButtonY.dir = 0;
69 |
70 | var scrollRightButtonY = new uiWidgets.Button(
71 | this,
72 | 0,
73 | centerY + 48,
74 | "mmDown",
75 | scrollTheWheel,
76 | null,
77 | );
78 | scrollRightButtonY.wheel = menuWheelY;
79 | scrollRightButtonY.dir = 1;
80 |
81 | // Example 2: Rotate around the X axis
82 | var menuListX = [];
83 |
84 | for (var i = 0; i < 12; i++) {
85 | var icon = this.add.sprite(0, 0, 'icon');
86 | menuListX.push(icon);
87 | }
88 |
89 | // Create the wheel.
90 | menuWheelX = new uiWidgets.Wheel3D(
91 | this,
92 | {"x": centerX - 100, "y": 100},
93 | menuListX,
94 | 0,
95 | 90,
96 | "x",
97 | {"x": 90, "y": 0, "z": 0}
98 | );
99 |
100 | // Tint the active item after each movement.
101 | menuWheelX.emitter.on('complete',
102 | function(wheel) {
103 | for (var i = 0; i < 12; i++) {
104 | wheel.sprites[i].tint = 0xFFFFFF;
105 | }
106 | wheel.active.tint = 0xdc21ff;
107 | }
108 | );
109 |
110 | menuWheelX.activate();
111 |
112 | // Scroll Buttons
113 | var scrollLeftButtonX = new uiWidgets.Button(
114 | this,
115 | 0,
116 | 0,
117 | "mmUp",
118 | scrollTheWheel,
119 | null,
120 | );
121 | scrollLeftButtonX.wheel = menuWheelX;
122 | scrollLeftButtonX.dir = 0;
123 |
124 | var scrollRightButtonX = new uiWidgets.Button(
125 | this,
126 | 0,
127 | 48,
128 | "mmDown",
129 | scrollTheWheel,
130 | null,
131 | );
132 | scrollRightButtonX.wheel = menuWheelX;
133 | scrollRightButtonX.dir = 1;
134 |
135 | // Example 3: Rotate around the Z axis
136 | var menuListZ = [];
137 |
138 | for (var i = 0; i < 12; i++) {
139 | var icon = this.add.sprite(0, 0, 'icon');
140 | menuListZ.push(icon);
141 | }
142 |
143 | // Create the wheel.
144 | menuWheelZ = new uiWidgets.Wheel3D(
145 | this,
146 | {"x": centerX, "y": 100},
147 | menuListZ,
148 | 0,
149 | 90,
150 | "z",
151 | {"x": 0, "y": 0, "z": 90}
152 | );
153 |
154 | menuWheelZ.emitter.on('start',
155 | function(wheel) {
156 | for (var i = 0; i < 12; i++) {
157 | wheel.sprites[i].tint = 0xFFFFFF;
158 | }
159 | wheel.active.tint = 0xdc21ff;
160 | }
161 | );
162 |
163 | menuWheelZ.activate();
164 |
165 | // Scroll Buttons
166 | var scrollLeftButtonZ = new uiWidgets.Button(
167 | this,
168 | this.cameras.main.width - 100,
169 | 0,
170 | "mmUp",
171 | scrollTheWheel,
172 | null,
173 | );
174 | scrollLeftButtonZ.wheel = menuWheelZ;
175 | scrollLeftButtonZ.dir = 0;
176 |
177 | var scrollRightButtonZ = new uiWidgets.Button(
178 | this,
179 | this.cameras.main.width - 100,
180 | 48,
181 | "mmDown",
182 | scrollTheWheel,
183 | null,
184 | );
185 | scrollRightButtonZ.wheel = menuWheelZ;
186 | scrollRightButtonZ.dir = 1;
187 | }
188 |
189 | var scrollTheWheel = function () {
190 | if (this.dir === 0){
191 | this.wheel.moveBack();
192 | }
193 | if (this.dir === 1){
194 | this.wheel.moveForward();
195 | }
196 | };
197 |
--------------------------------------------------------------------------------
/docs/examples/js/phaserce/hscrollbar.js:
--------------------------------------------------------------------------------
1 | var game = new Phaser.Game(400, 300, Phaser.AUTO, 'hscrollbar', { preload: preload, create: create });
2 |
3 | function preload() {
4 | var assetRoot = '../../assets/horizontal/';
5 | game.load.image("dummyButton", assetRoot + "sprite.png");
6 | game.load.image("track", assetRoot + "track.png");
7 | game.load.spritesheet('bar', assetRoot + 'bar.png', 44, 22);
8 | }
9 |
10 | function create() {
11 | // Create a viewport. A "window" with a limited area of view.
12 | var viewport = new uiWidgets.Viewport(game, 75, 75, 260, 128);
13 |
14 | // Create a row. Anything added to a row is placed next to the previous thing added.
15 | var row = new uiWidgets.Row(game);
16 |
17 | // Put the row inside the viewport.
18 | viewport.addNode(row);
19 |
20 | // Add things to the row.
21 | var dummy_sprite_a = this.game.add.sprite(0, 0, "dummyButton");
22 | var dummy_sprite_b = this.game.add.sprite(0, 0, "dummyButton");
23 | var dummy_sprite_c = this.game.add.sprite(0, 0, "dummyButton");
24 | var dummy_sprite_d = this.game.add.sprite(0, 0, "dummyButton");
25 | var dummy_sprite_e = this.game.add.sprite(0, 0, "dummyButton");
26 | var dummy_sprite_f = this.game.add.sprite(0, 0, "dummyButton");
27 | var dummy_sprite_g = this.game.add.sprite(0, 0, "dummyButton");
28 | var dummy_sprite_h = this.game.add.sprite(0, 0, "dummyButton");
29 | var dummy_sprite_i = this.game.add.sprite(0, 0, "dummyButton");
30 |
31 | row.addNode(dummy_sprite_a);
32 | row.addNode(dummy_sprite_b);
33 | row.addNode(dummy_sprite_c);
34 | row.addNode(dummy_sprite_d);
35 | row.addNode(dummy_sprite_e);
36 | row.addNode(dummy_sprite_f);
37 | row.addNode(dummy_sprite_g);
38 | row.addNode(dummy_sprite_h);
39 | row.addNode(dummy_sprite_i);
40 |
41 | // Create a scrollbar for the viewport.
42 | var scrollbar = new uiWidgets.Scrollbar(
43 | game,
44 | viewport,
45 | true,
46 | false,
47 | "track",
48 | "bar",
49 | {'duration': 300, 'ease': Phaser.Easing.Quadratic.Out}
50 | );
51 |
52 | // Place scrollbar below viewport.
53 | scrollbar.alignTo(viewport, Phaser.BOTTOM_LEFT, 0, 10);
54 | }
55 |
--------------------------------------------------------------------------------
/docs/examples/js/phaserce/modal.js:
--------------------------------------------------------------------------------
1 | var game = new Phaser.Game(
2 | 400,
3 | 300,
4 | Phaser.AUTO,
5 | 'textover',
6 | {preload: preload, create: create},
7 | false,
8 | false,
9 | );
10 |
11 | var textStyle = {'fill': '#FFF', 'font': '16px Courier New'};
12 |
13 | function preload() {
14 | var assetRoot = '../../assets/modal/';
15 | game.load.image("modalBg", assetRoot + "background.png");
16 | game.load.spritesheet('button', assetRoot + 'button.png', 128, 48);
17 | }
18 |
19 | function create() {
20 | var openButton = new uiWidgets.TextButton(this.game, 100, 50, "button", createModal, this, 1, 0, 2, 1)
21 | .setText("Open", textStyle)
22 | .eventTextYAdjustment(3);
23 |
24 | console.log(openButton.x, openButton.button.x, openButton.text.x)
25 |
26 | }
27 |
28 | function createModal() {
29 | var closeButton = new uiWidgets.TextButton(this.game, 0, 0, "button", closeCallback, this, 1, 0, 2, 1)
30 | .setText("Close", textStyle)
31 | .eventTextYAdjustment(3);
32 |
33 | this.modal = new uiWidgets.Column(this.game, 100, 100, bg="modalBg", modal=true);
34 | this.modal.addNode(closeButton, paddingX=0, paddingY=10);
35 | }
36 |
37 | function closeCallback() {
38 | this.modal.dismiss();
39 | }
40 |
--------------------------------------------------------------------------------
/docs/examples/js/phaserce/quantitybar.js:
--------------------------------------------------------------------------------
1 | var game = new Phaser.Game(600, 400, Phaser.AUTO, 'quantitybar', { preload: preload, create: create});
2 |
3 | function preload() {
4 | var assetRoot = '../../assets/quantitybar/';
5 | game.load.image("track", assetRoot + "horizontal/track.png");
6 | game.load.spritesheet('bar', assetRoot + 'horizontal/bar.png', 260, 32);
7 |
8 | game.load.image("vtrack", assetRoot + "vertical/track.png");
9 | game.load.spritesheet('vbar', assetRoot + 'vertical/bar.png', 32, 260);
10 |
11 | game.load.image("add", assetRoot + "add.png");
12 | game.load.image("subtract", assetRoot + "subtract.png");
13 | }
14 |
15 | var healthbar,
16 | healthbarText,
17 | vhealthbar,
18 | vhealthbarText,
19 | rhealthbar,
20 | rhealthbarText,
21 | rvhealthbar,
22 | rvhealthbarText,
23 | decreaseHealth,
24 | increaseHealth,
25 | vdecreaseHealth,
26 | vincreaseHealth,
27 | rdecreaseHealth,
28 | rincreaseHealth,
29 | rvdecreaseHealth,
30 | rvincreaseHealth,
31 | textStyle;
32 |
33 | function create() {
34 |
35 | textStyle = {
36 | font: "65px Arial",
37 | fill: "#ff0044",
38 | align: "center"
39 | };
40 |
41 | // Create a quantitybar starting at 50.
42 | healthbar = new uiWidgets.QuantityBar(
43 | game,
44 | {"x": 50, "y": 10},
45 | {"startValue": 50, maxValue: 100},
46 | false,
47 | false,
48 | "track",
49 | "bar",
50 | {'duration': 400, 'ease': Phaser.Easing.Quadratic.Out}
51 | );
52 |
53 | // Display the quantitybar's value.
54 | healthbarText = game.add.text(50, 50, healthbar.valueRange.startValue, textStyle);
55 |
56 | // Add buttons to modify the value.
57 | var lessHealth = game.add.button(150, 10, 'subtract', decreaseHealth, this);
58 | var moreHealth = game.add.button(200, 10, 'add', increaseHealth, this);
59 |
60 | // Create a reverse quantitybar starting at 30.
61 | rhealthbar = new uiWidgets.QuantityBar(
62 | game,
63 | {"x": 350, "y": 10},
64 | {"startValue": 30, maxValue: 100},
65 | false,
66 | true,
67 | "track",
68 | "bar",
69 | {'duration': 400, 'ease': Phaser.Easing.Quadratic.Out}
70 | );
71 |
72 | rhealthbarText = game.add.text(350, 50, rhealthbar.valueRange.startValue, textStyle);
73 |
74 | var rlessHealth = game.add.button(450, 10, 'subtract', rdecreaseHealth, this);
75 | var rmoreHealth = game.add.button(500, 10, 'add', rincreaseHealth, this);
76 |
77 | // Create a vertical quantitybar starting at 50.
78 | vhealthbar = new uiWidgets.QuantityBar(
79 | game,
80 | {"x": 30, "y": 130},
81 | {"startValue": 32, maxValue: 100},
82 | true,
83 | false,
84 | "vtrack",
85 | "vbar",
86 | {'duration': 400, 'ease': Phaser.Easing.Quadratic.Out}
87 | );
88 |
89 | vhealthbarText = game.add.text(100, 150, vhealthbar.valueRange.startValue, textStyle);
90 |
91 | var vlessHealth = game.add.button(100, 250, 'subtract', vdecreaseHealth, this);
92 | var vmoreHealth = game.add.button(150, 250, 'add', vincreaseHealth, this);
93 |
94 | // Create a reverse vertical quantitybar starting at 50.
95 | rvhealthbar = new uiWidgets.QuantityBar(
96 | game,
97 | {"x": 250, "y": 130},
98 | {"startValue": 30, maxValue: 100},
99 | true,
100 | true,
101 | "vtrack",
102 | "vbar",
103 | {'duration': 400, 'ease': Phaser.Easing.Quadratic.Out}
104 | );
105 |
106 | rvhealthbarText = game.add.text(300, 150, rvhealthbar.valueRange.startValue, textStyle);
107 |
108 | var vlessHealth = game.add.button(300, 250, 'subtract', rvdecreaseHealth, this);
109 | var vmoreHealth = game.add.button(350, 250, 'add', rvincreaseHealth, this);
110 |
111 | }
112 |
113 | function increaseHealth() {
114 | healthbar.adjustBar(10);
115 | healthbarText.setText(healthbar.valueRange.getCurrentValue());
116 | }
117 |
118 | function decreaseHealth() {
119 | healthbar.adjustBar(-10);
120 | healthbarText.setText(healthbar.valueRange.getCurrentValue());
121 | }
122 |
123 | function vincreaseHealth() {
124 | vhealthbar.adjustBar(1);
125 | vhealthbarText.setText(vhealthbar.valueRange.getCurrentValue());
126 | }
127 |
128 | function vdecreaseHealth() {
129 | vhealthbar.adjustBar(-1);
130 | vhealthbarText.setText(vhealthbar.valueRange.getCurrentValue());
131 | }
132 |
133 | function rincreaseHealth() {
134 | rhealthbar.adjustBar(10);
135 | rhealthbarText.setText(rhealthbar.valueRange.getCurrentValue());
136 | }
137 |
138 | function rdecreaseHealth() {
139 | rhealthbar.adjustBar(-10);
140 | rhealthbarText.setText(rhealthbar.valueRange.getCurrentValue());
141 | }
142 |
143 | function rvincreaseHealth() {
144 | rvhealthbar.adjustBar(10);
145 | rvhealthbarText.setText(rvhealthbar.valueRange.getCurrentValue());
146 | }
147 |
148 | function rvdecreaseHealth() {
149 | rvhealthbar.adjustBar(-10);
150 | rvhealthbarText.setText(rvhealthbar.valueRange.getCurrentValue());
151 | }
152 |
--------------------------------------------------------------------------------
/docs/examples/js/phaserce/quantitybar_column.js:
--------------------------------------------------------------------------------
1 | var game = new Phaser.Game(600, 400, Phaser.AUTO, 'quantitybar_column', { preload: preload, create: create, update: update });
2 |
3 | function preload() {
4 | var assetRoot = '../../assets/quantitybar/horizontal/';
5 | game.load.image("track", assetRoot + "track.png");
6 | game.load.image('bar', assetRoot + 'bar.png');
7 |
8 | game.load.image("add", assetRoot + "add.png");
9 | game.load.image("subtract", assetRoot + "subtract.png");
10 | }
11 |
12 | var healthbar;
13 | var healthbarText;
14 | var lessHealth;
15 | var moreHealth;
16 | var column;
17 |
18 | function create() {
19 |
20 | // Create a quantitybar starting at 50.
21 | healthbar = new uiWidgets.QuantityBar(
22 | game,
23 | {"x": 0, "y": 0},
24 | {"startValue": 50, maxValue: 100},
25 | false,
26 | false,
27 | "track",
28 | "bar",
29 | {'duration': 400, 'ease': Phaser.Easing.Quadratic.Out}
30 | );
31 |
32 | healthbarText = game.add.text(50, 50, healthbar.valueRange.minValue, {
33 | font: "65px Arial",
34 | fill: "#ff0044",
35 | align: "center"
36 | });
37 |
38 | lessHealth = game.add.button(150, 10, 'subtract', decreaseHealth, this);
39 | moreHealth = game.add.button(200, 10, 'add', increaseHealth, this);
40 |
41 | column = new uiWidgets.Column(game, 30, 0);
42 | column.addNode(healthbar);
43 | column.addNode(healthbarText);
44 | console.log("a", healthbar.track.x, healthbar.track.worldPosition.x)
45 | console.log("b", healthbar.bar.x, healthbar.bar.worldPosition.x)
46 | console.log("c", healthbar.x, healthbar.worldPosition.x)
47 | //console.log(healthbar.bar.mask.x, healthbar.bar.mask.worldPosition.x)
48 | //healthbar.bar.mask.x = 30
49 | //healthbar.bar.mask.y = 30
50 |
51 | }
52 |
53 | function update() {
54 | healthbarText.setText(healthbar.valueRange.getCurrentValue());
55 | }
56 |
57 | function increaseHealth() {
58 | healthbar.adjustBar(10);
59 |
60 | }
61 |
62 | function decreaseHealth() {
63 | healthbar.adjustBar(-10);
64 | }
65 |
--------------------------------------------------------------------------------
/docs/examples/js/phaserce/textover.js:
--------------------------------------------------------------------------------
1 | var game = new Phaser.Game(
2 | 400,
3 | 300,
4 | Phaser.AUTO,
5 | 'textover',
6 | {preload: preload, create: create},
7 | false,
8 | false,
9 | );
10 |
11 | var textStyle = {'fill': '#FFF', 'font': '16px Courier New'};
12 |
13 | function preload() {
14 | var assetRoot = '../../assets/textover/';
15 | game.load.image("header", assetRoot + "header.png");
16 | game.load.spritesheet('button', assetRoot + 'button.png', 128, 48);
17 | }
18 |
19 | function create() {
20 | this.header = new uiWidgets.TextSprite(game, 0, 0, "header").setText('Header', textStyle);
21 |
22 | var buttonOne = new uiWidgets.TextButton(game, 0, 0, "button", newGameCallback, this, 1, 0, 2, 1)
23 | .setText("New Game", textStyle)
24 | .eventTextYAdjustment(3);
25 | var buttonTwo = new uiWidgets.TextButton(game, 0, 0, "button", continueCallback, this, 1, 0, 2, 1)
26 | .setText("Continue", textStyle)
27 | .eventTextYAdjustment(3);
28 | var buttonThree = new uiWidgets.TextButton(game, 0, 0, "button", optionsCallback, this, 1, 0, 2, 1)
29 | .setText("Options", textStyle)
30 | .eventTextYAdjustment(3);
31 |
32 | var column = new uiWidgets.Column(this, 200, 100);
33 | column.addNode(buttonOne, paddingX=0, paddingY=10);
34 | column.addNode(buttonTwo, paddingX=0, paddingY=10);
35 | column.addNode(buttonThree, paddingX=0, paddingY=10);
36 |
37 | }
38 |
39 | function newGameCallback() {
40 | this.header.text.setText('You clicked the New Game button');
41 | }
42 |
43 |
44 | function continueCallback() {
45 | this.header.text.setText('You clicked the Continue button');
46 | }
47 |
48 |
49 | function optionsCallback() {
50 | this.header.text.setText('You clicked the Options button');
51 | }
52 |
--------------------------------------------------------------------------------
/docs/examples/js/phaserce/valuebar.js:
--------------------------------------------------------------------------------
1 | var game = new Phaser.Game(600, 400, Phaser.AUTO, 'valuebar', { preload: preload, create: create });
2 |
3 | function preload() {
4 | var assetRoot = '../../assets/valuebar/';
5 | game.load.image("track", assetRoot + "track.png");
6 | game.load.spritesheet('bar', assetRoot + 'bar.png', 32, 32);
7 | game.load.image("vtrack", assetRoot + "vtrack.png");
8 | game.load.image("alphaImage", assetRoot + "alpha.png");
9 | }
10 |
11 | var valuebar0;
12 | var valuebar50;
13 | var vvaluebar50;
14 | var valuebar0_text;
15 | var valuebar50_text;
16 | var vvaluebar50_text;
17 | var alphaImage;
18 |
19 | function create() {
20 |
21 | // Create a valuebar starting at 0.
22 | valuebar0 = new uiWidgets.ValueBar(
23 | game,
24 | {"x": 50, "y": 10},
25 | {"step": 1, "startValue": 0, maxValue: 100},
26 | true,
27 | false,
28 | "track",
29 | "bar",
30 | {'duration': 100, 'ease': Phaser.Easing.Quadratic.Out}
31 | );
32 |
33 | valuebar0_text = game.add.text(50, 50, valuebar0.valueRange.startValue, {
34 | font: "65px Arial",
35 | fill: "#ff0044",
36 | align: "center"
37 | });
38 |
39 | valuebar0.valueDisplay = valuebar0_text;
40 |
41 | // Use the onMovement signal to update the display of text when the bar is moved.
42 | valuebar0.emitter.on('movement', updateValueDisplay);
43 |
44 | // Create a valuebar starting at 50.
45 | valuebar50 = new uiWidgets.ValueBar(
46 | game,
47 | {"x": 50, "y": 150},
48 | {"step": 25, "startValue": 50, maxValue: 100},
49 | true,
50 | false,
51 | "track",
52 | "bar",
53 | {'duration': 100, 'ease': Phaser.Easing.Quadratic.Out}
54 | );
55 |
56 | valuebar50_text = game.add.text(50, 200, valuebar50.valueRange.startValue, {
57 | font: "65px Arial",
58 | fill: "#ff0044",
59 | align: "center"
60 | });
61 |
62 | valuebar50.valueDisplay = valuebar50_text;
63 | valuebar50.emitter.on('movement', updateValueDisplay);
64 |
65 | // Create a vertical valuebar starting at 50.
66 | vvaluebar50 = new uiWidgets.ValueBar(
67 | game,
68 | {"x": 350, "y": 50},
69 | {"step": 25, "startValue": 50, maxValue: 100},
70 | true,
71 | true,
72 | "vtrack",
73 | "bar",
74 | {'duration': 100, 'ease': Phaser.Easing.Quadratic.Out}
75 | );
76 |
77 | vvaluebar50_text = game.add.text(400, 200, valuebar50.valueRange.startValue, {
78 | font: "65px Arial",
79 | fill: "#ff0044",
80 | align: "center"
81 | });
82 |
83 | vvaluebar50.valueDisplay = vvaluebar50_text;
84 | vvaluebar50.emitter.on('movement', updateValueDisplay);
85 |
86 | alphaImage = game.add.sprite(500, 100, "alphaImage");
87 | alphaImage.alpha = vvaluebar50.valueRange.getCurrentValue() / 100;
88 |
89 | // Use the onMovement signal to updte the sprite's opacity whenever the bar is moved.
90 | vvaluebar50.emitter.on('movement', updateAlpha);
91 | }
92 |
93 | function updateValueDisplay(bar) {
94 | bar.valueDisplay.setText(bar.valueRange.getCurrentValue());
95 | }
96 |
97 | function updateAlpha(bar) {
98 | alphaImage.alpha = bar.valueRange.getCurrentValue() / 100;
99 | }
100 |
--------------------------------------------------------------------------------
/docs/examples/js/phaserce/valuebar_column.js:
--------------------------------------------------------------------------------
1 | var game = new Phaser.Game(600, 400, Phaser.AUTO, 'valuebar_column', { preload: preload, create: create });
2 |
3 | function preload() {
4 | var assetRoot = '../../assets/valuebar/';
5 | game.load.image("bg", assetRoot + "background.png");
6 | game.load.image("track", assetRoot + "track.png");
7 | game.load.spritesheet('bar', assetRoot + 'bar.png', 32, 32);
8 | game.load.image("pointer", assetRoot + "pointer.png");
9 |
10 | game.load.image("vtrack", "assets/valuebar/vtrack.png");
11 | }
12 |
13 | var bar;
14 | var bar2;
15 | var barText;
16 | var barText2;
17 | var lessHealth;
18 | var moreHealth;
19 | var column;
20 | var keyboardGroup;
21 | var cursor;
22 |
23 | function create() {
24 | // Create a quantitybar starting at 50.
25 | bar = new uiWidgets.ValueBar(
26 | game,
27 | {"x": 0, "y": 0},
28 | {"step": 25, "startValue": 50, maxValue: 100},
29 | true,
30 | false,
31 | "track",
32 | "bar",
33 | {'duration': 100, 'ease': Phaser.Easing.Quadratic.Out}
34 | );
35 |
36 | barText = game.add.text(50, 50, bar.valueRange.startValue, {
37 | font: "24px Arial",
38 | fill: "#ff0044",
39 | align: "center"
40 | });
41 |
42 | bar.valueDisplay = barText;
43 | bar.emitter.on('movement', updateValueDisplay);
44 |
45 | // Create a quantitybar starting at 50.
46 | bar2 = new uiWidgets.ValueBar(
47 | game,
48 | {"x": 0, "y": 0},
49 | {"step": 25, "startValue": 50, maxValue: 100},
50 | true,
51 | false,
52 | "track",
53 | "bar",
54 | {'duration': 100, 'ease': Phaser.Easing.Quadratic.Out}
55 | );
56 |
57 | barText2 = game.add.text(50, 50, bar2.valueRange.startValue, {
58 | font: "24px Arial",
59 | fill: "#ff0044",
60 | align: "center"
61 | });
62 |
63 | bar2.valueDisplay = barText2;
64 | bar2.emitter.on('movement', updateValueDisplay);
65 |
66 | var prevItemCallback = function (group, context) {
67 | cursor.y = group.selected.worldPosition.y - (group.selected.height/4);
68 | };
69 |
70 | var nextItemCallback = function (group, context) {
71 | cursor.y = group.selected.worldPosition.y - (group.selected.height/4);
72 | };
73 |
74 | column = new uiWidgets.Column(game, 150, 50, "bg");
75 | column.addNode(bar);
76 | column.addNode(barText);
77 | column.addNode(bar2);
78 | column.addNode(barText2);
79 |
80 | // Example of using prev/nextItem callback.
81 | // Create a cursor and move to the selected child's position.
82 | cursor = game.add.sprite(100, 42, 'pointer');
83 |
84 | // Create a KeyboardGroup and add the Bars to it.
85 | keyboardGroup = new uiWidgets.KeyboardGroup(game, true, this);
86 | keyboardGroup.addNode(bar);
87 | keyboardGroup.addNode(bar2);
88 |
89 | keyboardGroup.emitter.on('previous', prevItemCallback);
90 | keyboardGroup.emitter.on('next', nextItemCallback);
91 | }
92 |
93 | function updateValueDisplay(bar) {
94 | bar.valueDisplay.setText(bar.valueRange.getCurrentValue());
95 | }
96 |
--------------------------------------------------------------------------------
/docs/examples/js/phaserce/vscrollbar.js:
--------------------------------------------------------------------------------
1 | var game = new Phaser.Game(600, 400, Phaser.AUTO, 'vscrollbar', { preload: preload, create: create });
2 |
3 | function preload() {
4 | var assetRoot = '../../assets/vertical/';
5 | game.load.image("dummyButton", assetRoot + "sprite.png");
6 | game.load.image("track", assetRoot + "track.png");
7 | game.load.spritesheet('bar', assetRoot + 'bar.png', 22, 44);
8 | }
9 |
10 | function create() {
11 |
12 | // Create a viewport. A "window" with a limited area of view.
13 | var viewport = new uiWidgets.Viewport(game, 75, 75, 600, 260);
14 |
15 | // Create a column. Anything added to a column is placed under the previous thing added.
16 | var column = new uiWidgets.Column(game);
17 |
18 | // Put the column inside the viewport.
19 | viewport.addNode(column);
20 |
21 | // Add things to the column.
22 | var dummy_sprite_a = this.game.add.sprite(0, 0, "dummyButton");
23 | var dummy_sprite_b = this.game.add.sprite(0, 0, "dummyButton");
24 | var dummy_sprite_c = this.game.add.sprite(0, 0, "dummyButton");
25 | var dummy_sprite_d = this.game.add.sprite(0, 0, "dummyButton");
26 | var dummy_sprite_e = this.game.add.sprite(0, 0, "dummyButton");
27 | var dummy_sprite_f = this.game.add.sprite(0, 0, "dummyButton");
28 |
29 | column.addNode(dummy_sprite_a);
30 | column.addNode(dummy_sprite_b);
31 | column.addNode(dummy_sprite_c);
32 | column.addNode(dummy_sprite_d);
33 | column.addNode(dummy_sprite_e);
34 | column.addNode(dummy_sprite_f);
35 |
36 | // Create a scrollbar for the viewport.
37 | var scrollbar = new uiWidgets.Scrollbar(
38 | game,
39 | viewport,
40 | true,
41 | true,
42 | "track",
43 | "bar",
44 | {'duration': 300, 'ease': Phaser.Easing.Quadratic.Out}
45 | );
46 |
47 | // Place scrollbar next to viewport.
48 | scrollbar.alignTo(viewport, Phaser.RIGHT_TOP, 10);
49 | }
50 |
--------------------------------------------------------------------------------
/docs/examples/js/phaserce/wheel3D.js:
--------------------------------------------------------------------------------
1 | var game = new Phaser.Game(
2 | 600,
3 | 400,
4 | Phaser.AUTO,
5 | 'wheel3D',
6 | { preload: preload, create: create },
7 | );
8 |
9 | function preload() {
10 | var assetRoot = '../../assets/wheel3D/';
11 | game.load.image("icon", assetRoot + "icon.png");
12 | game.load.image("mmUp", assetRoot + "mmUp.png");
13 | game.load.image("mmDown", assetRoot + "mmDown.png");
14 | }
15 |
16 | function create() {
17 |
18 | // Example 1: Rotate around the Y axis
19 |
20 | // Build a list of sprites for the wheel.
21 | var menuListY = [];
22 |
23 | for (var i = 0; i < 12; i++) {
24 | var icon = game.add.sprite(0, 0, 'icon');
25 | menuListY.push(icon);
26 | }
27 |
28 | // Create the wheel.
29 | menuWheelY = new uiWidgets.Wheel3D(
30 | game,
31 | {"x": game.world.centerX - 100, "y": game.world.centerY},
32 | menuListY,
33 | 0,
34 | 90,
35 | "y",
36 | {"x":0, "y": -90, "z": 0}
37 | );
38 |
39 | // Tint the active item after each movement.
40 | menuWheelY.emitter.on('complete',
41 | function(wheel) {
42 | for (var i = 0; i < 12; i++) {
43 | wheel.sprites[i].tint = 0xFFFFFF;
44 | }
45 | wheel.active.tint = 0xdc21ff;
46 | }
47 | );
48 |
49 | menuWheelY.activate();
50 |
51 | // Scroll Buttons
52 | var scrollLeftButtonY = this.game.add.button(
53 | 0,
54 | game.world.centerY,
55 | "mmUp",
56 | scrollTheWheel,
57 | this,
58 | );
59 | scrollLeftButtonY.wheel = menuWheelY;
60 | scrollLeftButtonY.dir = 0;
61 |
62 | var scrollRightButtonY = this.game.add.button(
63 | 0,
64 | game.world.centerY + 48,
65 | "mmDown",
66 | scrollTheWheel,
67 | this,
68 | );
69 | scrollRightButtonY.wheel = menuWheelY;
70 | scrollRightButtonY.dir = 1;
71 |
72 | // Example 2: Rotate around the X axis
73 | var menuListX = [];
74 |
75 | for (var i = 0; i < 12; i++) {
76 | var icon = game.add.sprite(0, 0, 'icon');
77 | menuListX.push(icon);
78 | }
79 |
80 | // Create the wheel.
81 | menuWheelX = new uiWidgets.Wheel3D(
82 | game,
83 | {"x": game.world.centerX - 100, "y": 100},
84 | menuListX,
85 | 0,
86 | 90,
87 | "x",
88 | {"x": 90, "y": 0, "z": 0}
89 | );
90 |
91 | // Tint the active item after each movement.
92 | menuWheelX.emitter.on('complete',
93 | function(wheel) {
94 | for (var i = 0; i < 12; i++) {
95 | wheel.sprites[i].tint = 0xFFFFFF;
96 | }
97 | wheel.active.tint = 0xdc21ff;
98 | }
99 | );
100 |
101 | menuWheelX.activate();
102 |
103 | // Scroll Buttons
104 | var scrollLeftButtonX = this.game.add.button(
105 | 0,
106 | 0,
107 | "mmUp",
108 | scrollTheWheel,
109 | this,
110 | );
111 | scrollLeftButtonX.wheel = menuWheelX;
112 | scrollLeftButtonX.dir = 0;
113 |
114 | var scrollRightButtonX = this.game.add.button(
115 | 0,
116 | 48,
117 | "mmDown",
118 | scrollTheWheel,
119 | this,
120 | );
121 | scrollRightButtonX.wheel = menuWheelX;
122 | scrollRightButtonX.dir = 1;
123 |
124 | // Example 3: Rotate around the Z axis
125 | var menuListZ = [];
126 |
127 | for (var i = 0; i < 12; i++) {
128 | var icon = game.add.sprite(0, 0, 'icon');
129 | menuListZ.push(icon);
130 | }
131 |
132 | // Create the wheel.
133 | menuWheelZ = new uiWidgets.Wheel3D(
134 | game,
135 | {"x": game.world.centerX, "y": 100},
136 | menuListZ,
137 | 0,
138 | 90,
139 | "z",
140 | {"x": 0, "y": 0, "z": 90}
141 | );
142 |
143 | menuWheelZ.emitter.on('start',
144 | function(wheel) {
145 | for (var i = 0; i < 12; i++) {
146 | wheel.sprites[i].tint = 0xFFFFFF;
147 | }
148 | wheel.active.tint = 0xdc21ff;
149 | }
150 | );
151 |
152 | menuWheelZ.activate();
153 |
154 | // Scroll Buttons
155 | var scrollLeftButtonZ = this.game.add.button(
156 | game.world.width - 100,
157 | 0,
158 | "mmUp",
159 | scrollTheWheel,
160 | this,
161 | );
162 | scrollLeftButtonZ.wheel = menuWheelZ;
163 | scrollLeftButtonZ.dir = 0;
164 |
165 | var scrollRightButtonZ = this.game.add.button(
166 | game.world.width - 100,
167 | 48,
168 | "mmDown",
169 | scrollTheWheel,
170 | this,
171 | );
172 | scrollRightButtonZ.wheel = menuWheelZ;
173 | scrollRightButtonZ.dir = 1;
174 | }
175 |
176 | var scrollTheWheel = function (item) {
177 | if (item.dir === 0){
178 | item.wheel.moveBack();
179 | }
180 | if (item.dir === 1){
181 | item.wheel.moveForward();
182 | }
183 | };
184 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "phaser-ui-tools",
3 | "version": "2.0.0-beta",
4 | "description": "User Interface objects for the phaser game engine.",
5 | "author": "Joshua Fehler ",
6 | "repository": "github:jsfehler/phaser-ui-tools",
7 | "license": "MIT",
8 | "main": "dist/phaser-ui-tools.js",
9 | "unpkg": "dist/phaser-ui-tools.min.js",
10 | "files": [
11 | "dist/phaser-ui-tools.js",
12 | "dist/phaser-ui-tools.min.js"
13 | ],
14 | "scripts": {
15 | "build:js": "webpack",
16 | "test": "mocha-headless-chrome -f tests/testrunner.html",
17 | "test3": "mocha-headless-chrome -f tests/testrunner_phaser3.html",
18 | "copyToExamplesLib": "copyfiles -f dist/phaser-ui-tools.js docs/examples/lib/",
19 | "build:docs": "documentation build src/** -f html -o docs"
20 | },
21 | "devDependencies": {
22 | "@babel/core": "^7.23.9",
23 | "@babel/preset-env": "^7.23.9",
24 | "babel-loader": "^9.1.3",
25 | "chai": "^4.3.4",
26 | "copyfiles": "^2.4.1",
27 | "documentation": "^14.0.2",
28 | "eslint": "^8.56.0",
29 | "eslint-config-airbnb-base": "^15.0.0",
30 | "eslint-plugin-import": "^2.29.1",
31 | "eslint-webpack-plugin": "^4.0.1",
32 | "mocha": "^10.2.0",
33 | "mocha-headless-chrome": "^4.0.0",
34 | "webpack": "^5.90.0",
35 | "webpack-cli": "^5.1.4"
36 | },
37 | "peerDependencies": {
38 | "phaser": "^3.60.0",
39 | "phaser-ce": "2.20.0"
40 | },
41 | "peerDependenciesMeta": {
42 | "phaser-ce": {
43 | "optional": true
44 | },
45 | "phaser": {
46 | "optional": true
47 | }
48 | },
49 | "dependencies": {
50 | "eventemitter3": "^5.0.1"
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/bars/bar.js:
--------------------------------------------------------------------------------
1 | import * as PhaserObjects from '../phaserObjects';
2 |
3 | /** Base object for all Bar-like Widgets.
4 | * @private
5 | * @extends PhaserObjects.Group
6 | */
7 | export class Bar extends PhaserObjects.Group {
8 | /**
9 | * @param {Object} game - Current game instance.
10 | * @param {number} x - The Bar's x position.
11 | * @param {number} y - The Bar's y position.
12 | * @param {boolean} vertical - Sets the Bar's alignment as vertical.
13 | * @param {string} trackKey - The key to use for the track.
14 | * @param {string} barKey - The key to use for the bar.
15 | */
16 | constructor(game, x = 0, y = 0, vertical = false, trackKey = '', barKey = '') {
17 | super(game);
18 | game.add.existing(this);
19 |
20 | this.game = game;
21 | this.x = x;
22 | this.y = y;
23 |
24 | this.vertical = vertical;
25 |
26 | this.trackKey = trackKey;
27 | this.barKey = barKey;
28 | }
29 |
30 | /**
31 | * @private
32 | * Determine the distance the bar can scroll over.
33 | */
34 | setTrackScrollAreaSize() {
35 | if (this.vertical) {
36 | this.trackScrollAreaSize = this.track.height - this.vslice;
37 | } else {
38 | this.trackScrollAreaSize = this.track.width - this.hslice;
39 | }
40 | }
41 |
42 | /**
43 | * @private
44 | * Sets position for the bar's non-moving axis. Centers it inside the track.
45 | */
46 | centerStaticAxis() {
47 | if (this.vertical) {
48 | this.bar.x = (
49 | this.track.x + (this.track.width / 2)) - (this.bar.displayWidth / 2);
50 | } else {
51 | this.bar.y = (
52 | this.track.y + (this.track.height / 2)) - (this.bar.displayHeight / 2);
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/bars/draggable_bar.js:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from 'eventemitter3';
2 | import * as PhaserObjects from '../phaserObjects';
3 | import { Bar } from './bar';
4 |
5 | /**
6 | * Base object for Bars that can be manipulated with a mouse.
7 | * @private
8 | * @extends Bar
9 | */
10 | export class DraggableBar extends Bar {
11 | constructor(game, x = 0, y = 0, vertical = false, trackKey = '', barKey = '') {
12 | super(game, x, y, vertical, trackKey, barKey);
13 | this.emitter = new EventEmitter();
14 | }
15 |
16 | /**
17 | * @private
18 | * If the vertical scrollbar is draggable,
19 | * this function is called when the track is clicked.
20 | */
21 | verticalTrackClick() {
22 | // Don't register mouse clicks on the bar itself.
23 | const mouseY = this.game.input.mousePointer.y;
24 |
25 | let barY = this.bar.y + this.worldPosition.y;
26 |
27 | if (this.parentContainer) {
28 | barY += this.parentContainer.y;
29 | }
30 |
31 | if (mouseY > barY + this.bar.displayHeight) {
32 | this.scrollDown();
33 | } else if (mouseY < barY) {
34 | this.scrollUp();
35 | }
36 | }
37 |
38 | /**
39 | * @private
40 | * If the horizontal scrollbar is draggable,
41 | * this function is called when the track is clicked.
42 | */
43 | horizontalTrackClick() {
44 | // Don't register mouse clicks on the bar itself.
45 | const mouseX = this.game.input.mousePointer.x;
46 |
47 | let barX = this.bar.x + this.worldPosition.x;
48 |
49 | if (this.parentContainer) {
50 | barX += this.parentContainer.x;
51 | }
52 |
53 | if (mouseX > barX + this.bar.displayWidth) {
54 | this.scrollRight();
55 | } else if (mouseX < barX) {
56 | this.scrollLeft();
57 | }
58 | }
59 |
60 | /**
61 | * @private
62 | * Allows the bar to scroll when the track is clicked directly.
63 | */
64 | enableTrackClick() {
65 | let event;
66 |
67 | this.track.setInteractive();
68 |
69 | if (this.vertical) {
70 | event = this.verticalTrackClick;
71 | } else {
72 | event = this.horizontalTrackClick;
73 | }
74 |
75 | this.track.addDownEvent(event, this);
76 | }
77 |
78 | /**
79 | * @private
80 | * When called, ensures the bar can be moved.
81 | * Must be called once the bar has finished scrolling.
82 | */
83 | enableBarInput() {
84 | this.trackClicked = false;
85 | this.barMoving = false;
86 | this.bar.enableDragging(this.vertical);
87 | }
88 |
89 | /**
90 | * @private
91 | * Enables clicking and dragging on the bar.
92 | */
93 | enableBarDrag() {
94 | this.setDraggableArea();
95 |
96 | this.bar.enableDragging(this.vertical);
97 |
98 | let draggableArea;
99 |
100 | if (this.vertical) {
101 | draggableArea = this.verticalDraggableArea;
102 | } else {
103 | draggableArea = this.horizontalDraggableArea;
104 | }
105 |
106 | this.bar.setDragBounds(draggableArea);
107 |
108 | if (this.snapping) {
109 | this.bar.addUpEvent(this.snapToClosestPosition, this);
110 | }
111 | this.bar.addDownEvent(this.saveMousePosition, this);
112 | this.bar.addDragEvent(this.moveContent, this);
113 | }
114 |
115 | saveMousePosition(pointer) {
116 | // When the bar is dragged, record where the mouse clicked down.
117 | this.mousePointer = {
118 | x: pointer.x - (pointer.x - this.bar.x),
119 | y: pointer.y - (pointer.y - this.bar.y),
120 | };
121 | }
122 |
123 | getBarPosition() {
124 | const currentValue = this.valueRange.getCurrentValue();
125 | const windowPositionRatio = currentValue / this.windowScrollAreaSize;
126 | return this.trackScrollAreaSize * windowPositionRatio;
127 | }
128 |
129 | getMouseDelta() {
130 | // Only difference between clicking the track/using the keyboard vs mouse drag.
131 | let newMousePointer;
132 | if (this.trackClicked) {
133 | newMousePointer = { x: this.bar.x, y: this.bar.y };
134 | } else {
135 | const { mousePointer } = this.game.input;
136 | newMousePointer = {
137 | x: mousePointer.x - (mousePointer.x - this.bar.x),
138 | y: mousePointer.y - (mousePointer.y - this.bar.y),
139 | };
140 | }
141 |
142 | let oldMousePosition;
143 | let newMousePosition;
144 | if (this.vertical) {
145 | oldMousePosition = this.mousePointer.y;
146 | newMousePosition = newMousePointer.y;
147 | } else {
148 | oldMousePosition = this.mousePointer.x;
149 | newMousePosition = newMousePointer.x;
150 | }
151 |
152 | this.mousePointer = newMousePointer;
153 |
154 | // Only update when the new position is inside the track.
155 | let mousePositionDelta;
156 | if (newMousePosition < this.maxValue) {
157 | mousePositionDelta = oldMousePosition - newMousePosition;
158 | } else {
159 | mousePositionDelta = 0;
160 | }
161 |
162 | return mousePositionDelta;
163 | }
164 |
165 | /**
166 | * @private
167 | * Creates the tween for moving the bar to a new position.
168 | */
169 | addScrollTween(properties) {
170 | this.mousePointer = { x: this.bar.x, y: this.bar.y };
171 | this.trackClicked = true;
172 |
173 | new PhaserObjects.Tween(this.game).add(
174 | this.bar,
175 | properties,
176 | this.tweenParams.duration,
177 | this.tweenParams.ease,
178 | this.enableBarInput,
179 | this.moveContent,
180 | null,
181 | this,
182 | );
183 | }
184 |
185 | /** For Vertical Scrollbars. Scrolls up by one step. */
186 | scrollUp() {
187 | // Prevents users from moving the bar while it's moving.
188 | if (this.bar.y !== this.track.y && !this.barMoving) {
189 | const testPosition = this.bar.y - this.vslice;
190 | let moveToY = null;
191 | this.barMoving = true;
192 |
193 | // Ensure the bar can't move above the track.
194 | if (testPosition <= this.track.y) {
195 | moveToY = this.minY;
196 | } else {
197 | moveToY = this.bar.y - this.vslice;
198 | }
199 |
200 | this.addScrollTween({ y: moveToY });
201 | }
202 | }
203 |
204 | /** For Vertical Scrollbars. Scrolls down by one step. */
205 | scrollDown() {
206 | if (this.bar.y + this.bar.displayHeight !== this.track.y + this.track.height && !this.barMoving) {
207 | const testPosition = this.bar.y + (this.vslice * 2);
208 | let moveToY = null;
209 | this.barMoving = true;
210 | this.bar.disableInteractive();
211 |
212 | // Ensure the bar can't move below the track.
213 | if (testPosition >= this.track.y + this.track.height) {
214 | moveToY = this.maxY;
215 | } else {
216 | moveToY = this.bar.y + this.vslice;
217 | }
218 |
219 | this.addScrollTween({ y: moveToY });
220 | }
221 | }
222 |
223 | /** For Horizontal Scrollbars. Scrolls left by one step. */
224 | scrollLeft() {
225 | if (this.bar.x !== this.track.x && !this.barMoving) {
226 | const testPosition = this.bar.x - this.hslice;
227 | let moveToX = null;
228 | this.barMoving = true;
229 | this.bar.disableInteractive();
230 |
231 | // Ensure the bar can't move above the track.
232 | if (testPosition <= this.track.x) {
233 | moveToX = this.minX;
234 | } else {
235 | moveToX = this.bar.x - this.hslice;
236 | }
237 |
238 | this.addScrollTween({ x: moveToX });
239 | }
240 | }
241 |
242 | /** For Horizontal Scrollbars. Scrolls right by one step. */
243 | scrollRight() {
244 | if (this.bar.x + this.bar.displayWidth !== this.track.x + this.track.width && !this.barMoving) {
245 | const testPosition = this.bar.x + (this.hslice * 2);
246 | let moveToX = null;
247 | this.barMoving = true;
248 | this.bar.disableInteractive();
249 |
250 | // Ensure the bar can't move below the track.
251 | if (testPosition >= this.track.x + this.track.width) {
252 | moveToX = this.maxX;
253 | } else {
254 | moveToX = this.bar.x + this.hslice;
255 | }
256 |
257 | this.addScrollTween({ x: moveToX });
258 | }
259 | }
260 |
261 | /** Called when the scrollbar needs to move the viewport.
262 | * Causes the content to move relative to the bar's position on the track.
263 | */
264 | moveContent() {
265 | const newGripPositionRatio = this.getGripPositionRatio();
266 |
267 | const newContentPosition = newGripPositionRatio * this.windowScrollAreaSize;
268 |
269 | this.valueRange.adjustValue(newContentPosition);
270 |
271 | this.emitter.emit('movement', this);
272 | }
273 | }
274 |
--------------------------------------------------------------------------------
/src/bars/quantitybar.js:
--------------------------------------------------------------------------------
1 | import { Bar } from './bar';
2 |
3 | import { QuantityRange } from './ranges';
4 |
5 | import * as PhaserObjects from '../phaserObjects';
6 |
7 | /**
8 | * Bar that adjusts the size of a static sprite based on a value.
9 | * This is done by masking the sprite and then resizing the mask.
10 | * @extends Bar
11 | */
12 | export class QuantityBar extends Bar {
13 | /**
14 | * @param {Object} game - Current game instance.
15 | * @param {Object} xy - Dictionary with the values for the bar's x and y position.
16 | * @param {Object} values - The numerical values for the bar.
17 | * @param {boolean} vertical - Determines if the bar should be vertical or horizontal.
18 | * @param {boolean} reverse - Determines the direction the bar moves when adjusted.
19 | * @param {string} trackKey - The key to use for the track.
20 | * @param {string} barKey - The key to use for the bar.
21 | * @param {Object} tweenParams - Object with duration and easing function for the scrolling tween.
22 | */
23 | constructor(
24 | game,
25 | xy,
26 | values,
27 | vertical = false,
28 | reverse = false,
29 | trackKey = '',
30 | barKey = '',
31 | tweenParams = null,
32 | ) {
33 | super(game, xy.x, xy.y, vertical, trackKey, barKey);
34 |
35 | this.uiWidgetsObjectRole = 'quantitybar';
36 |
37 | this.valueRange = new QuantityRange(
38 | this,
39 | values.startValue,
40 | values.maxValue,
41 | );
42 |
43 | this.reverse = reverse || false;
44 |
45 | this.tweenParams = tweenParams || { duration: 300, ease: PhaserObjects.Easing.Quadratic.Out };
46 |
47 | // The track is the static area the bar will move along.
48 | this.track = new PhaserObjects.Sprite(game, 0, 0, this.trackKey);
49 |
50 | // Phaser 3:
51 | // Anchor the track to 0 instead of 0.5
52 | this.track.displayOriginX = 0;
53 | this.track.displayOriginY = 0;
54 |
55 | this.add(this.track);
56 |
57 | this.width = this.track.width;
58 | this.height = this.track.height;
59 |
60 | // The bar is a static image taking up the width of the track.
61 | this.bar = new PhaserObjects.Sprite(
62 | game,
63 | 0,
64 | 0,
65 | this.barKey,
66 | );
67 |
68 | // Phaser 3:
69 | // Anchor the track to 0 instead of 0.5
70 | this.bar.displayOriginX = 0;
71 | this.bar.displayOriginY = 0;
72 |
73 | this.add(this.bar);
74 |
75 | this.create();
76 | }
77 |
78 | /**
79 | * @private
80 | * Sets the bar's mask.
81 | */
82 | setMask() {
83 | if (this.bar.mask !== null) {
84 | this.bar.mask.destroy();
85 | this.bar.mask = null;
86 | }
87 |
88 | const mask = new PhaserObjects.ViewportMask(this.game, this.maskX, this.maskY);
89 | this.bar.mask = mask.create(this.bar.maskX, this.bar.maskY, this.maskW, this.maskH);
90 |
91 | // Phaser CE: Mask must be added to Group
92 | if (this.version === undefined) {
93 | this.add(mask);
94 | }
95 | }
96 |
97 | getMaskXY(x = 0, y = 0) {
98 | // Phaser CE: Mask starts at bar xy, Phaser 3: Mask starts at group xy
99 | let maskX;
100 | let maskY;
101 |
102 | maskX = x;
103 | maskY = y;
104 |
105 | if (this.version === undefined) {
106 | maskX += this.bar.x;
107 | maskY += this.bar.y;
108 | } else {
109 | maskX += this.x;
110 | maskY += this.y;
111 | }
112 |
113 | // Resizes the bar.
114 | if (this.reverse) {
115 | if (this.vertical) {
116 | maskY += this.getBarFraction();
117 | } else {
118 | maskX += this.getBarFraction();
119 | }
120 | }
121 |
122 | return [maskX, maskY];
123 | }
124 |
125 | getBarPosition() {
126 | const windowPositionRatio = this.valueRange.getRatio() / this.windowScrollAreaSize;
127 | return this.trackScrollAreaSize * windowPositionRatio;
128 | }
129 |
130 | create(maskX = 0, maskY = 0) {
131 | this.centerStaticAxis();
132 |
133 | // Values for the bar's mask.
134 | this.maskW = this.bar.width;
135 | this.maskH = this.bar.height;
136 |
137 | const [mx, my] = this.getMaskXY(maskX, maskY);
138 | this.maskX = mx;
139 | this.maskY = my;
140 |
141 | this.setMask();
142 |
143 | const barSize = this.getBarSize();
144 |
145 | if (this.reverse) {
146 | if (this.vertical) {
147 | this.bar.mask.geometryMask.scaleY = barSize;
148 | } else {
149 | this.bar.mask.geometryMask.scaleX = barSize;
150 | }
151 | } else {
152 | if (this.vertical) {
153 | this.bar.mask.geometryMask.scaleY = barSize;
154 | } else {
155 | this.bar.mask.geometryMask.scaleX = barSize;
156 | }
157 | }
158 |
159 | // Determine the distance the window can scroll over
160 | this.windowScrollAreaSize = this.valueRange.maxValue;
161 |
162 | // Represents one fraction of the track.
163 | this.vslice = (this.track.height * this.valueRange.getRatio());
164 | this.hslice = (this.track.width * this.valueRange.getRatio());
165 |
166 | this.setTrackScrollAreaSize();
167 | }
168 |
169 | /**
170 | * @private
171 | * Creates the tween for adjusting the size of the mask.
172 | * @param {Object} properties - Values for the tween's movement.
173 | */
174 | addScrollTweenMask(properties, duration, ease) {
175 | new PhaserObjects.Tween(this.game).add(
176 | this.bar.mask.geometryMask,
177 | properties,
178 | duration,
179 | ease,
180 | );
181 | }
182 |
183 | /**
184 | * Adjusts the bar by a given value.
185 | * @param {number} newValue - The value to adjust the bar by.
186 | */
187 | adjustBar(newValue) {
188 | this.valueRange.currentValue += newValue;
189 |
190 | let tween;
191 | const barSize = this.getBarSize();
192 |
193 | let moveToX;
194 | let moveToY;
195 |
196 | // Phaser 3 requires an offset
197 | if (this.version === undefined) {
198 | moveToX = 0;
199 | moveToY = 0;
200 | } else {
201 | moveToX = this.x;
202 | moveToY = this.y;
203 | }
204 |
205 | if (this.reverse) {
206 | if (this.vertical) {
207 | tween = { scaleY: barSize, y: moveToY + this.getBarFraction() };
208 | } else {
209 | tween = { scaleX: barSize, x: moveToX + this.getBarFraction() };
210 | }
211 | } else {
212 | if (this.vertical) {
213 | tween = { scaleY: barSize };
214 | } else {
215 | tween = { scaleX: barSize };
216 | }
217 | }
218 |
219 | this.addScrollTweenMask(tween, this.tweenParams.duration, this.tweenParams.ease);
220 | }
221 |
222 | getBarFraction() {
223 | let fraction;
224 | if (this.vertical) {
225 | fraction = this.track.height * this.valueRange.getRatio();
226 | } else {
227 | fraction = this.track.width * this.valueRange.getRatio();
228 | }
229 |
230 | return fraction;
231 | }
232 |
233 | /**
234 | * @private
235 | * Given a ratio between total content size and viewport size,
236 | * return an appropriate percentage of the track.
237 | */
238 | getBarSize() {
239 | let barSize;
240 |
241 | if (this.reverse) {
242 | barSize = 1 - this.valueRange.getRatio();
243 | } else {
244 | barSize = this.valueRange.getRatio();
245 | }
246 |
247 | return barSize;
248 | }
249 | }
250 |
--------------------------------------------------------------------------------
/src/bars/ranges.js:
--------------------------------------------------------------------------------
1 | /** Used by a QuantityBar to hold the bar's values. */
2 | export class QuantityRange {
3 | /**
4 | * @param {number} bar - The QuantityBar object that uses the range.
5 | * @param {number} startValue - The initial value for the bar.
6 | * @param {number} maxValue - The maximum value the bar can have.
7 | */
8 | constructor(bar, startValue, maxValue) {
9 | this.bar = bar;
10 | this.startValue = startValue;
11 | this.maxValue = maxValue;
12 |
13 | this.currentValue = startValue;
14 | }
15 |
16 | /** Returns the current ratio for how large the bar is compared to the track. */
17 | getRatio() {
18 | const ratio = this.currentValue / this.maxValue;
19 | return ratio;
20 | }
21 |
22 | /** Returns the bar's current value. */
23 | getCurrentValue() {
24 | return this.currentValue;
25 | }
26 | }
27 |
28 | /** Used by a ValueBar to hold the bar's values. */
29 | export class ValueRange {
30 | /**
31 | * @param {number} step - The amount the bar is changed by.
32 | * @param {number} startValue - The initial value for the bar.
33 | * @param {number} maxValue - The maximum value the bar can have.
34 | */
35 | constructor(step, startValue, maxValue) {
36 | this.step = step;
37 | this.startValue = startValue;
38 | this.maxValue = maxValue + step;
39 |
40 | this.ratio = step / maxValue;
41 |
42 | // The ratio between the step and max can't be greater than 1.
43 | // ie: There can't be more steps than the max value.
44 | if (this.ratio > 1) {
45 | this.ratio = 1;
46 | }
47 |
48 | this.currentValue = startValue;
49 |
50 | // List of every possible step. Used for snapping into position by the ValueBar.
51 | this.steps = [];
52 | for (let i = 0; i < this.maxValue; i += step) {
53 | this.steps.push(i);
54 | }
55 | }
56 |
57 | /** Adjusts the current value for the bar.
58 | * @param {number} newValue - The new current value.
59 | */
60 | adjustValue(newValue) {
61 | this.currentValue = newValue;
62 | }
63 |
64 | /** Returns the bar's current value. */
65 | getCurrentValue() {
66 | return this.currentValue;
67 | }
68 | }
69 |
70 | /** Used by a Scrollbar to hold the values and adjust a viewport's position. */
71 | export class ViewportRange {
72 | /**
73 | * @param {Object} viewport - The viewport to adjust.
74 | * @param {boolean} vertical - If the viewport is vertical or horizontal.
75 | */
76 | constructor(viewport, vertical) {
77 | this.viewport = viewport;
78 | this.vertical = vertical;
79 |
80 | if (vertical) {
81 | this.step = viewport.area.height;
82 | this.maxValue = viewport.realHeight;
83 | } else {
84 | this.step = viewport.area.width;
85 | this.maxValue = viewport.realWidth;
86 | }
87 |
88 | this.ratio = this.step / this.maxValue;
89 |
90 | // The ratio between the step and max can't be greater than 1.
91 | // ie: There can't be more steps than the max value.
92 | if (this.ratio > 1) {
93 | this.ratio = 1;
94 | }
95 | }
96 |
97 | /** Adjusts the viewport's position. */
98 | adjustValue(newValue) {
99 | // Set the content's new position. Uses an offset for where the viewport is on screen.
100 | if (this.vertical) {
101 | this.viewport.y = newValue + this.viewport.area.y;
102 | } else {
103 | this.viewport.x = newValue + this.viewport.area.x;
104 | }
105 |
106 | this.viewport.disableOutOfBounds(
107 | this.viewport.children,
108 | this,
109 | this.vertical,
110 | );
111 | }
112 |
113 | getCurrentValue() {
114 | let currentValue;
115 | if (this.vertical) {
116 | // y - an offset for where the viewport is on screen.
117 | currentValue = this.viewport.y - this.viewport.area.y;
118 | } else {
119 | currentValue = this.viewport.x - this.viewport.area.x;
120 | }
121 |
122 | return currentValue;
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/src/bars/scrollbar.js:
--------------------------------------------------------------------------------
1 | import { DraggableBar } from './draggable_bar';
2 |
3 | import { ViewportRange } from './ranges';
4 |
5 | import * as PhaserObjects from '../phaserObjects';
6 |
7 | /**
8 | * A bar that moves along a track.
9 | * The bar is resized relative to the size of the track and size of the content to be scrolled.
10 | * @extends DraggableBar
11 | */
12 | export class Scrollbar extends DraggableBar {
13 | /**
14 | * @param {Object} game - Current game instance.
15 | * @param {Object} content - An object to adjust via the scrollbar.
16 | * @param {boolean} draggable - Determines if the scrollbar responds to mouse clicks.
17 | * @param {boolean} vertical - Determines if the scrollbar should be vertical or horizontal.
18 | * @param {string} trackKey - The key to use for the track.
19 | * @param {string} barKey - The key to use for the bar.
20 | * @param {Object} tweenParams - Object with duration and easing function for the scrolling tween.
21 | */
22 | constructor(game, content, draggable, vertical = false, trackKey = '', barKey = '', tweenParams = null) {
23 | super(game, 0, 0, vertical, trackKey, barKey);
24 |
25 | this.game = game;
26 |
27 | this.content = content;
28 |
29 | this.valueRange = new ViewportRange(content, vertical);
30 |
31 | this.draggable = draggable || false;
32 |
33 | // The smallest pixel size allowed for the bar.
34 | this.minBarSize = 1;
35 |
36 | this.tweenParams = tweenParams || { duration: 300, ease: PhaserObjects.Easing.Quadratic.Out };
37 |
38 | // Flag switched on when the track is clicked, switched off after the bar movement is finished.
39 | this.trackClicked = false;
40 | this.barMoving = false;
41 |
42 | // Records mouse pointer when clicking the bar.
43 | this.mousePointer = null;
44 |
45 | // The track is the static area the bar will move along.
46 | this.track = new PhaserObjects.Sprite(
47 | game,
48 | this.x,
49 | this.y,
50 | this.trackKey,
51 | );
52 |
53 | // Phaser 3:
54 | // Anchor the track to 0 instead of 0.5
55 | this.track.displayOriginX = 0;
56 | this.track.displayOriginY = 0;
57 |
58 | this.add(this.track);
59 |
60 | if (this.draggable) {
61 | // If the bar is draggable, clicking the track will move the bar up or down.
62 | this.enableTrackClick();
63 | }
64 |
65 | this.createBar();
66 | this.add(this.bar);
67 |
68 | this.minY = this.track.y;
69 | this.maxY = (this.track.y + this.track.height) - this.bar.displayHeight;
70 | this.minX = this.track.x;
71 | this.maxX = (this.track.x + this.track.width) - this.bar.displayWidth;
72 |
73 | this.create();
74 |
75 | // Maximum value for the mouse position.
76 | if (this.vertical) {
77 | this.maxValue = this.track.displayHeight + this.worldPosition.y;
78 |
79 | if (this.version === undefined) {
80 | this.maxValue += this.bar.displayHeight;
81 | }
82 | } else {
83 | this.maxValue = this.track.displayWidth + this.worldPosition.x;
84 |
85 | if (this.version === undefined) {
86 | this.maxValue += this.bar.displayWidth;
87 | }
88 | }
89 | }
90 |
91 | /**
92 | * @private
93 | * The bar is the part that moves, controlling the value of the scrollbar.
94 | */
95 | createBar() {
96 | const bar = new PhaserObjects.Button(
97 | this.game,
98 | this.x,
99 | this.y,
100 | this.barKey,
101 | this.moveContent,
102 | this,
103 | 1,
104 | 0,
105 | );
106 |
107 | // Phaser 3:
108 | // Anchor the bar to 0 instead of 0.5
109 | bar.displayOriginX = 0;
110 | bar.displayOriginY = 0;
111 |
112 | this.bar = bar;
113 |
114 | this.resizeBar();
115 |
116 | return bar;
117 | }
118 |
119 | /**
120 | * @private
121 | * Given a ratio between total content size and viewport size,
122 | * resize the bar sprite to the appropriate percentage of the track.
123 | */
124 | resizeBar() {
125 | let barSize;
126 | if (this.vertical) {
127 | barSize = this.track.height * this.valueRange.ratio;
128 | } else {
129 | barSize = this.track.width * this.valueRange.ratio;
130 | }
131 |
132 | // Prevents bar from becoming zero pixels.
133 | if (barSize < this.minBarSize) {
134 | barSize = this.minBarSize;
135 | }
136 |
137 | // Resizes the bar.
138 | if (this.vertical) {
139 | this.bar.displayHeight = barSize;
140 | } else {
141 | this.bar.displayWidth = barSize;
142 | }
143 | }
144 |
145 | create() {
146 | this.centerStaticAxis();
147 |
148 | if (this.draggable) {
149 | this.enableBarDrag();
150 | }
151 |
152 | // Determine the distance the window can scroll over
153 | this.windowScrollAreaSize = this.valueRange.maxValue - this.valueRange.step;
154 |
155 | // Represents one fraction of the track.
156 | this.vslice = (this.track.displayHeight * this.valueRange.ratio);
157 | this.hslice = (this.track.displayWidth * this.valueRange.ratio);
158 |
159 | this.setTrackScrollAreaSize();
160 |
161 | // Initial position for the bar.
162 | this.mousePointer = { x: this.bar.x, y: this.bar.y };
163 |
164 | this.setInitialBarPosition();
165 | }
166 |
167 | /**
168 | * @private
169 | * Sets the draggable area of the bar.
170 | */
171 | setDraggableArea() {
172 | let vh = this.track.displayHeight;
173 |
174 | if (this.version === 3) {
175 | vh -= this.bar.displayHeight;
176 | }
177 |
178 | this.verticalDraggableArea = {
179 | x: this.track.x - ((this.bar.displayWidth - this.track.width) / 2),
180 | y: this.track.y,
181 | w: this.bar.displayWidth,
182 | h: vh,
183 | };
184 |
185 | this.horizontalDraggableArea = {
186 | x: this.track.x,
187 | y: this.track.y - ((this.bar.displayHeight - this.track.height) / 2),
188 | w: this.track.width,
189 | h: this.bar.displayHeight,
190 | };
191 | }
192 |
193 | /**
194 | * @private
195 | * Ensure the bar starts off where it should be, according to the bar's logical position.
196 | */
197 | setInitialBarPosition() {
198 | const gripPositionOnTrack = this.getBarPosition();
199 |
200 | // Make sure the bar is physically where it should be.
201 | if (this.vertical) {
202 | this.bar.y = gripPositionOnTrack + this.track.y;
203 | } else {
204 | this.bar.x = gripPositionOnTrack + this.track.x;
205 | }
206 | }
207 |
208 | getGripPositionRatio() {
209 | const gripPositionOnTrack = this.getBarPosition();
210 | const mousePositionDelta = this.getMouseDelta();
211 |
212 | let newGripPosition = gripPositionOnTrack + mousePositionDelta;
213 |
214 | // Don't let the content scroll above or below the track's size
215 | if (newGripPosition > 0) {
216 | newGripPosition = 0;
217 | } else if (newGripPosition <= -this.trackScrollAreaSize) {
218 | newGripPosition = -this.trackScrollAreaSize;
219 | }
220 |
221 | // When the scrollbar is at the top or bottom, prevent a mouse movement that
222 | // doesn't move the scrollbar from moving the content.
223 | if (this.vertical) {
224 | if (this.bar.y <= this.track.y) {
225 | newGripPosition = 0;
226 | } else if (this.bar.y + this.bar.displayHeight >= this.track.y + this.track.displayHeight) {
227 | newGripPosition = -this.trackScrollAreaSize;
228 | }
229 | } else {
230 | if (this.bar.x <= this.track.x) {
231 | newGripPosition = 0;
232 | } else if (this.bar.x + this.bar.displayWidth >= this.track.x + this.track.displayWidth) {
233 | newGripPosition = -this.trackScrollAreaSize;
234 | }
235 | }
236 |
237 | let newGripPositionRatio = newGripPosition / this.trackScrollAreaSize;
238 |
239 | // If the scrollable area is less than the size of the scrollbar,
240 | // the bar and track will be the same size.
241 | // In this scenario, a divide by zero occurs. Capture that and turn it into zero.
242 | if (Number.isNaN(newGripPositionRatio)) {
243 | newGripPositionRatio = 0;
244 | }
245 |
246 | return newGripPositionRatio;
247 | }
248 | }
249 |
--------------------------------------------------------------------------------
/src/bars/valuebar.js:
--------------------------------------------------------------------------------
1 | import { DraggableBar } from './draggable_bar';
2 |
3 | import { ValueRange } from './ranges';
4 |
5 | import * as PhaserObjects from '../phaserObjects';
6 |
7 | /**
8 | * Bar that adjusts a number.
9 | * This is done by masking the sprite and then resizing the mask.
10 | * @extends DraggableBar
11 | */
12 | export class ValueBar extends DraggableBar {
13 | /**
14 | * @param {Object} game - Current game instance.
15 | * @param {Object} xy - Dictionary with the values for the bar's x and y position.
16 | * @param {Object} values - The numerical values for the bar.
17 | * @param {boolean} draggable - Determines if the scrollbar responds to mouse clicks.
18 | * @param {boolean} vertical - Determines if the bar should be vertical or horizontal.
19 | * @param {string} trackKey - The key to use for the track.
20 | * @param {string} barKey - The key to use for the bar.
21 | * @param {Object} tweenParams - Object with duration and easing function for the scrolling tween.
22 | */
23 | constructor(game, xy, values, draggable, vertical = false, trackKey = '', barKey = '', tweenParams = null) {
24 | super(game, xy.x, xy.y, vertical, trackKey, barKey);
25 |
26 | this.valueRange = new ValueRange(values.step, values.startValue, values.maxValue);
27 |
28 | this.draggable = draggable || false;
29 |
30 | this.tweenParams = tweenParams || { duration: 300, ease: PhaserObjects.Easing.Quadratic.Out };
31 |
32 | // Flag flipped when the track is clicked, switched off after the bar movement is finished.
33 | this.trackClicked = false;
34 | this.barMoving = false;
35 |
36 | // Records mouse pointer when clicking the bar.
37 | this.mousePointer = null;
38 |
39 | // The track is the static area the bar will move along.
40 | this.track = new PhaserObjects.Sprite(game, 0, 0, this.trackKey);
41 |
42 | // Phaser 3:
43 | // Anchor the track to 0 instead of 0.5
44 | this.track.displayOriginX = 0;
45 | this.track.displayOriginY = 0;
46 |
47 | this.add(this.track);
48 |
49 | this.width = this.track.width;
50 | this.height = this.track.height;
51 |
52 | // If the bar is draggable, clicking the track will move the bar up or down.
53 | if (this.draggable) {
54 | this.enableTrackClick();
55 | }
56 |
57 | // The bar is the part that moves, controlling the value of the scrollbar.
58 | this.bar = new PhaserObjects.Button(
59 | game,
60 | this.x,
61 | this.y,
62 | this.barKey,
63 | this.moveContent,
64 | this,
65 | 1,
66 | 0,
67 | );
68 |
69 | // Phaser 3:
70 | // Anchor the track to 0 instead of 0.5
71 | this.bar.displayOriginX = 0;
72 | this.bar.displayOriginY = 0;
73 |
74 | // Add an invisible background.
75 | // This ensures the bar can always be entered correctly, no matter where the grip is.
76 | this.bg = new PhaserObjects.Graphics(game, { x: 0, y: 0 });
77 | this.add(this.bg);
78 | this.sendToBack(this.bg);
79 | this.bg.fillStyle(0xff0000, 0);
80 |
81 | if (this.vertical) {
82 | this.bg.fillRect(0, 0 - (this.bar.height / 2), 1, this.track.height + this.bar.height);
83 | } else {
84 | this.bg.fillRect(0 - (this.bar.width / 2), 0, this.track.width + this.bar.width, 1);
85 | }
86 |
87 | this.snapping = true;
88 |
89 | this.add(this.bar);
90 | this.minY = this.track.y - (this.bar.height / 2);
91 | this.maxY = (this.track.y + this.track.height) - (this.bar.height / 2);
92 | this.minX = this.track.x - (this.bar.width / 2);
93 | this.maxX = (this.track.x + this.track.width) - (this.bar.width / 2);
94 |
95 | this.create();
96 |
97 | if (this.vertical) {
98 | this.upEvent = this.scrollUp;
99 | this.downEvent = this.scrollDown;
100 | } else {
101 | this.upEvent = this.scrollLeft;
102 | this.downEvent = this.scrollRight;
103 | }
104 |
105 | // Maximum value for the mouse position.
106 | if (this.vertical) {
107 | this.maxValue = this.track.displayHeight + this.worldPosition.y;
108 |
109 | if (this.version === undefined) {
110 | this.maxValue += this.bar.displayHeight;
111 | }
112 | } else {
113 | this.maxValue = this.track.displayWidth + this.worldPosition.x;
114 |
115 | if (this.version === undefined) {
116 | this.maxValue += this.bar.displayWidth;
117 | }
118 | }
119 | }
120 |
121 | create() {
122 | this.centerStaticAxis();
123 |
124 | if (this.draggable) {
125 | this.enableBarDrag();
126 | }
127 |
128 | // Determine the distance the window can scroll over
129 | this.windowScrollAreaSize = this.valueRange.maxValue - this.valueRange.step;
130 |
131 | // Represents one fraction of the track.
132 | this.vslice = (this.track.displayHeight * this.valueRange.ratio);
133 | this.hslice = (this.track.displayWidth * this.valueRange.ratio);
134 |
135 | this.setTrackScrollAreaSize();
136 |
137 | this.setInitialBarPosition();
138 |
139 | // Initial position for the bar.
140 | this.mousePointer = { x: this.bar.x, y: this.bar.y };
141 | }
142 |
143 | /** Sets the draggable area of the bar. */
144 | setDraggableArea() {
145 | let vh = this.track.displayHeight;
146 |
147 | if (this.version === undefined) {
148 | vh += this.bar.displayHeight;
149 | }
150 |
151 | this.verticalDraggableArea = {
152 | x: this.track.x - ((this.bar.displayWidth - this.track.displayWidth) / 2),
153 | y: this.track.y - (this.bar.displayHeight / 2),
154 | w: this.bar.displayWidth,
155 | h: vh,
156 | };
157 |
158 | this.horizontalDraggableArea = {
159 | x: this.track.x - (this.bar.displayWidth / 2),
160 | y: this.track.y - ((this.bar.displayHeight - this.track.displayHeight) / 2),
161 | w: this.track.displayWidth + this.bar.displayWidth,
162 | h: this.bar.displayHeight,
163 | };
164 | }
165 |
166 | /** Determine the distance the bar can scroll over */
167 | setTrackScrollAreaSize() {
168 | if (this.vertical) {
169 | this.trackScrollAreaSize = this.track.displayHeight;
170 | } else {
171 | this.trackScrollAreaSize = this.track.displayWidth;
172 | }
173 | }
174 |
175 | /** Ensure the bar starts off where it should be, according to the bar's logical position. */
176 | setInitialBarPosition() {
177 | const gripPositionOnTrack = this.getBarPosition();
178 |
179 | // The bar should always be in centered on it's current position.
180 | if (this.vertical) {
181 | this.bar.y = (gripPositionOnTrack + this.track.y) - (this.bar.displayHeight / 2);
182 | } else {
183 | this.bar.x = (gripPositionOnTrack + this.track.x) - (this.bar.displayWidth / 2);
184 | }
185 | }
186 |
187 | /** @returns {number} the closest valid value. */
188 | getClosestPosition() {
189 | const currentValue = this.valueRange.getCurrentValue();
190 |
191 | let diff = Math.abs(currentValue - this.valueRange.steps[0]);
192 | let closestPosition = this.valueRange.steps[0];
193 |
194 | for (let i = 0; i < this.valueRange.steps.length; i++) {
195 | const newdiff = Math.abs(currentValue - this.valueRange.steps[i]);
196 | if (newdiff < diff) {
197 | diff = newdiff;
198 | closestPosition = this.valueRange.steps[i];
199 | }
200 | }
201 |
202 | return closestPosition;
203 | }
204 |
205 | /** On mouse up, forces the value to equal the closest step. */
206 | snapToClosestPosition() {
207 | const closestPosition = this.getClosestPosition();
208 |
209 | this.valueRange.adjustValue(closestPosition);
210 | this.moveContent();
211 | this.setInitialBarPosition();
212 | }
213 |
214 | /**
215 | * @private
216 | * Creates the tween for moving the bar to a new position.
217 | */
218 | addScrollTween(properties) {
219 | this.mousePointer = { x: this.bar.x, y: this.bar.y };
220 | this.trackClicked = true;
221 |
222 | new PhaserObjects.Tween(this.game).add(
223 | this.bar,
224 | properties,
225 | this.tweenParams.duration,
226 | this.tweenParams.ease,
227 | () => { this.moveContent(); this.enableBarInput(); },
228 | null,
229 | null,
230 | this,
231 | null,
232 | null,
233 | );
234 | }
235 |
236 | getGripPositionRatio() {
237 | const gripPositionOnTrack = this.getBarPosition();
238 | const mousePositionDelta = this.getMouseDelta();
239 |
240 | let newGripPosition = gripPositionOnTrack - mousePositionDelta;
241 | // Don't let the content scroll above or below the track's size
242 | if (newGripPosition < 0) {
243 | newGripPosition = 0;
244 | } else if (newGripPosition >= this.trackScrollAreaSize) {
245 | newGripPosition = this.trackScrollAreaSize;
246 | }
247 |
248 | // When the scrollbar is at the top or bottom, prevent a mouse movement that
249 | // doesn't move the scrollbar from moving the content.
250 | if (this.vertical) {
251 | if (this.bar.y <= this.track.y) {
252 | newGripPosition = 0;
253 | } else if (this.bar.y + this.bar.displayHeight >= this.track.y + this.track.displayHeight) {
254 | newGripPosition = this.trackScrollAreaSize;
255 | }
256 | } else {
257 | if (this.bar.x <= this.track.x) {
258 | newGripPosition = 0;
259 | } else if (this.bar.x + this.bar.displayWidth >= this.track.x + this.track.displayWidth) {
260 | newGripPosition = this.trackScrollAreaSize;
261 | }
262 | }
263 |
264 | let newGripPositionRatio = newGripPosition / this.trackScrollAreaSize;
265 |
266 | // If the scrollable area is less than the size of the scrollbar,
267 | // the bar and track will be the same size.
268 | // In this scenario, a divide by zero occurs. Capture that and turn it into zero.
269 | if (Number.isNaN(newGripPositionRatio)) {
270 | newGripPositionRatio = 0;
271 | }
272 |
273 | return newGripPositionRatio;
274 | }
275 | }
276 |
--------------------------------------------------------------------------------
/src/buttons.js:
--------------------------------------------------------------------------------
1 | import * as PhaserObjects from './phaserObjects';
2 |
3 | /** Group with some added functionality for text overlays.
4 | * @private
5 | * @extends Phaser.Group
6 | */
7 | class TextGroup extends PhaserObjects.Group {
8 | /**
9 | * @param {Object} game - Current game instance.
10 | * @param {number} x - The x coordinate on screen where the sprite will be placed.
11 | * @param {number} y - The y coordinate on screen where the sprite will be placed.
12 | */
13 | constructor(game, x, y) {
14 | super(game, x, y);
15 |
16 | this.game = game;
17 | this.x = x;
18 | this.y = y;
19 |
20 | game.add.existing(this);
21 | }
22 |
23 | /**
24 | * @param {string} label - The text to place on top of the sprite.
25 | * @param {Object} style - The style properties to be set on the Text.
26 | */
27 | setText(label, style) {
28 | if (this.text) {
29 | this.text.destroy();
30 | }
31 |
32 | if (this.version === 3) {
33 | this.text = this.game.add.text(0, 0, label, style);
34 | this.text.setOrigin(0.5, 0.5);
35 | } else {
36 | this.text = this.game.add.text(this.width / 2, this.height / 2, label, style);
37 | this.text.anchor.set(0.5, 0.5);
38 | }
39 |
40 | this.add(this.text);
41 |
42 | this.text.wordWrap = true;
43 | this.text.wordWrapWidth = this.width;
44 |
45 | return this;
46 | }
47 |
48 | /** When setOrigin is called, align the text as well. */
49 | setOrigin(x, y) {
50 | if (this.version === 3) {
51 | this.sprite.setOrigin(x, y);
52 | } else {
53 | this.sprite.anchor.set(x, y);
54 | }
55 |
56 | this.text.x = this.sprite.width / 2;
57 | this.text.y = this.sprite.height / 2;
58 | this.currentTextY = this.sprite.height / 2;
59 |
60 | return this;
61 | }
62 | }
63 |
64 | /** Sprite with text added as a child.
65 | * @extends Phaser.Group
66 | */
67 | export class TextSprite extends TextGroup {
68 | /**
69 | * @param {Object} game - Current game instance.
70 | * @param {number} x - The x coordinate on screen where the textSprite will be placed.
71 | * @param {number} y - The y coordinate on screen where the textSprite will be placed.
72 | * @param {string} key - The image to create a sprite with.
73 | */
74 | constructor(game, x, y, key) {
75 | super(game, x, y);
76 |
77 | this.sprite = new PhaserObjects.Sprite(game, 0, 0, key);
78 | this.add(this.sprite);
79 |
80 | this.width = this.sprite.width;
81 | this.height = this.sprite.height;
82 | }
83 | }
84 |
85 | /** Phaser Group containing a button with text anchored in the button's center.
86 | * @extends Phaser.Group
87 | */
88 | export class TextButton extends TextGroup {
89 | /**
90 | * @param {Object} game - Current game instance.
91 | * @param {number} x - The x coordinate on screen where the textSprite will be placed.
92 | * @param {number} y - The y coordinate on screen where the textSprite will be placed.
93 | * @param {string} key - The image to create a sprite with.
94 | * @param {Object} callback - Callback to use when the button is clicked.
95 | * @param {Object} callbackContext - The context the callback is called in.
96 | * @param {number} overKey - The frame to switch to when an over event is triggered.
97 | * @param {number} outKey - The frame to switch to when an out event is triggered.
98 | * @param {number} downKey - The frame to switch to when a down event is triggered.
99 | * @param {number} upKey - The frame to switch to when an up event is triggered.
100 | */
101 | constructor(game, x, y, key, callback, callbackContext, overKey, outKey, downKey, upKey) {
102 | super(game, x, y);
103 |
104 | this.sprite = new PhaserObjects.Button(
105 | game,
106 | 0,
107 | 0,
108 | key,
109 | callback,
110 | callbackContext,
111 | overKey,
112 | outKey,
113 | downKey,
114 | upKey,
115 | );
116 | this.add(this.sprite);
117 |
118 | this.width = this.sprite.width;
119 | this.height = this.sprite.height;
120 |
121 | this.currentTextY = 0;
122 | }
123 |
124 | /** Adds an adjustment to the text on down/up events. */
125 | eventTextYAdjustment(number) {
126 | this.sprite.addDownEvent(() => { this.text.y += number; });
127 | this.sprite.addUpEvent(() => { this.text.y = this.currentTextY; });
128 |
129 | // A pointerout event should reset the text position too.
130 | this.sprite.addOutEvent(() => { this.text.y = this.currentTextY; });
131 |
132 | return this;
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/const.js:
--------------------------------------------------------------------------------
1 | // Matches the alignment consts from Phaser
2 | export const alignments = {
3 | TOP_LEFT: 0,
4 | TOP_CENTER: 1,
5 | TOP_RIGHT: 2,
6 | LEFT_TOP: 3,
7 | LEFT_CENTER: 4,
8 | LEFT_BOTTOM: 5,
9 | CENTER: 6,
10 | RIGHT_TOP: 7,
11 | RIGHT_CENTER: 8,
12 | RIGHT_BOTTOM: 9,
13 | BOTTOM_LEFT: 10,
14 | BOTTOM_CENTER: 11,
15 | BOTTOM_RIGHT: 12,
16 | };
17 |
--------------------------------------------------------------------------------
/src/containers/column.js:
--------------------------------------------------------------------------------
1 | import { alignments } from '../const';
2 | import { Frame } from './frame';
3 |
4 | /** Frame that places new child nodes directly under the previous child.
5 | * @extends Frame
6 | */
7 | export class Column extends Frame {
8 | /**
9 | * @param {Object} game - Current game instance.
10 | * @param {Number} x - The x position of the Column.
11 | * @param {Number} y - The y position of the Column.
12 | * @param {string} bg - The background image to use.
13 | * @param {boolean} modal - If the Column should block external interaction until killed.
14 | */
15 | constructor(game, x = 0, y = 0, bg = null, modal = false) {
16 | super(game, x, y, bg, modal);
17 | this.alignment = alignments.BOTTOM_CENTER;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/containers/frame.js:
--------------------------------------------------------------------------------
1 | import { alignments } from '../const';
2 | import * as PhaserObjects from '../phaserObjects';
3 |
4 | /** Group with a dedicated background image.
5 | * @extends Phaser.Group
6 | */
7 | export class Frame extends PhaserObjects.Group {
8 | /**
9 | * @param {Object} game - Current game instance.
10 | * @param {number} x - The x position of the Frame.
11 | * @param {number} y - The y position of the Frame.
12 | * @param {string} bg - The background image to use.
13 | * @param {boolean} modal - If the Frame should block external interaction until killed.
14 | */
15 | constructor(game, x = 0, y = 0, bg = null, modal = false) {
16 | super(game);
17 | game.add.existing(this);
18 |
19 | this.x = x;
20 | this.y = y;
21 |
22 | this.uiWidgetsObjectRole = 'layout';
23 |
24 | this.modal = modal;
25 |
26 | this.background = null;
27 | this.back = null;
28 |
29 | if (modal) {
30 | // Create a sprite to use as the modal back.
31 | const texture = new PhaserObjects.Graphics(game, { x: 0, y: 0 });
32 | texture.fillStyle(0xffffff, 1);
33 | texture.fillRect(0, 0, game.scale.width, game.scale.height);
34 |
35 | let modalBack;
36 | if (this.version === 3) {
37 | texture.generateTexture('modalBack');
38 | modalBack = 'modalBack';
39 | } else {
40 | modalBack = texture.generateTexture();
41 | }
42 |
43 | this.back = new PhaserObjects.Sprite(game, 0, 0, modalBack);
44 | this.back.setInteractive();
45 | this.back.setOrigin(0, 0);
46 | // CE requirement
47 | this.back.moveDown();
48 |
49 | // Mask the back, causing it to be invisible.
50 | const backMask = new PhaserObjects.ViewportMask(game, 0, 0);
51 | this.back.mask = backMask.create(0, 0, 0, 0);
52 |
53 | game.add.existing(this.back);
54 |
55 | // Ensure the modal doesn't hide the Frame's content.
56 | this.depth = 9999;
57 | this.back.depth = 9998;
58 | }
59 |
60 | if (bg !== null) {
61 | this.background = new PhaserObjects.Sprite(game, 0, 0, bg);
62 | game.add.existing(this.background);
63 | this.background.sendToBack();
64 | this.background.alignIn(this, alignments.TOP_LEFT);
65 | }
66 | }
67 |
68 | /** Destroy the Frame, along with any background or modal effect. */
69 | dismiss() {
70 | if (this.modal) {
71 | this.back.destroy();
72 | }
73 |
74 | if (this.background !== null) {
75 | this.background.destroy();
76 | }
77 |
78 | this.destroy();
79 | }
80 |
81 | /** Adds a new object into the Frame, then aligns it with the previous object.
82 | * @param {Object} node - The object to add to the Frame.
83 | * @param {number} paddingX - The amount of horizontal space between objects.
84 | * @param {number} paddingY - The amount of vertical space between objects.
85 | * @param {number} alignment - The alignment relative to the previous child.
86 | */
87 | addNode(node, paddingX = 0, paddingY = 0, alignment = null) {
88 | const align = alignment || this.alignment;
89 |
90 | if (!(node instanceof PhaserObjects.Group)) {
91 | node.displayOriginX = 0; // eslint-disable-line
92 | node.displayOriginY = 0; // eslint-disable-line
93 | } else if (node instanceof PhaserObjects.Group) {
94 | node.setOrigin(0, 0);
95 | }
96 |
97 | this.add(node);
98 | this.alignNodeToPrevious(node, align, paddingX, paddingY);
99 | node.parentContainer = this; // eslint-disable-line
100 |
101 | // Phaser 3: QuantityBar's mask needs a personal touch.
102 | if (node.uiWidgetsObjectRole === 'quantitybar') {
103 | if (node.version === 3) {
104 | node.create(this.x, this.y);
105 | }
106 | }
107 |
108 | // Reset the positions for the bar's draggable area.
109 | if ('enableBarDrag' in node) {
110 | node.enableBarDrag();
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/src/containers/row.js:
--------------------------------------------------------------------------------
1 | import { alignments } from '../const';
2 | import { Frame } from './frame';
3 |
4 | /** Frame that places new child nodes directly next to the previous child.
5 | * @extends Frame
6 | */
7 | export class Row extends Frame {
8 | /**
9 | * @param {Object} game - Current game instance.
10 | * @param {Number} x - The x position of the Row.
11 | * @param {Number} y - The y position of the Row.
12 | * @param {string} bg - The background image to use.
13 | * @param {boolean} modal - If the Row should block external interaction until killed.
14 | */
15 | constructor(game, x = 0, y = 0, bg = null, modal = false) {
16 | super(game, x, y, bg, modal);
17 | this.alignment = alignments.RIGHT_CENTER;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/containers/viewport.js:
--------------------------------------------------------------------------------
1 | import * as PhaserObjects from '../phaserObjects';
2 |
3 | /**
4 | * A container with a limited viewable area. Uses a mask to hide children outside of the specified x/y/width/height area.
5 | * Content outside the viewport has their input disabled.
6 | * @extends PhaserObjects.Group
7 | */
8 | export class Viewport extends PhaserObjects.Group {
9 | /**
10 | * @param {Object} game - Current game instance.
11 | * @param {number} x - The x coordinate on screen where the viewport will be placed.
12 | * @param {number} y - The y coordinate on screen where the viewport will be placed.
13 | * @param {number} width - The width of the viewport.
14 | * @param {number} height - The height of the viewport.
15 | */
16 | constructor(game, x, y, width, height) {
17 | super(game);
18 | game.add.existing(this);
19 |
20 | this.x = x;
21 | this.y = y;
22 |
23 | this.uiWidgetsObjectRole = 'layout';
24 |
25 | // Viewport size and position, distinct from the total window size.
26 | this.area = {
27 | x,
28 | y,
29 | width,
30 | height,
31 | };
32 |
33 | // Adding the mask attribute to a group hides objects outside the mask.
34 | const mask = new PhaserObjects.ViewportMask(game, x, y);
35 |
36 | if (this.version === undefined) {
37 | this.mask = mask.create(x, y, width, height);
38 | } else {
39 | this.mask = mask.create(0, 0, width, height);
40 | }
41 | }
42 |
43 | /** Adds a new object into the Viewport.
44 | * @param {Object} node - The object to add to the Viewport.
45 | */
46 | addNode(node) {
47 | this.add(node);
48 | node.parentContainer = this; // eslint-disable-line
49 | }
50 |
51 | /** Disable input for all objets outside the viewport's visible area.
52 | * Recursively checks all the object's children.
53 | * @param {Object} children - The objects to disable, if they're outside the viewport.
54 | * @param {Object} context - The context the function is run in.
55 | * @param {boolean} vertical - If the bounds should be checked horizontally or vertically.
56 | */
57 | disableOutOfBounds(children, context, vertical) {
58 | let child;
59 | let location;
60 | let contentLocation;
61 | let trueCoords;
62 |
63 | // Makes sure the recursive function stops when there's no children.
64 | if (children !== undefined) {
65 | for (let i = 0; i < children.length; i++) {
66 | child = children[i];
67 | child.inputEnabled = true;
68 |
69 | // An object's x/y is relative to it's parent.
70 | // The world gives an x/y relative to the whole game.
71 | trueCoords = child.world || child;
72 |
73 | if (vertical) {
74 | location = trueCoords.y;
75 | contentLocation = context.viewport.area.y;
76 | } else {
77 | location = trueCoords.x;
78 | contentLocation = context.viewport.area.x;
79 | }
80 |
81 | if (location < contentLocation) {
82 | child.inputEnabled = false;
83 | }
84 |
85 | this.disableOutOfBounds(child.children, context, vertical);
86 | }
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/entry.js:
--------------------------------------------------------------------------------
1 | import { TextSprite, TextButton } from './buttons';
2 | import { KeyboardGroup } from './keyboard_group';
3 | import { Wheel3D } from './wheel3D';
4 |
5 | import { QuantityBar } from './bars/quantitybar';
6 | import { Scrollbar } from './bars/scrollbar';
7 | import { ValueBar } from './bars/valuebar';
8 |
9 | import { Frame } from './containers/frame';
10 | import { Column } from './containers/column';
11 | import { Row } from './containers/row';
12 | import { Viewport } from './containers/viewport';
13 |
14 | import { Button } from './phaserObjects/button';
15 |
16 | export {
17 | TextSprite,
18 | TextButton,
19 | KeyboardGroup,
20 | Wheel3D,
21 | QuantityBar,
22 | Scrollbar,
23 | ValueBar,
24 | Frame,
25 | Column,
26 | Row,
27 | Viewport,
28 | Button,
29 | };
30 |
--------------------------------------------------------------------------------
/src/keyboard_group.js:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from 'eventemitter3';
2 | import * as PhaserObjects from './phaserObjects';
3 |
4 | import { utils } from './utils';
5 |
6 | /** Collection of sprites that can be selected with the keyboard.
7 | * When the select key is hit, the sprite that was selected is now connected to the keyboard.
8 | */
9 | export class KeyboardGroup {
10 | /**
11 | * @param {Object} game - Current game instance.
12 | * @param {Boolean} vertical - If the selection should be controlled with up/down or left/right arrow keys.
13 | * @param {Object} callbackContext - The context for the previous and next Events.
14 | */
15 | constructor(game, vertical, callbackContext) {
16 | this.game = game;
17 | this.vertical = vertical || false;
18 | this.callbackContext = callbackContext;
19 |
20 | this.children = [];
21 |
22 | this.selected = null;
23 | this.idx = 0;
24 |
25 | this.upKey = this.game.input.keyboard.addKey(PhaserObjects.KeyCodes.UP);
26 | this.downKey = this.game.input.keyboard.addKey(PhaserObjects.KeyCodes.DOWN);
27 | this.leftKey = this.game.input.keyboard.addKey(PhaserObjects.KeyCodes.LEFT);
28 | this.rightKey = this.game.input.keyboard.addKey(PhaserObjects.KeyCodes.RIGHT);
29 |
30 | this.upEvent = this.prevItem;
31 | this.downEvent = this.nextItem;
32 |
33 | this.emitter = new EventEmitter();
34 |
35 | this.activateGroup();
36 | }
37 |
38 | /** Add a new child to the group
39 | * @param {Object} newNode - The sprite to add to the group.
40 | */
41 | addNode(newNode) {
42 | this.children.push(newNode);
43 |
44 | // Ensure the first child is already selected when the game loads.
45 | this.selected = this.children[0]; // eslint-disable-line prefer-destructuring
46 | this.useBar();
47 | }
48 |
49 | /** Selects the previous child. */
50 | prevItem() {
51 | this.idx = utils.modulo(this.idx - 1, this.children.length);
52 |
53 | this.selected = this.children[this.idx];
54 |
55 | this.useBar();
56 |
57 | this.emitter.emit('previous', this, this.callbackContext);
58 | }
59 |
60 | /** Selects the next child. */
61 | nextItem() {
62 | this.idx = utils.modulo(this.idx + 1, this.children.length);
63 |
64 | this.selected = this.children[this.idx];
65 |
66 | this.useBar();
67 |
68 | this.emitter.emit('next', this, this.callbackContext);
69 | }
70 |
71 | /**
72 | * Enables keyboard input for the group.
73 | * @private
74 | */
75 | activateGroup() {
76 | const keyboard = new PhaserObjects.Keyboard();
77 |
78 | if (this.vertical) {
79 | keyboard.addDownEvent(this.upKey, this.upEvent, this);
80 | keyboard.addDownEvent(this.downKey, this.downEvent, this);
81 | } else {
82 | keyboard.addDownEvent(this.leftKey, this.upEvent, this);
83 | keyboard.addDownEvent(this.rightKey, this.downEvent, this);
84 | }
85 | }
86 |
87 | /**
88 | * Enables keyboard input on a child.
89 | * @private
90 | */
91 | useBar() {
92 | const keyboard = new PhaserObjects.Keyboard();
93 |
94 | if (this.vertical) {
95 | keyboard.removeDownEvent(this.leftKey);
96 | keyboard.removeDownEvent(this.rightKey);
97 |
98 | keyboard.addDownEvent(this.leftKey, this.selected.upEvent, this.selected);
99 | keyboard.addDownEvent(this.rightKey, this.selected.downEvent, this.selected);
100 | } else {
101 | keyboard.removeDownEvent(this.upKey);
102 | keyboard.removeDownEvent(this.downKey);
103 |
104 | keyboard.addDownEvent(this.upKey, this.selected.upEvent, this.selected);
105 | keyboard.addDownEvent(this.downKey, this.selected.downEvent, this.selected);
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/phaserObjects/button.js:
--------------------------------------------------------------------------------
1 | import { Sprite } from './sprite';
2 |
3 | let exportObject;
4 |
5 | if (Phaser.Button === undefined) {
6 | /** Build a button object that immitates Phaser CE's Button
7 | * @private
8 | */
9 | class Phaser3Button extends Sprite {
10 | constructor(game, x, y, key, callback, callbackContext, overKey, outKey, downKey, upKey) {
11 | super(game, x, y, key);
12 |
13 | game.add.existing(this);
14 |
15 | this.game = game;
16 |
17 | this.overKey = overKey;
18 | this.outKey = outKey;
19 | this.downKey = downKey;
20 | this.upKey = upKey;
21 |
22 | this.setInteractive({ useHandCursor: true });
23 |
24 | let cbContext = callbackContext;
25 |
26 | if (cbContext === null || (cbContext === undefined)) {
27 | cbContext = this;
28 | }
29 |
30 | this.on('pointerdown', (pointer) => {
31 | callback.call(cbContext, pointer);
32 | });
33 | this.on('pointerover', this.onOver, this);
34 | this.on('pointerout', this.onOut, this);
35 | this.on('pointerdown', this.onDown, this);
36 | this.on('pointerup', this.onUp, this);
37 | }
38 |
39 | onOver() {
40 | this.setFrame(this.overKey);
41 | }
42 |
43 | onOut() {
44 | this.setFrame(this.outKey);
45 | }
46 |
47 | onDown() {
48 | this.setFrame(this.downKey);
49 | }
50 |
51 | onUp() {
52 | this.setFrame(this.upKey);
53 | }
54 |
55 | updateDrag(pointer, gameObject, x, y) { //eslint-disable-line
56 | if (gameObject.vertical) {
57 | if ((gameObject.draggableArea.y + gameObject.draggableArea.h) >= y) {
58 | if (gameObject.draggableArea.y <= y) {
59 | gameObject.y = y; //eslint-disable-line
60 | }
61 | }
62 | } else {
63 | const fx = (x + gameObject.displayWidth);
64 | if ((gameObject.draggableArea.x + gameObject.draggableArea.w) >= fx) {
65 | if (gameObject.draggableArea.x <= x) {
66 | gameObject.x = x; //eslint-disable-line
67 | }
68 | }
69 | }
70 | }
71 |
72 | setDragBounds(draggableArea) {
73 | this.draggableArea = draggableArea;
74 | }
75 |
76 | enableDragging(vertical = false) {
77 | this.setInteractive({ useHandCursor: true });
78 | this.vertical = vertical;
79 | this.game.input.setDraggable(this);
80 | this.game.input.on('drag', this.updateDrag);
81 | }
82 | }
83 |
84 | exportObject = Phaser3Button;
85 | } else {
86 | class PhaserCEButton extends Phaser.Button {
87 | constructor(game, x, y, key, callback, callbackContext, overKey, outKey, downKey, upKey) {
88 | super(game, x, y, key, callback, callbackContext, overKey, outKey, downKey, upKey);
89 |
90 | game.add.existing(this);
91 | }
92 |
93 | setInteractive() {
94 | this.inputEnabled = true;
95 | this.input.useHandCursor = true;
96 | }
97 |
98 | disableInteractive() {
99 | this.inputEnabled = false;
100 | }
101 |
102 | setDragBounds(draggableArea) {
103 | this.input.boundsRect = new Phaser.Rectangle(
104 | draggableArea.x,
105 | draggableArea.y,
106 | draggableArea.w,
107 | draggableArea.h,
108 | );
109 | }
110 |
111 | enableDragging(vertical = false) {
112 | this.inputEnabled = true;
113 | this.input.enableDrag();
114 |
115 | if (vertical) {
116 | this.input.allowHorizontalDrag = false;
117 | } else {
118 | this.input.allowVerticalDrag = false;
119 | }
120 | }
121 |
122 | /**
123 | * @private
124 | * Add a callback that is triggered when the pointer moves out of the object.
125 | */
126 | addOutEvent(callback, callbackContext) {
127 | this.events.onInputOut.add(callback, callbackContext);
128 | }
129 |
130 | /**
131 | * @private
132 | * Add a callback that is triggered when the object is unclicked.
133 | */
134 | addUpEvent(callback, callbackContext) {
135 | this.events.onInputUp.add(callback, callbackContext);
136 | }
137 |
138 | /**
139 | * @private
140 | * Add a callback that is triggered when the object is clicked.
141 | */
142 | addDownEvent(callback, callbackContext) {
143 | this.events.onInputDown.add(callback, callbackContext);
144 | }
145 |
146 | /**
147 | * @private
148 | * Add a callback that is triggered when the object is dragged.
149 | */
150 | addDragEvent(callback, callbackContext) {
151 | this.events.onDragUpdate.add(callback, callbackContext);
152 | }
153 |
154 | /** Immitate the API of Phaser3.
155 | * The current displayed height of the Object.
156 | * @type {number}
157 | * @private
158 | */
159 | get displayHeight() {
160 | return this.height;
161 | }
162 |
163 | set displayHeight(newValue) {
164 | this.height = newValue;
165 | }
166 |
167 | /** Immitate the API of Phaser3.
168 | * The current displayed width of the Object.
169 | * @type {number}
170 | * @private
171 | */
172 | get displayWidth() {
173 | return this.width;
174 | }
175 |
176 | set displayWidth(newValue) {
177 | this.width = newValue;
178 | }
179 | }
180 |
181 | exportObject = PhaserCEButton;
182 | }
183 |
184 | export const Button = exportObject;
185 |
--------------------------------------------------------------------------------
/src/phaserObjects/easing.js:
--------------------------------------------------------------------------------
1 | let exportObject;
2 |
3 | if (Phaser.Easing === undefined) {
4 | exportObject = Phaser.Math.Easing;
5 | } else {
6 | exportObject = Phaser.Easing;
7 | }
8 |
9 | export const Easing = exportObject;
10 |
--------------------------------------------------------------------------------
/src/phaserObjects/graphics.js:
--------------------------------------------------------------------------------
1 | let exportObject;
2 |
3 | if (Phaser.Graphics === undefined) {
4 | exportObject = Phaser.GameObjects.Graphics;
5 | } else {
6 | class PhaserCEGraphics extends Phaser.Graphics {
7 | constructor(game, options) {
8 | super(game, options.x, options.y);
9 | }
10 |
11 | fillStyle(colour, alpha) {
12 | this.beginFill(colour, alpha);
13 | }
14 |
15 | fillRect(x, y, width, height) {
16 | this.drawRect(x, y, width, height);
17 | this.endFill();
18 | }
19 | }
20 |
21 | exportObject = PhaserCEGraphics;
22 | }
23 |
24 | export const Graphics = exportObject;
25 |
--------------------------------------------------------------------------------
/src/phaserObjects/group.js:
--------------------------------------------------------------------------------
1 | let exportObject;
2 |
3 | if (Phaser.Group === undefined) {
4 | // Emulate Phaser CE's worldPosition object
5 | class WorldPosition {
6 | constructor(parent) {
7 | this.parent = parent;
8 | }
9 |
10 | get x() {
11 | return this.parent.x;
12 | }
13 |
14 | get y() {
15 | return this.parent.y;
16 | }
17 | }
18 |
19 | class Phaser3Group extends Phaser.GameObjects.Container {
20 | constructor(game, x = 0, y = 0) {
21 | super(game, x, y);
22 |
23 | game.add.existing(this);
24 |
25 | this.parentContainer = null;
26 |
27 | this.SORT_ASCENDING = -1;
28 | this.SORT_DESCENDING = 1;
29 |
30 | this.version = 3;
31 |
32 | // Emulate Phaser CE's GameObject.alignTo
33 | this.alignToMapping = {
34 | 0: Phaser.Display.Align.To.TopLeft,
35 | 1: Phaser.Display.Align.To.TopCenter,
36 | 8: Phaser.Display.Align.To.RightCenter,
37 | 11: Phaser.Display.Align.To.BottomCenter,
38 | };
39 |
40 | this.worldPosition = new WorldPosition(this);
41 | }
42 |
43 | /** @private Alias to match Phaser CE */
44 | get children() {
45 | return this.list;
46 | }
47 |
48 | get realHeight() {
49 | return this.getBounds().height - this.y;
50 | }
51 |
52 | get realWidth() {
53 | return this.getBounds().width - this.x;
54 | }
55 |
56 | /** Set the origin points of every member of the group. */
57 | setOrigin(x = 0, y = 0) {
58 | let node;
59 |
60 | for (let i = 0; i < this.children.length; i++) {
61 | node = this.children[i];
62 |
63 | if (!(node instanceof Phaser3Group)) {
64 | node.displayOriginX = x; // eslint-disable-line
65 | node.displayOriginY = y; // eslint-disable-line
66 | } else if (node instanceof Phaser3Group) {
67 | node.setOrigin(x, y);
68 | }
69 | }
70 | }
71 |
72 | getNodes() {
73 | return this.getAll();
74 | }
75 |
76 | // Can't align to Containers automatically
77 | alignToContainerBottom(previousNode, child) {
78 | // realWidth changes inside a Container
79 |
80 | let previousNodeWidth;
81 | let previousNodeHeight;
82 | if (child.uiWidgetsObjectRole === 'layout') {
83 | const bounds = previousNode.getBounds();
84 | previousNodeWidth = bounds.width - this.worldPosition.x;
85 | previousNodeHeight = bounds.height - this.worldPosition.y;
86 | } else {
87 | previousNodeWidth = previousNode.width;
88 | previousNodeHeight = previousNode.height;
89 | }
90 |
91 | const centerX = (previousNodeWidth * 0.5);
92 | const bottomY = previousNodeHeight;
93 |
94 | let w = child.width;
95 | if (child.uiWidgetsObjectRole === 'layout') {
96 | w = child.getBounds().width;
97 | }
98 |
99 | child.x = centerX - (w * 0.5); // eslint-disable-line
100 | child.y = previousNode.getBounds().y + bottomY; // eslint-disable-line
101 | }
102 |
103 | /** Containers can't be aligned automatically */
104 | alignContainerToBottom(previousNode, child) { // eslint-disable-line
105 | const bounds = previousNode.getBounds();
106 | const centerX = previousNode.x + (bounds.width * 0.5);
107 |
108 | child.x = centerX - (child.width * 0.5); // eslint-disable-line
109 | child.y = bounds.y; // eslint-disable-line
110 | }
111 |
112 | alignContainerToRight(previousNode, child) { // eslint-disable-line
113 | const rightX = previousNode.x + previousNode.width;
114 |
115 | child.x = rightX; // eslint-disable-line
116 | }
117 |
118 | /** Aligns child to the last object in the group.
119 | * @private
120 | */
121 | alignNodeToPrevious(child, align, paddingX, paddingY) {
122 | const nodes = this.getNodes();
123 | const previousNode = nodes[nodes.length - 2];
124 |
125 | const toGroupAlignFuncs = {
126 | 11: this.alignContainerToBottom, // Column
127 | 8: this.alignContainerToRight, // Row
128 | };
129 |
130 | const toGroupAlignFunc = toGroupAlignFuncs[align];
131 |
132 | if (previousNode instanceof Phaser3Group) {
133 | this.alignToContainerBottom(previousNode, child);
134 | } else if (child instanceof Phaser3Group && (previousNode !== undefined)) {
135 | toGroupAlignFunc(previousNode, child);
136 | } else if (previousNode !== undefined) {
137 | this.alignToMapping[align](child, previousNode, paddingX, paddingY);
138 | }
139 | }
140 | }
141 |
142 | exportObject = Phaser3Group;
143 | } else {
144 | class PhaserCEGroup extends Phaser.Group {
145 | constructor(game) {
146 | super(game);
147 |
148 | this.parentContainer = null;
149 |
150 | this.SORT_ASCENDING = -1;
151 | this.SORT_DESCENDING = 1;
152 | }
153 |
154 | get realHeight() {
155 | return this.height;
156 | }
157 |
158 | get realWidth() {
159 | return this.width;
160 | }
161 |
162 | getNodes() {
163 | return this.children;
164 | }
165 |
166 | /** Aligns child to the last object in the group.
167 | * @private
168 | */
169 | alignNodeToPrevious(child, align, paddingX, paddingY) {
170 | const nodes = this.getNodes();
171 | const previousNode = nodes[nodes.length - 2];
172 |
173 | if (previousNode !== undefined) {
174 | child.alignTo(previousNode, align, paddingX, paddingY);
175 | }
176 | }
177 | }
178 |
179 | exportObject = PhaserCEGroup;
180 | }
181 |
182 | export const Group = exportObject;
183 |
--------------------------------------------------------------------------------
/src/phaserObjects/index.js:
--------------------------------------------------------------------------------
1 | /** Collection of shims that provide different objects based on the Phaser
2 | * version used.
3 | * @module phaserObjects
4 | * @private
5 | */
6 | import { Button } from './button';
7 | import { Easing } from './easing';
8 | import { Graphics } from './graphics';
9 | import { Group } from './group';
10 | import { Keyboard } from './keyboard';
11 | import { KeyCodes } from './keycodes';
12 | import { Rectangle } from './rectangle';
13 | import { Sprite } from './sprite';
14 | import { Tween } from './tween';
15 | import { ViewportMask } from './viewport_mask';
16 |
17 | export {
18 | Button,
19 | Easing,
20 | Graphics,
21 | Group,
22 | Keyboard,
23 | KeyCodes,
24 | Rectangle,
25 | Sprite,
26 | Tween,
27 | ViewportMask,
28 | };
29 |
--------------------------------------------------------------------------------
/src/phaserObjects/keyboard.js:
--------------------------------------------------------------------------------
1 | let exportObject;
2 |
3 | if (Phaser.Keyboard === undefined) {
4 | class Phaser3Keyboard {
5 | addDownEvent(key, event, context) { // eslint-disable-line
6 | key.on('down', event, context);
7 | }
8 |
9 | removeDownEvent(key) { // eslint-disable-line
10 | key.removeListener('down');
11 | }
12 | }
13 |
14 | exportObject = Phaser3Keyboard;
15 | } else {
16 | class PhaserCEKeyboard {
17 | addDownEvent(key, event, context) { // eslint-disable-line
18 | key.onDown.add(event, context);
19 | }
20 |
21 | removeDownEvent(key) { // eslint-disable-line
22 | key.onDown.removeAll();
23 | }
24 | }
25 |
26 | exportObject = PhaserCEKeyboard;
27 | }
28 |
29 | export const Keyboard = exportObject;
30 |
--------------------------------------------------------------------------------
/src/phaserObjects/keycodes.js:
--------------------------------------------------------------------------------
1 | let exportKeyCodes;
2 |
3 | if (Phaser.Keyboard === undefined) {
4 | exportKeyCodes = Phaser.Input.Keyboard.KeyCodes;
5 | } else {
6 | exportKeyCodes = Phaser.Keyboard;
7 | }
8 |
9 | export const KeyCodes = exportKeyCodes;
10 |
--------------------------------------------------------------------------------
/src/phaserObjects/rectangle.js:
--------------------------------------------------------------------------------
1 | let exportObject;
2 |
3 | if (Phaser.Rectangle === undefined) {
4 | exportObject = Phaser.Geom.Rectangle;
5 | } else {
6 | exportObject = Phaser.Rectangle;
7 | }
8 |
9 | export const Rectangle = exportObject;
10 |
--------------------------------------------------------------------------------
/src/phaserObjects/sprite.js:
--------------------------------------------------------------------------------
1 | let exportObject;
2 |
3 | if (Phaser.Sprite === undefined) {
4 | class Phaser3Sprite extends Phaser.GameObjects.Sprite {
5 | constructor(game, x, y, image) {
6 | super(game, x, y, image);
7 |
8 | game.add.existing(this);
9 |
10 | // Map alignment constants to Phaser 3 Align functions
11 | const alignIn = Phaser.Display.Align.In;
12 | this.alignInMapping = {
13 | 0: alignIn.TopLeft,
14 | 1: alignIn.TopCenter,
15 | 2: alignIn.TopRight,
16 | 3: alignIn.LeftTop,
17 | 4: alignIn.LeftCenter,
18 | 5: alignIn.LeftBottom,
19 | 6: alignIn.Center,
20 | 7: alignIn.RightTop,
21 | 8: alignIn.RightCenter,
22 | 9: alignIn.RightBottom,
23 | 10: alignIn.BottomLeft,
24 | 11: alignIn.BottomCenter,
25 | 12: alignIn.BottomRight,
26 | };
27 | }
28 |
29 | get maskX() {
30 | return this.x;
31 | }
32 |
33 | get maskY() {
34 | return this.y;
35 | }
36 |
37 | /** Immitate the API of PhaserCE.
38 | * Move this object behind all others.
39 | * @private
40 | */
41 | sendToBack() {
42 | this.depth = -9999;
43 | }
44 |
45 | /** Immitate the API of PhaserCE.
46 | * Move this object down the depth order by 1.
47 | * @private
48 | */
49 | moveDown() {
50 | this.depth -= 1;
51 | }
52 |
53 | /** Immitate the API of PhaserCE.
54 | * Align this object in another.
55 | * @private
56 | */
57 | alignIn(other, align) {
58 | this.alignInMapping[align](this, other, other.width);
59 | }
60 |
61 | /**
62 | * @private
63 | * Add a callback that is triggered when the pointer moves out of the object.
64 | */
65 | addOutEvent(callback, callbackContext) {
66 | this.on('pointerout', (pointer) => {
67 | callback.call(callbackContext, pointer);
68 | });
69 | }
70 |
71 | /**
72 | * @private
73 | * Add a callback that is triggered when the object is unclicked.
74 | */
75 | addUpEvent(callback, callbackContext) {
76 | this.on('pointerup', (pointer) => {
77 | callback.call(callbackContext, pointer);
78 | });
79 | }
80 |
81 | /**
82 | * @private
83 | * Add a callback that is triggered when the object is clicked.
84 | */
85 | addDownEvent(callback, callbackContext) {
86 | this.on('pointerdown', (pointer) => {
87 | callback.call(callbackContext, pointer);
88 | });
89 | }
90 |
91 | /**
92 | * @private
93 | * Add a callback that is triggered when the object is dragged.
94 | */
95 | addDragEvent(callback, callbackContext) {
96 | this.on('drag', () => { callback.call(callbackContext); });
97 | }
98 | }
99 |
100 | exportObject = Phaser3Sprite;
101 | } else {
102 | class PhaserCESprite extends Phaser.Sprite {
103 | constructor(game, x, y, key) {
104 | super(game, x, y, key);
105 |
106 | game.add.existing(this);
107 | }
108 |
109 | setOrigin(x, y) {
110 | this.anchor = new Phaser.Point(x, y);
111 | }
112 |
113 | get maskX() { //eslint-disable-line
114 | return 0;
115 | }
116 |
117 | get maskY() { //eslint-disable-line
118 | return 0;
119 | }
120 |
121 | setInteractive() {
122 | this.inputEnabled = true;
123 | }
124 |
125 | disableInteractive() {
126 | this.inputEnabled = false;
127 | }
128 |
129 | /**
130 | * @private
131 | * Add a callback that is triggered when the pointer moves out of the object.
132 | */
133 | addOutEvent(callback, callbackContext) {
134 | this.events.onInputOut.add(callback, callbackContext);
135 | }
136 |
137 | /**
138 | * @private
139 | * Add a callback that is triggered when the object is unclicked.
140 | */
141 | addUpEvent(callback, callbackContext) {
142 | this.events.onInputUp.add(callback, callbackContext);
143 | }
144 |
145 | /**
146 | * @private
147 | * Add a callback that is triggered when the object is clicked.
148 | */
149 | addDownEvent(callback, callbackContext) {
150 | this.events.onInputDown.add(callback, callbackContext);
151 | }
152 |
153 | /** Immitate the API of Phaser3.
154 | * The current displayed height of the Object.
155 | * @type {number}
156 | * @private
157 | */
158 | get displayHeight() {
159 | return this.height;
160 | }
161 |
162 | set displayHeight(newValue) {
163 | this.height = newValue;
164 | }
165 |
166 | /** Immitate the API of Phaser3.
167 | * The current displayed width of the Object.
168 | * @type {number}
169 | * @private
170 | */
171 | get displayWidth() {
172 | return this.width;
173 | }
174 |
175 | set displayWidth(newValue) {
176 | this.width = newValue;
177 | }
178 | }
179 |
180 | exportObject = PhaserCESprite;
181 | }
182 |
183 | export const Sprite = exportObject;
184 |
--------------------------------------------------------------------------------
/src/phaserObjects/tween.js:
--------------------------------------------------------------------------------
1 | let exportObject;
2 |
3 | if (Phaser.Tween === undefined) {
4 | class Phaser3Tween {
5 | constructor(game) {
6 | this.game = game;
7 | }
8 |
9 | add(target, properties, duration, ease, onComplete, onUpdate, onStart, callbackScope) {
10 | const config = {
11 | targets: target,
12 | duration,
13 | ease,
14 | onComplete,
15 | onUpdate,
16 | onStart,
17 | callbackScope,
18 | };
19 | const params = Object.assign(config, properties);
20 | this.game.tweens.add(params);
21 | }
22 | }
23 |
24 | exportObject = Phaser3Tween;
25 | } else {
26 | class PhaserCETween {
27 | constructor(game) {
28 | this.game = game;
29 | }
30 |
31 | add(target, properties, duration, ease, onComplete, onUpdate, onStart, onCompleteScope, onUpdateScope, onStartScope) {
32 | const tween = this.game.add.tween(target).to(
33 | properties,
34 | duration,
35 | ease,
36 | true,
37 | );
38 |
39 | // Add the necessary events to the tween.
40 | if (onUpdate) {
41 | tween.onUpdateCallback(onUpdate, onUpdateScope);
42 | }
43 |
44 | if (onComplete) {
45 | tween.onComplete.add(onComplete, onCompleteScope);
46 | }
47 |
48 | if (onStart) {
49 | tween.onStart.add(onStart, onStartScope);
50 | }
51 | }
52 | }
53 |
54 | exportObject = PhaserCETween;
55 | }
56 |
57 | export const Tween = exportObject;
58 |
--------------------------------------------------------------------------------
/src/phaserObjects/viewport_mask.js:
--------------------------------------------------------------------------------
1 | let exportObject;
2 |
3 | if (Phaser.Graphics === undefined) {
4 | class ViewportMask3 extends Phaser.GameObjects.Graphics {
5 | constructor(game, x, y) {
6 | super(game, { x, y });
7 |
8 | this.game = game;
9 | this.x = x;
10 | this.y = y;
11 | }
12 |
13 | create(x, y, width, height) {
14 | this.fillStyle(0xffffff);
15 | this.beginPath();
16 | this.fillRect(x, y, width, height);
17 |
18 | const m = this.createGeometryMask();
19 | m.x = m.geometryMask.x;
20 | m.y = m.geometryMask.y;
21 | m.width = width;
22 | m.height = height;
23 |
24 | return m;
25 | }
26 | }
27 | exportObject = ViewportMask3;
28 | } else {
29 | class ViewportMaskCE extends Phaser.Graphics {
30 | get scaleX() {
31 | return this.scale.x;
32 | }
33 |
34 | set scaleX(value) {
35 | this.scale.x = value;
36 | }
37 |
38 | get scaleY() {
39 | return this.scale.y;
40 | }
41 |
42 | set scaleY(value) {
43 | this.scale.y = value;
44 | }
45 |
46 | create(x, y, width, height) {
47 | this.beginFill(0x0000ff);
48 | this.drawRect(x, y, width, height);
49 | this.endFill();
50 |
51 | // Match the internals of Phaser3
52 | this.geometryMask = this;
53 |
54 | return this;
55 | }
56 | }
57 |
58 | exportObject = ViewportMaskCE;
59 | }
60 |
61 | export const ViewportMask = exportObject;
62 |
--------------------------------------------------------------------------------
/src/utils.js:
--------------------------------------------------------------------------------
1 | const utils = {};
2 |
3 | /**
4 | * @private
5 | * A modulo operator that doesn't allow negative numbers.
6 | * @param {number} dividend
7 | * @param {number} divisor
8 | * @returns {number}
9 | */
10 | utils.modulo = function modulo(dividend, divisor) {
11 | return ((((dividend) % divisor) + divisor) % divisor);
12 | };
13 |
14 | /**
15 | * @private
16 | * Select an operator action using a string value.
17 | */
18 | utils.operators = {
19 | '+': function add(a, b) { return a + b; },
20 | '-': function sub(a, b) { return a - b; },
21 | };
22 |
23 | export { utils };
24 |
--------------------------------------------------------------------------------
/src/wheel3D.js:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from 'eventemitter3';
2 |
3 | import { utils } from './utils';
4 |
5 | import * as PhaserObjects from './phaserObjects';
6 |
7 | /**
8 | * Represents a single point in a Wheel3D.
9 | * @ignore
10 | */
11 | class VectorPoint {
12 | /**
13 | * @ignore
14 | * @param {number} x - The point's virtual x location.
15 | * @param {number} y - The point's virtual y location.
16 | * @param {number} z - The point's virtual z location.
17 | * @param {Object} sprite - The sprite associated with this point.
18 | * @param {number} position - The point's position on the Wheel3D.
19 | */
20 | constructor(x = 0, y = 0, z = 0, sprite = null, position = 0) {
21 | this.x = x;
22 | this.y = y;
23 | this.z = z;
24 | this.sprite = sprite;
25 | this.position = position;
26 | }
27 |
28 | getSinCosOfAngle(angle) { // eslint-disable-line class-methods-use-this
29 | const rad = (angle * Math.PI) / 180;
30 | const cosAngle = Math.cos(rad);
31 | const sinAngle = Math.sin(rad);
32 |
33 | return { cosine: cosAngle, sine: sinAngle };
34 | }
35 |
36 | rotateY(angle) {
37 | const angles = this.getSinCosOfAngle(angle);
38 | const z = (this.z * angles.cosine) - (this.x * angles.sine);
39 | const x = (this.z * angles.sine) + (this.x * angles.cosine);
40 |
41 | return new VectorPoint(x, this.y, z);
42 | }
43 |
44 | rotateX(angle) {
45 | const angles = this.getSinCosOfAngle(angle);
46 | const y = (this.y * angles.cosine) - (this.z * angles.sine);
47 | const z = (this.y * angles.sine) + (this.z * angles.cosine);
48 |
49 | return new VectorPoint(this.x, y, z);
50 | }
51 |
52 | rotateZ(angle) {
53 | const angles = this.getSinCosOfAngle(angle);
54 | const x = (this.x * angles.cosine) - (this.y * angles.sine);
55 | const y = (this.x * angles.sine) + (this.y * angles.cosine);
56 |
57 | return new VectorPoint(x, y, this.z);
58 | }
59 |
60 | /** Rotate the point along the given axis by the given angle.
61 | * @param {string} axis - The axis to rotate.
62 | * @param {number} angle - The angle to rotate by.
63 | */
64 | rotate(axis, angle) {
65 | let newVector = null;
66 |
67 | if (axis === 'x') {
68 | newVector = this.rotateX(angle);
69 | } else if (axis === 'y') {
70 | newVector = this.rotateY(angle);
71 | } else if (axis === 'z') {
72 | newVector = this.rotateZ(angle);
73 | }
74 |
75 | return newVector;
76 | }
77 |
78 | /** Project the point to the correct physical location on screen.
79 | * z axis is not projected, because screens are 2D.
80 | */
81 | project(width, height, factor) {
82 | const x = (this.x * factor) + width;
83 | const y = (-this.y * factor) + height;
84 |
85 | return new VectorPoint(x, y, this.z);
86 | }
87 | }
88 |
89 | /**
90 | * A Wheel of sprites where each item's position is projected in 3D space.
91 | * The number of points is automatically determined by the number of items.
92 | */
93 | export class Wheel3D {
94 | /**
95 | * @param {Object} game - Reference to current game instance.
96 | * @param {array} sprites - List of sprites to use in the wheel.
97 | * @param {Number} firstPlace - Determines which position on the wheel is the active one.
98 | * @param {Number} zoom - Determines how far to project the points.
99 | * @param {String} axis - The axis the wheel3D places items around.
100 | * @param {Object} rotations - Axis and angle to rotate the entire wheel after the initial projection.
101 | * @param {Object} visibleRange - Determines which items on the wheel should be visible. If none provided, assumes all items should be visible.
102 | * @param {Object} tweenParams - Array with the duration and easing function for the movement tween.
103 | */
104 | constructor(game, xy, sprites, firstPlace, zoom, axis, rotations, visibleRange, tweenParams) {
105 | this.game = game;
106 | this.xy = xy;
107 | this.sprites = sprites;
108 | this.firstPlace = firstPlace;
109 | this.zoom = zoom;
110 | this.axis = axis;
111 | this.rotationAxis = rotations;
112 | this.visibleRange = visibleRange || null;
113 | this.tweenParams = tweenParams || { duration: 300, ease: PhaserObjects.Easing.Quadratic.Out };
114 |
115 | this.emitter = new EventEmitter();
116 |
117 | // Group to store wheel sprites in, used for zindex sorting.
118 | this.group = new PhaserObjects.Group(game);
119 | }
120 |
121 | activate() {
122 | let angle;
123 | let radCos;
124 | let radSin;
125 | let nx;
126 | let ny;
127 | let nz;
128 |
129 | this.pointsAmount = this.sprites.length;
130 | this.totalPositions = this.pointsAmount - 1;
131 | this.rotationAmount = 360 / this.pointsAmount;
132 |
133 | // Determines which items in the wheel should be visible.
134 | if (this.visibleRange !== null) {
135 | const allPositions = [];
136 | for (let i = 0; i <= this.totalPositions; i++) {
137 | allPositions.push(i);
138 | }
139 |
140 | const maxV = allPositions.slice(0, this.visibleRange.max);
141 | const minV = allPositions.slice(this.visibleRange.min);
142 |
143 | this.visiblePositions = maxV.concat(minV);
144 | }
145 |
146 | // Prevents slamming down the move keys.
147 | this.moving = false;
148 |
149 | // Stores the direction the wheel is moving in.
150 | this.direction = null;
151 |
152 | // Set point positions on logical circle.
153 | this.wheelItems = [];
154 | const radius = 1;
155 | const slice = (2 * Math.PI) / this.pointsAmount;
156 |
157 | // For a vertical wheel, the X axis is -1. Points are laid out on the Y axis (height) and Z axis (depth). The wheel rotates around the X axis.
158 | // For a horizontal wheel, the Y Axis is -1. Points are laid out on the X axis (width) and Z axis (depth). The wheel rotates around the Y axis.
159 | // For flat circular wheel, the Z Axis is -1. Points are laid out on the X axis (width) and Y axis (height). The wheel rotates around the Z axis.
160 | for (let i = 0; i < this.pointsAmount; i++) {
161 | // Add sprite to group.
162 | this.sprites[i].wheelPosition = i;
163 | this.group.add(this.sprites[i]);
164 |
165 | angle = slice * i;
166 | radCos = radius * Math.cos(angle);
167 | radSin = radius * Math.sin(angle);
168 |
169 | if (this.axis === 'x') {
170 | nx = -1;
171 | ny = radCos;
172 | nz = radSin;
173 | } else if (this.axis === 'y') {
174 | nx = radCos;
175 | ny = -1;
176 | nz = radSin;
177 | } else if (this.axis === 'z') {
178 | nx = radCos;
179 | ny = radSin;
180 | nz = -1;
181 | }
182 |
183 | this.wheelItems.push(new VectorPoint(nx, ny, nz, this.sprites[i], i));
184 | }
185 |
186 | // Active Point
187 | this.active = this.wheelItems[this.firstPlace].sprite;
188 |
189 | this.project();
190 | }
191 |
192 | /** Move the wheel backwards. */
193 | moveBack() {
194 | if (this.moving === false) {
195 | this.moving = true;
196 | this.direction = 0;
197 |
198 | if (this.axis === 'x' || this.axis === 'z') {
199 | this.rotationAxis[this.axis] += this.rotationAmount;
200 | } else { // y axis needs to go in the opposite direction.
201 | this.rotationAxis[this.axis] -= this.rotationAmount;
202 | }
203 |
204 | this.updatePosition('+');
205 |
206 | this.project();
207 | this.resetAngle();
208 | }
209 | }
210 |
211 | /** Move the wheel forward. */
212 | moveForward() {
213 | if (this.moving === false) {
214 | this.moving = true;
215 | this.direction = 1;
216 |
217 | if (this.axis === 'x' || this.axis === 'z') {
218 | this.rotationAxis[this.axis] -= this.rotationAmount;
219 | } else { // y axis needs to go in the opposite direction.
220 | this.rotationAxis[this.axis] += this.rotationAmount;
221 | }
222 |
223 | this.updatePosition('-');
224 |
225 | this.project();
226 | this.resetAngle();
227 | }
228 | }
229 |
230 | /** Project every item in the wheel to it's physical location. */
231 | project() {
232 | // Create a list with the axes, then remove the projected axis.
233 | const arr = ['x', 'y', 'z'];
234 | const idx = arr.indexOf(this.axis);
235 | arr.splice(idx, 1);
236 |
237 | // We only need to call all this when moving. It doesn't need to be done
238 | // every update
239 | for (let i = 0; i < this.wheelItems.length; i++) {
240 | // Rotate along the projected axis
241 | const rotationOne = this.wheelItems[i].rotate(
242 | this.axis,
243 | this.rotationAxis[this.axis],
244 | );
245 |
246 | // Rotate the other 2 axes
247 | const rotationTwo = rotationOne.rotate(arr[0], this.rotationAxis[arr[0]]);
248 | const rotationThree = rotationTwo.rotate(arr[1], this.rotationAxis[arr[1]]);
249 |
250 | const p = rotationThree.project(
251 | this.xy.x,
252 | this.xy.y,
253 | this.zoom,
254 | );
255 |
256 | const transformed = this.wheelItems[i].sprite;
257 | transformed.lz = p.z;
258 |
259 | // Ensure active sprite has no scale/alpha changes.
260 | if (this.wheelItems[i].position === this.firstPlace) {
261 | transformed.alpha = 1.0;
262 | this.active = this.wheelItems[i].sprite;
263 | } else {
264 | if (this.visibleRange !== null) {
265 | const includes = this.visiblePositions.includes(this.wheelItems[i].position);
266 | // const includes = _.includes(
267 | // this.visiblePositions,
268 | // this.wheelItems[i].position,
269 | // );
270 |
271 | if (includes) {
272 | transformed.alpha = 1.0;
273 | } else {
274 | transformed.alpha = 0.0;
275 | }
276 | }
277 | }
278 |
279 | const newTween = new PhaserObjects.Tween(this.game);
280 |
281 | if (i !== this.wheelItems.length - 1) {
282 | newTween.add(
283 | transformed,
284 | { x: p.x, y: p.y },
285 | this.tweenParams.duration,
286 | this.tweenParams.ease,
287 | );
288 | } else {
289 | // Wheel's signals are dispatched by the last tween.
290 | newTween.add(
291 | transformed,
292 | { x: p.x, y: p.y },
293 | this.tweenParams.duration,
294 | this.tweenParams.ease,
295 | () => { this.enableMoving(); this.dispatchOnComplete(); },
296 | null,
297 | () => { this.dispatchOnStart(); },
298 | this,
299 | );
300 | }
301 | }
302 |
303 | // Sort wheelItems by the projection's z axis for correct z-order when drawing.
304 | this.group.sort('lz', PhaserObjects.Group.SORT_ASCENDING);
305 | }
306 |
307 | /** Called after movement starts. */
308 | dispatchOnStart() {
309 | this.emitter.emit('start', this);
310 | }
311 |
312 | /** Called after movement is finished. */
313 | dispatchOnComplete() {
314 | if (this.direction === 0) {
315 | this.emitter.emit('backComplete', this);
316 | } else if (this.direction === 1) {
317 | this.emitter.emit('forwardComplete', this);
318 | }
319 |
320 | this.emitter.emit('complete', this);
321 | }
322 |
323 | /** Once the buttons have finished their move animation, allow them to move again. */
324 | enableMoving() {
325 | this.moving = false;
326 | }
327 |
328 | /** Move all the WheelItem's position by 1. */
329 | updatePosition(operator) {
330 | for (let i = 0; i < this.wheelItems.length; i++) {
331 | const { position } = this.wheelItems[i];
332 | this.wheelItems[i].position = utils.operators[operator](position, 1);
333 |
334 | const m = utils.modulo(this.wheelItems[i].position, this.pointsAmount);
335 | this.wheelItems[i].position = m;
336 | this.wheelItems[i].sprite.wheelPosition = m;
337 | }
338 | }
339 |
340 | /** Make sure rotation can't go past 360 in either direction. */
341 | resetAngle() {
342 | const angle = this.rotationAxis[this.axis];
343 |
344 | if (angle === 360 || angle === -360) {
345 | this.rotationAxis[this.axis] = 0;
346 | }
347 | }
348 | }
349 |
--------------------------------------------------------------------------------
/tests/column.spec.js:
--------------------------------------------------------------------------------
1 | describe("Column", function(){
2 | var column;
3 |
4 | describe("When I add a second node to a Column", function(){
5 | it("Then should be placed under the first node", function(){
6 | var dummySprite = game.add.sprite(0, 0, "dummySprite");
7 | var dummySprite2 = game.add.sprite(0, 0, "dummySprite");
8 | column = new uiWidgets.Column(game);
9 | column.addNode(dummySprite);
10 | column.addNode(dummySprite2);
11 |
12 | chai.expect(column.children[1].y).to.equal(78);
13 | });
14 | });
15 |
16 | describe("When I add a second node to a Column with padding", function(){
17 | it("Then should be placed under to the first node, offset by the padding", function(){
18 | var dummySprite = game.add.sprite(0, 0, "dummySprite");
19 | var dummySprite2 = game.add.sprite(0, 0, "dummySprite");
20 | column = new uiWidgets.Column(game);
21 | column.addNode(dummySprite);
22 | column.addNode(dummySprite2, 0, 23);
23 |
24 | chai.expect(column.children[1].y).to.equal(101);
25 | });
26 | });
27 |
28 | afterEach(function() {
29 | column.destroy();
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/tests/frame.spec.js:
--------------------------------------------------------------------------------
1 | describe("Frame", function(){
2 | describe("When I create a new Frame", function(){
3 | it("Then the x, y attributes should be set correctly", function(){
4 | var frame = new uiWidgets.Frame(game, 12, 37);
5 |
6 | chai.expect(frame.x).to.equal(12);
7 | chai.expect(frame.y).to.equal(37);
8 |
9 | });
10 | });
11 | describe("When I create a new Frame with no x, y attributes", function(){
12 | it("Then the x, y attributes should be 0", function(){
13 | var frame = new uiWidgets.Frame(game);
14 |
15 | chai.expect(frame.x).to.equal(0);
16 | chai.expect(frame.y).to.equal(0);
17 |
18 | });
19 | });
20 | describe("When I add a new node to a Frame", function(){
21 | it("Then it should be added as a child of the Frame", function(){
22 | var frame = new uiWidgets.Frame(game);
23 | var dummySprite = game.add.sprite(0, 0);
24 | frame.addNode(dummySprite);
25 |
26 | chai.expect(frame.children[0]).to.equal(dummySprite);
27 | });
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/tests/row.spec.js:
--------------------------------------------------------------------------------
1 | describe("Row", function(){
2 | var row;
3 |
4 | describe("When I add a second node to a Row", function(){
5 | it("Then should be placed next to the first node", function(){
6 | var dummySprite = game.add.sprite(0, 0, "dummySprite");
7 | var dummySprite2 = game.add.sprite(0, 0, "dummySprite");
8 | row = new uiWidgets.Row(game);
9 | row.addNode(dummySprite);
10 | row.addNode(dummySprite2);
11 |
12 | chai.expect(row.children[1].x).to.equal(300);
13 | });
14 | });
15 |
16 | describe("When I add a second node to a Row with padding", function(){
17 | it("Then should be placed next to the first node, offset by the padding", function(){
18 | var dummySprite = game.add.sprite(0, 0, "dummySprite");
19 | var dummySprite2 = game.add.sprite(0, 0, "dummySprite");
20 | row = new uiWidgets.Row(game);
21 | row.addNode(dummySprite);
22 | row.addNode(dummySprite2, 17, 0);
23 |
24 | chai.expect(row.children[1].x).to.equal(317);
25 | });
26 | });
27 |
28 | afterEach(function() {
29 | row.destroy();
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/tests/testrunner.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Mocha Tests
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
18 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/tests/testrunner_phaser3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Mocha Tests
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
18 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/tests/viewport.spec.js:
--------------------------------------------------------------------------------
1 | describe("Viewport", function(){
2 | var viewport;
3 |
4 | describe("When I create a new Viewport", function(){
5 | it("Then the x, y attributes should be set correctly", function(){
6 | viewport = new uiWidgets.Viewport(game, 17, 102, 103, 104);
7 | chai.expect(viewport.x).to.equal(17);
8 | chai.expect(viewport.y).to.equal(102);
9 | });
10 |
11 | it("Then the area attribute should be set correctly", function(){
12 | viewport = new uiWidgets.Viewport(game, 17, 102, 103, 104);
13 | chai.expect(viewport.area.x).to.equal(17);
14 | chai.expect(viewport.area.y).to.equal(102);
15 | chai.expect(viewport.area.width).to.equal(103);
16 | chai.expect(viewport.area.height).to.equal(104);
17 | });
18 |
19 | it("Then the viewport mask attributes should be set correctly", function(){
20 | viewport = new uiWidgets.Viewport(game, 17, 102, 103, 104);
21 | chai.expect(viewport.mask.x).to.equal(17);
22 | chai.expect(viewport.mask.y).to.equal(102);
23 | });
24 | });
25 |
26 | afterEach(function() {
27 | viewport.destroy();
28 | });
29 |
30 | });
31 |
--------------------------------------------------------------------------------
/tests/wheel3D.spec.js:
--------------------------------------------------------------------------------
1 | describe("Wheel3D", function(){
2 | describe("When I create a new Wheel3D", function(){
3 | describe("And I move the wheel backwards", function(){
4 | it("Then the active sprite should be the previous one", function(done){
5 | var menuList = [];
6 | for (var i = 0; i < 4; i++) {
7 | var dummySprite = game.add.sprite(0, 0, "dummySprite");
8 | menuList.push(dummySprite);
9 | }
10 |
11 | var wheel = new uiWidgets.Wheel3D(
12 | game,
13 | {"x": 0, "y": 0},
14 | menuList,
15 | 0,
16 | 90,
17 | "x",
18 | {"x":0, "y": -90, "z": 0}
19 | );
20 |
21 | var isDone = false;
22 |
23 | wheel.emitter.on('complete',
24 | function (wheel) {
25 | isDone = true;
26 | });
27 | wheel.activate();
28 | wheel.moveBack();
29 |
30 | setTimeout( function () {
31 | try {
32 | chai.expect(isDone).to.equal(true);
33 | done();
34 | } catch(err) {
35 | done(err);
36 | }
37 | }, 500 );
38 | });
39 | });
40 | describe("And I move the wheel forward", function(){
41 | it("Then the active sprite should be the next one", function(done){
42 | var menuList = [];
43 | for (var i = 0; i < 4; i++) {
44 | var dummySprite = game.add.sprite(0, 0, "dummySprite");
45 | menuList.push(dummySprite);
46 | }
47 |
48 | var wheel = new uiWidgets.Wheel3D(
49 | game,
50 | {"x": 0, "y": 0},
51 | menuList,
52 | 0,
53 | 90,
54 | "x",
55 | {"x":0, "y": -90, "z": 0}
56 | );
57 |
58 | var isDone = false;
59 |
60 | wheel.emitter.on('complete',
61 | function (wheel) {
62 | isDone = true;
63 | });
64 | wheel.activate();
65 | wheel.moveForward();
66 |
67 | setTimeout( function () {
68 | try {
69 | chai.expect(isDone).to.equal(true);
70 | done();
71 | } catch(err) {
72 | done(err);
73 | }
74 | }, 500 );
75 |
76 | });
77 | });
78 | });
79 | });
80 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | const ESLintPlugin = require('eslint-webpack-plugin');
4 |
5 | module.exports = {
6 | mode: 'production',
7 | plugins: [new ESLintPlugin()],
8 | module: {
9 | rules: [
10 | {
11 | test: /\.(js)$/,
12 | exclude: /node_modules/,
13 | use: {
14 | loader: 'babel-loader',
15 | options: {
16 | presets: ['@babel/preset-env'],
17 | },
18 | },
19 | },
20 | ],
21 | },
22 | entry: './src/entry.js',
23 | output: {
24 | library: 'uiWidgets',
25 | libraryTarget: 'umd',
26 | umdNamedDefine: true,
27 | filename: 'phaser-ui-tools.js',
28 | path: path.resolve(__dirname, 'dist'),
29 | },
30 | };
31 |
--------------------------------------------------------------------------------