Skip to content

Commit ce404e7

Browse files
author
AleBles
committedMar 31, 2016
added support for zoom/focus on input field, added support for the return/enter key.
1 parent b2bfcf8 commit ce404e7

9 files changed

+257
-63
lines changed
 

‎README.md

+31-40
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@ Phaser Input
33

44
Some description here about how awesome this Phaser Input library is, because it works on Canvas AND WebGL. Oh did I mention mobile to? no? Well it supports mobile..
55

6+
Key features:
7+
8+
* Works on mobile and Desktop
9+
* Included TypeScript support
10+
* Also runs under WebGL renderer
11+
* Pure Phaser implementation
12+
* Easy configurable
13+
* Production hardened
14+
615

716
Getting Started
817
---------------
@@ -21,8 +30,9 @@ After adding the script to the page you can activate it by enabling the plugin:
2130
game.add.plugin(Fabrique.Plugins.Input);
2231
```
2332

24-
Adding a InputField
25-
-------------------
33+
Usage
34+
-----
35+
### Adding a InputField
2636
The simpelest way of adding a input field is:
2737
```javascript
2838
var input = game.add.inputField(10, 90);
@@ -44,13 +54,21 @@ var password = game.add.inputField(10, 90, {
4454
type: Fabrique.InputType.password
4555
});
4656
```
57+
### Using zoom
58+
Zooming is easy to enable on an input field, it can be passed to the InputField as a setting. But there are some caveats:
59+
60+
First of all, it's only meant for mobile. Second; it modifies the scale and pivot of the world, and that might interfere with your resize.
61+
62+
Also, when the keyboard is shown, sometimes a resize event will be triggered.
4763

48-
Current Limitations
49-
-------------------
64+
Ideally you use a custom resize event, check for the static property `Fabrique.Plugins.InputField.KeyboardOpen` and don't resize when it's set to true.
65+
66+
67+
### Current Limitations
5068
- Updates are slow when typing fast (type slower you!!)
69+
- Zoom modifies the pivot and scal eof the world, so it might interfere with some stuff
5170

52-
Properties
53-
----------
71+
## Properties
5472
- **x**: number (0 by default) The X-coordinate in the game
5573
- **y**: number (0 by default) The Y-coordinate in the game
5674
- **fill**: string (#fff by default) The color of the inputted text
@@ -70,9 +88,9 @@ Properties
7088
- **min**: string (none by default) The minimum number for the input field, only for number input fields
7189
- **max**: string (none by default) The maximum number for the number input field, or the maxLength for other input fields
7290
- **selectionColor**: string (rgba(179, 212, 253, 0.8) by default) The default color for the text selection highlight.
91+
- **zoom**: boolean (false by default) if we need to zoom onto the input field (mobile only).
7392

74-
Browser Support
75-
---------------
93+
### Browser Support
7694
Tested on:
7795
- Desktop
7896
* Chrome 48+
@@ -82,40 +100,13 @@ Tested on:
82100
* Chrome 48+
83101
* iOS 9+
84102

85-
Changelog
86-
---------
87-
### 1.0.0
88-
* Updated example
89-
* Added masking for texts so they don't overflow the box anymore
90-
* Combined max/maxLength
91-
* Moved dom manipulation to seperate class
92-
* Added option for aligning texts
93-
* Keyboard can now be used to update caret position
94-
* Clicking in the input field now changes the caret position
95-
* ctrl+a can be used to select text
96-
97-
### 0.1.4
98-
* You can now reset text
99-
* Only nummeric input now also possible as type
100-
* You can now specify a max length (text/password) or min/max (number)
101-
102-
### 0.1.3
103-
* Fixed an issue where input wouldn't appear on Desktop Firefox and Safari
104-
105-
### 0.1.2
106-
* Fixed a small issue when no placeHolder was set
107-
108-
### 0.1.1
109-
* Fixed sprite texture glitch in WebGL renderers
110-
* Appended properties with the inherited Phaser.PhaserTextStyle properties that are used
111-
* added the possibility to change the cursor color
112-
* made the options parameter optional
113-
114-
### 0.1.0
115-
* Full Android/iOS support
103+
Credits
104+
-------
105+
phaser-input is inspired by [CanvasInput](https://github.com/goldfire/CanvasInput)
116106

117107
Disclaimer
118108
----------
119109
We at OrangeGames just love playing and creating awesome games. We aren't affiliated with Phaser.io. We just needed some awesome input boxes in our awesome HTML5 games. Feel free to use it for enhancing your own awesome games!
120110

121-
Released under the MIT license
111+
Phaser Input is distributed under the MIT license. All 3rd party libraries and components are distributed under their
112+
respective license terms.

‎build/phaser-input.d.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,17 @@ declare module Fabrique {
99
private callback;
1010
private type;
1111
private id;
12-
constructor(id: string, type?: InputType, value?: string);
12+
private game;
13+
focusIn: Phaser.Signal;
14+
focusOut: Phaser.Signal;
15+
constructor(game: Phaser.Game, id: string, type?: InputType, value?: string);
1316
addKeyUpListener(callback: () => void): void;
1417
removeEventListener(): void;
1518
destroy(): void;
1619
setMax(max: string, min?: string): void;
1720
value: string;
1821
focus(): void;
22+
blur(): void;
1923
hasSelection: boolean;
2024
caretStart: number;
2125
caretEnd: number;
@@ -42,6 +46,7 @@ declare module Fabrique {
4246
max?: string;
4347
textAlign?: string;
4448
selectionColor?: string;
49+
zoom?: boolean;
4550
}
4651
class InputField extends Phaser.Sprite {
4752
private placeHolder;
@@ -106,10 +111,12 @@ declare module Fabrique {
106111
* This checks if a select has been made, and if so highlight it with blue
107112
*/
108113
private updateSelection();
114+
private zoomIn();
115+
private zoomOut();
109116
/**
110117
* Event fired when a key is pressed, it takes the value from the hidden input field and adds it as its own
111118
*/
112-
private keyListener();
119+
private keyListener(evt);
113120
/**
114121
* We overwrite the destroy method because we want to delete the (hidden) dom element when the inputField was removed
115122
*/
@@ -156,6 +163,8 @@ declare module Fabrique {
156163
make: InputFieldObjectCreator;
157164
}
158165
class InputField extends Phaser.Plugin {
166+
static Zoomed: boolean;
167+
static KeyboardOpen: boolean;
159168
constructor(game: Phaser.Game, parent: PIXI.DisplayObject);
160169
/**
161170
* Extends the GameObjectFactory prototype with the support of adding InputField. this allows us to add InputField methods to the game just like any other object:

‎build/phaser-input.js

+94-12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎build/phaser-input.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎example/index.html

+10-3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@
3939
}
4040

4141
function create(){
42+
if (!game.device.desktop) {
43+
game.scale.setGameSize(window.innerWidth, window.innerHeight);
44+
}
45+
4246
//let's add a nice background
4347
game.add.image(0, 0, 'bg');
4448

@@ -64,7 +68,8 @@
6468
borderColor: '#000',
6569
borderRadius: 6,
6670
placeHolder: 'Username',
67-
textAlign: 'center'
71+
textAlign: 'center',
72+
zoom: true
6873
});
6974

7075
//We'd need a password too
@@ -81,7 +86,8 @@
8186
borderColor: '#000',
8287
borderRadius: 6,
8388
placeHolder: 'Password',
84-
type: Fabrique.InputType.password
89+
type: Fabrique.InputType.password,
90+
zoom: true
8591
});
8692

8793
//Let's not forget about age?!
@@ -100,7 +106,8 @@
100106
min: '18',
101107
max: '99',
102108
placeHolder: 'Your age',
103-
type: Fabrique.InputType.number
109+
type: Fabrique.InputType.number,
110+
zoom: true
104111
});
105112

106113
var submitBtn = game.add.nineSlice(game.width / 2 - 100, 360, 'btn', 100, 70);

‎package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "phaser-input",
33
"author": "OrangeGames",
4-
"version": "1.0.0",
4+
"version": "1.1.0",
55
"description": "Adds input boxes to Phaser like CanvasInput, but also works for WebGL and Mobile, made for Phaser only.",
66
"contributors": [
77
{

‎ts/InputElement.ts

+38-1
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,16 @@ module Fabrique {
1515

1616
private id: string;
1717

18-
constructor(id: string, type: InputType = InputType.text, value: string = '') {
18+
private game: Phaser.Game;
19+
20+
public focusIn: Phaser.Signal = new Phaser.Signal();
21+
22+
public focusOut: Phaser.Signal = new Phaser.Signal();
23+
24+
constructor(game: Phaser.Game, id: string, type: InputType = InputType.text, value: string = '') {
1925
this.id = id;
2026
this.type = type;
27+
this.game = game;
2128

2229
this.element = document.createElement('input');
2330

@@ -28,6 +35,14 @@ module Fabrique {
2835
this.element.value = this.value;
2936
this.element.type = InputType[type];
3037

38+
39+
this.element.addEventListener('focusin', (): void => {
40+
this.focusIn.dispatch();
41+
});
42+
this.element.addEventListener('focusout', (): void => {
43+
this.focusOut.dispatch()
44+
});
45+
3146
document.body.appendChild(this.element);
3247
}
3348

@@ -71,6 +86,28 @@ module Fabrique {
7186

7287
public focus(): void {
7388
this.element.focus();
89+
console.log('focussing');
90+
if (!this.game.device.desktop && this.game.device.chrome) {
91+
let originalWidth = window.innerWidth,
92+
originalHeight = window.innerHeight;
93+
94+
let kbAppeared: boolean = false;
95+
let interval: number = setInterval((): void => {
96+
console.log(originalWidth, window.innerWidth, originalHeight, window.innerHeight)
97+
if (originalWidth > window.innerWidth || originalHeight > window.innerHeight) {
98+
kbAppeared = true;
99+
}
100+
101+
if (kbAppeared && originalWidth === window.innerWidth && originalHeight === window.innerHeight) {
102+
this.focusOut.dispatch();
103+
clearInterval(interval);
104+
}
105+
}, 50);
106+
}
107+
}
108+
109+
public blur(): void {
110+
this.element.blur();
74111
}
75112

76113
get hasSelection () {

‎ts/InputField.ts

+68-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ module Fabrique {
1818
max?: string;
1919
textAlign?: string;
2020
selectionColor?: string;
21+
zoom?: boolean;
2122
}
2223

2324
export class InputField extends Phaser.Sprite {
@@ -56,6 +57,7 @@ module Fabrique {
5657
this.inputOptions.height = inputOptions.height || 14;
5758
this.inputOptions.fillAlpha = (inputOptions.fillAlpha === undefined) ? 1 : inputOptions.fillAlpha;
5859
this.inputOptions.selectionColor = inputOptions.selectionColor || 'rgba(179, 212, 253, 0.8)';
60+
this.inputOptions.zoom = (!game.device.desktop) ? inputOptions.zoom || false : false;
5961

6062
//create the input box
6163
this.box = new InputBox(this.game, inputOptions);
@@ -66,7 +68,7 @@ module Fabrique {
6668
this.addChild(this.textMask);
6769

6870
//Create the hidden dom elements
69-
this.domElement = new InputElement('phaser-input-' + (Math.random() * 10000 | 0).toString(), this.inputOptions.type, this.value);
71+
this.domElement = new InputElement(this.game, 'phaser-input-' + (Math.random() * 10000 | 0).toString(), this.inputOptions.type, this.value);
7072
this.domElement.setMax(this.inputOptions.max, this.inputOptions.min);
7173

7274
this.selection = new SelectionHighlight(this.game, this.inputOptions);
@@ -125,6 +127,14 @@ module Fabrique {
125127
this.input.useHandCursor = true;
126128

127129
this.game.input.onDown.add(this.checkDown, this);
130+
this.domElement.focusOut.add((): void => {
131+
if (Plugins.InputField.KeyboardOpen) {
132+
this.endFocus();
133+
if (this.inputOptions.zoom) {
134+
this.zoomOut();
135+
}
136+
}
137+
})
128138
}
129139

130140
/**
@@ -150,9 +160,15 @@ module Fabrique {
150160
}
151161

152162
this.startFocus();
163+
if (this.inputOptions.zoom) {
164+
this.zoomIn();
165+
}
153166
} else {
154167
if (this.focus === true) {
155-
this.endFocus()
168+
this.endFocus();
169+
if (this.inputOptions.zoom) {
170+
this.zoomOut();
171+
}
156172
}
157173
}
158174
}
@@ -190,6 +206,19 @@ module Fabrique {
190206
this.placeHolder.visible = true;
191207
}
192208
this.cursor.visible = false;
209+
210+
if (this.game.device.desktop) {
211+
//Timeout is a chrome hack
212+
setTimeout(() => {
213+
this.domElement.blur();
214+
}, 0);
215+
} else {
216+
this.domElement.blur();
217+
}
218+
219+
if (!this.game.device.desktop) {
220+
Plugins.InputField.KeyboardOpen = false;
221+
}
193222
}
194223

195224
/**
@@ -207,6 +236,9 @@ module Fabrique {
207236
this.domElement.focus();
208237
}
209238

239+
if (!this.game.device.desktop) {
240+
Plugins.InputField.KeyboardOpen = true;
241+
}
210242
}
211243

212244
/**
@@ -357,14 +389,47 @@ module Fabrique {
357389
this.selection.clear();
358390
}
359391
}
392+
393+
private zoomIn(): void {
394+
if (Plugins.InputField.Zoomed) {
395+
return;
396+
}
397+
398+
let windowScale: number;
399+
if (window.innerHeight > window.innerWidth) {
400+
windowScale = this.game.width / (this.width * 1.5);
401+
} else {
402+
windowScale = (this.game.width / 2) / (this.width * 1.5);
403+
}
404+
405+
let offsetX: number = ((this.game.width - this.width * 1.5) / 2) / windowScale;
406+
this.game.world.scale.set(windowScale);
407+
this.game.world.pivot.set(this.x - offsetX, this.y - this.inputOptions.padding * 2);
408+
Plugins.InputField.Zoomed = true;
409+
}
410+
411+
private zoomOut(): void {
412+
if (!Plugins.InputField.Zoomed) {
413+
return;
414+
}
415+
416+
this.game.world.scale.set(1);
417+
this.game.world.pivot.set(0, 0);
418+
Plugins.InputField.Zoomed = false;
419+
}
360420

361421
/**
362422
* Event fired when a key is pressed, it takes the value from the hidden input field and adds it as its own
363423
*/
364-
private keyListener()
424+
private keyListener(evt: KeyboardEvent)
365425
{
366426
this.value = this.domElement.value;
367427

428+
if (evt.keyCode === 13) {
429+
this.endFocus();
430+
return;
431+
}
432+
368433
this.updateText();
369434
this.updateCursor();
370435
this.updateSelection();

‎ts/Plugin.ts

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ module Fabrique {
1414
}
1515

1616
export class InputField extends Phaser.Plugin {
17+
public static Zoomed: boolean = false;
18+
public static KeyboardOpen: boolean = false;
19+
1720
constructor(game:Phaser.Game, parent:PIXI.DisplayObject) {
1821
super(game, parent);
1922

0 commit comments

Comments
 (0)
Please sign in to comment.