├── .bowerrc ├── .gitignore ├── example ├── UIpack │ ├── blueSheet.png │ ├── license.txt │ └── blueSheet.xml ├── index.htm ├── game.js └── nine-patch-phaser-plugin │ ├── nine-patch-phaser-plugin.min.js │ └── nine-patch-phaser-plugin.js ├── bower.json ├── package.json ├── src ├── index.js ├── NinePatchImage.es6 └── NinePatchCache.es6 ├── gulpfile.js └── README.md /.bowerrc: -------------------------------------------------------------------------------- 1 | { "directory": "example/lib" } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | example/lib 3 | -------------------------------------------------------------------------------- /example/UIpack/blueSheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netcell/nine-patch-phaser-plugin/HEAD/example/UIpack/blueSheet.png -------------------------------------------------------------------------------- /example/UIpack/license.txt: -------------------------------------------------------------------------------- 1 | 2 | ############################################################################### 3 | 4 | UI pack by Kenney Vleugels (www.kenney.nl) 5 | 6 | ------------------------------ 7 | 8 | License (CC0) 9 | http://creativecommons.org/publicdomain/zero/1.0/ 10 | 11 | You may use these graphics in personal and commercial projects. 12 | Credit (Kenney or www.kenney.nl) would be nice but is not mandatory. 13 | 14 | ############################################################################### -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nine-patch-phaser-plugin", 3 | "version": "1.0.0", 4 | "authors": [ 5 | "Nguyen Tuan Anh " 6 | ], 7 | "description": "A Nine Patch Plugin for Phaser", 8 | "main": "build/nine-patch-phaser-plugin.min.js", 9 | "moduleType": [ 10 | "es6", 11 | "globals", 12 | "node" 13 | ], 14 | "keywords": [ 15 | "phaser", 16 | "plugin", 17 | "nine", 18 | "patch", 19 | "9", 20 | "ninepatch", 21 | "9patch", 22 | "nine-patch", 23 | "9-patch" 24 | ], 25 | "license": "MIT", 26 | "homepage": "http://anhnt.ninja", 27 | "ignore": [ 28 | "node_modules", 29 | "bower_components" 30 | ], 31 | "dependencies": { 32 | "dat-gui": "~0.5.1", 33 | "phaser": "~2.4.3" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nine-patch-phaser-plugin", 3 | "version": "1.0.0", 4 | "description": "A Nine Patch Plugin for Phaser", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "phaser", 11 | "plugin", 12 | "nine", 13 | "patch", 14 | "9", 15 | "ninePatch", 16 | "9Patch" 17 | ], 18 | "author": "Nguyen Tuan Anh ", 19 | "license": "MIT", 20 | "dependencies": { 21 | "babelify": "^6.2.0", 22 | "browserify": "^11.0.1", 23 | "gulp": "^3.9.0", 24 | "gulp-clean": "^0.3.1", 25 | "gulp-rename": "^1.2.2", 26 | "gulp-uglify": "^1.3.0", 27 | "run-sequence": "^1.1.2", 28 | "vinyl-source-stream": "^1.1.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /example/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Phaser Nine Patch Plugin 6 | 7 | 8 | 9 | 10 | 11 |
12 |
NINE PATCH PLUGIN FOR PHASER
13 |
created by @netcell at http://anhnt.ninja
14 |
15 |
EXAMPLE PAGE
16 |
17 |
Use the control panel in the top right conner -->
18 |
Remember to run UpdateImageSize after changing anchor
19 |
20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | var NinePatchCache = require('./NinePatchCache'); 2 | /** 3 | * This function should be called when the image/spritesheet/texture has been loaded 4 | * @param {String} name - the key to refer to the created NinePatchCache 5 | * @param {String} imageKey - REF NinePatchCache 6 | * @param {String} imageFrame - REF NinePatchCache 7 | * @param {Number} left - REF NinePatchCache 8 | * @param {Number} right - REF NinePatchCache 9 | * @param {Number} top - REF NinePatchCache 10 | * @param {Number} bottom - REF NinePatchCache 11 | */ 12 | Phaser.Cache.prototype.addNinePatch = function addNinePatch(name, imageKey, imageFrame, left, right, top, bottom){ 13 | var _ninePatches = this._ninePatches = this._ninePatches || {}; 14 | _ninePatches[name] = new NinePatchCache(this.game, imageKey, imageFrame, left, right, top, bottom); 15 | console.log(_ninePatches) 16 | } 17 | /** Return an instance of NinePatchCache match with the name */ 18 | Phaser.Cache.prototype.getNinePatch = function getNinePatch(name) { 19 | var _ninePatches = this._ninePatches = this._ninePatches || {}; 20 | return _ninePatches[name]; 21 | } 22 | Phaser.NinePatchImage = require('./NinePatchImage'); -------------------------------------------------------------------------------- /example/game.js: -------------------------------------------------------------------------------- 1 | var game = new Phaser.Game(600, 400, Phaser.CANVAS, 'game', { 2 | preload: function preload() { 3 | game.load.atlasXML('blueSheet', 'UIpack/blueSheet.png', 'UIpack/blueSheet.xml'); 4 | }, 5 | create: function create() { 6 | /** Cache the patches' textures */ 7 | game.cache.addNinePatch('blue_button02', 'blueSheet', 'blue_button02.png', 10, 10, 10, 20); 8 | /** @type {Phaser.NinePatchImage} Create a NinePatchImage from cached textures */ 9 | var image = new Phaser.NinePatchImage(game, game.width/2, game.height/2, 'blue_button02'); 10 | /** Set the measures for image - [AUTOMATICALLY UPDATED] */ 11 | image.targetWidth = 200; 12 | image.targetHeight = 200; 13 | /** Set anchor for image - [NEEDS MANUAL UPDATE] */ 14 | image.anchor.setTo(0.5, 0.5); 15 | image.UpdateImageSizes(); 16 | /** [NOT IMPORTANT] Dat.Gui Controller */ 17 | var gui = new dat.GUI(); 18 | var position = gui.addFolder('position'); 19 | position.add(image, 'x').step(1); 20 | position.add(image, 'y').step(1); 21 | var measures = gui.addFolder('measures'); 22 | measures.add(image, 'targetWidth').step(1); 23 | measures.add(image, 'targetHeight').step(1); 24 | var anchor = gui.addFolder('anchor'); 25 | anchor.add(image.anchor, 'x').step(0.01); 26 | anchor.add(image.anchor, 'y').step(0.01); 27 | gui.add(image, 'UpdateImageSizes'); 28 | } 29 | }) -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var clean = require('gulp-clean'); 3 | var browserify = require('browserify'); 4 | var source = require('vinyl-source-stream'); 5 | var babelify = require('babelify'); 6 | var uglify = require('gulp-uglify'); 7 | var rename = require('gulp-rename'); 8 | var runSequence = require('run-sequence'); 9 | 10 | gulp.task('copy:example', function() { 11 | return gulp.src('./build/*.js') 12 | .pipe(gulp.dest('./example/nine-patch-phaser-plugin')); 13 | }); 14 | 15 | gulp.task('minify', function() { 16 | return gulp.src('./build/nine-patch-phaser-plugin.js') 17 | .pipe(rename('nine-patch-phaser-plugin.min.js')) 18 | .pipe(uglify()) 19 | .pipe(gulp.dest('./build')); 20 | }); 21 | 22 | gulp.task('browserify', function() { 23 | var bundler = browserify('./src/index.js', { extensions : ['.js', '.es6'] }); 24 | bundler.transform( babelify.configure({ only : /es6/ }) ); 25 | return bundler.bundle() 26 | .pipe(source('nine-patch-phaser-plugin.js')) 27 | .pipe(gulp.dest('./build')); 28 | }); 29 | 30 | gulp.task('browserify:debug', function() { 31 | var bundler = browserify('./src/index.js', { extensions : ['.js', '.es6'], debug : true }); 32 | bundler.transform( babelify.configure({ only : /es6/ }) ); 33 | return bundler.bundle() 34 | .pipe(source('nine-patch-phaser-plugin.js')) 35 | .pipe(gulp.dest('./build')); 36 | }); 37 | 38 | gulp.task('clean', function () { 39 | return gulp.src([ './build/**/*.*', ], {read: false}).pipe(clean({force: true})); 40 | }); 41 | 42 | gulp.task('default', function(cb) { 43 | runSequence('clean', 'browserify', 'minify', 'copy:example', cb); 44 | }); 45 | 46 | gulp.task('debug', function(cb) { 47 | runSequence('clean', 'browserify:debug', 'minify', 'copy:example', cb); 48 | }); -------------------------------------------------------------------------------- /example/UIpack/blueSheet.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/NinePatchImage.es6: -------------------------------------------------------------------------------- 1 | /** 2 | * Return true if value is a String 3 | * TODO: Use a better method to prevent error 4 | */ 5 | function isString(value){ 6 | return typeof value === 'string'; 7 | } 8 | 9 | export default class NinePatchImage extends Phaser.Image { 10 | /** 11 | * @param {Phaser.Game} game - REF Phaser.Image params 12 | * @param {Number} x = 0 - REF Phaser.Image params 13 | * @param {Number} y = 0 - REF Phaser.Image params 14 | * @param {String || NinePatchCache} key - The NinePatchCache used by the NinePatchImage. It can be a string which is a reference to the Cache entry, or an instance of a NinePatchCache. 15 | * @param {NinePatchCache} ninePatchImages - To be deprecated. 16 | */ 17 | constructor(game, x = 0, y = 0, key, ninePatchImages) { 18 | super(game, x, y, PIXI.Texture.emptyTexture); 19 | game.add.existing(this); 20 | /** Get the NinePatchCache instance */ 21 | if (!ninePatchImages) { 22 | if (typeof key == 'string') { 23 | ninePatchImages = game.cache.getNinePatch(key); 24 | } else if (true /** Check if key is an instance of NinePatchCache */) { 25 | ninePatchImages = key; 26 | } else throw new Error('NinePatchImage key must be a String or an instance of NinePatchCache'); 27 | } 28 | this.ninePatchImages = ninePatchImages; 29 | /** @type {Array} Generate 9 instances of Phaser.Image as the children of this */ 30 | this.images = ninePatchImages.CreateImages(this); 31 | /** Setting measures for this */ 32 | this.currentWidth = ninePatchImages.width; 33 | this.currentHeight = ninePatchImages.height; 34 | /** Update images' positions */ 35 | this.UpdateImageSizes(); 36 | } 37 | /** Get/Set for measures to update images' positions on chagnges */ 38 | get targetWidth() { 39 | return this.currentWidth; 40 | } 41 | get targetHeight() { 42 | return this.currentHeight; 43 | } 44 | set targetWidth(value) { 45 | this.currentWidth = value; 46 | this.UpdateImageSizes(); 47 | } 48 | set targetHeight(value) { 49 | this.currentHeight = value; 50 | this.UpdateImageSizes(); 51 | } 52 | /** Update images' positions to match the new measures */ 53 | UpdateImageSizes() { 54 | var {ninePatchImages, currentWidth, currentHeight, images, anchor} = this; 55 | /** Get the positions for the new measures */ 56 | var dimensions = ninePatchImages.CreateDimensionMap(currentWidth, currentHeight); 57 | /** Calculate the padding to match the anchor */ 58 | var paddingX = anchor.x * currentWidth; 59 | var paddingY = anchor.y * currentHeight; 60 | /** Loop through all images and update the positions */ 61 | for (let i = 0; i < 3; i++) { 62 | for (let j = 0; j < 3; j++) { 63 | let image = images[i][j]; 64 | let dimension = dimensions[i][j]; 65 | image.x = dimension.x - paddingX; 66 | image.y = dimension.y - paddingY; 67 | image.width = dimension.width; 68 | image.height = dimension.height; 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nine Patch Phaser Plugin 2 | 3 | **UPDATE**: Unless you are currently using it, or your game is not very complicated, or has no need to run on old mobile devices, I am recommending you not to use this library due to posible performance issues. This is a nice experiment and a modified version of it (specifically designed for a code base of a game, so not gonna be useful publicly released) works pretty well in production. It is possible to look into the `src` folder to understand the library (it's really simple) and modify it to your needs, and I am willing to support you. However, since I am not currently using Phaser, I can't really invest time into updating this old library. Sincerely appologize. Thank you for your interest. 4 | 5 | Nine Patch Phaser Plugin allows you to use [nine patch images](https://github.com/chrislondon/9-Patch-Image-for-Websites/wiki/What-Are-9-Patch-Images) in the HTML game framework [Phaser](http://phaser.io). 6 | 7 | This is not technically a Phaser Plugin. It provides two methods in `game.cache` to generate nine patch textures and a `Phaser.NinePatchImage` class to create nine patch images from these textures. 8 | 9 | The plugin is written using ES6 and compiled with [Babel](babeljs.io) and [Browserify](http://browserify.org/), tested on Phaser 2.1.3 and Phaser 2.4.3. 10 | 11 | **UPDATE**: The latest release is supposed to be compatible with Phaser 2.6.1 and above. If you are using an older version, please try using previous releases first. 12 | 13 | Feel free to follow me on twitter [@netcell](https://twitter.com/netcell) and check out [my blog](http://netcell.github.io)! 14 | 15 | ## Demo 16 | 17 | Check the `example` folder or try that example rightaway on [this codepen](http://codepen.io/netcell/full/XmrWod/). The example includes a [dat.gui](https://github.com/dataarts/dat.gui) control panel that you can play with. 18 | 19 | ## Download 20 | 21 | The source is available for download from [latest release](https://github.com/netcell/nine-patch-phaser-plugin/releases) or by cloning the repository or download the files in `build` folder. Alternatively, you can install via: 22 | - [bower](http://bower.io/): `bower install --save nine-patch-phaser-plugin` 23 | 24 | ## Usage 25 | 26 | Simply download the `nine-patch-phaser-plugin.js` or `nine-patch-phaser-plugin.min.js` script from [latest release](https://github.com/netcell/nine-patch-phaser-plugin/releases) and include it on your page after including Phaser: 27 | 28 | ```html 29 | 30 | 31 | ``` 32 | 33 | In the `create` method in your preloading states (to make sure the image/spritesheet/atlas is loaded), use `game.cache.addNinePatch` method to create the nine patch textures: 34 | ```javascript 35 | game.cache.addNinePatch(name, key, frame, left, right, top, bottom); 36 | ``` 37 | - `name` is the reference key that would be used later to get the nine patch textures 38 | - `key` is a key string of the image/spritesheet/atlas loaded 39 | - `frame` is the optional index of the frame if the nine patch image is on a spritesheet or atlas, can be either string or number 40 | - `left`, `right`, `top`, `bottom` are the left most, right most, top most and bottom most points of the center patch in the nine patch image. 41 | 42 | After that, in your game, you can create a nine patch image as follow: 43 | ```javascript 44 | var image = new Phaser.NinePatchImage(game, x, y, name); 45 | ``` 46 | with `name` is the reference key you specified before. 47 | 48 | To change the measures of the NinePatchImage, change the `targetWidth` and `targetHeight` properties. Also, remember that since Phaser.NinePatchImage actually extends Phaser.Image, so you can do anything that you can do on a Phaser.Image instance with a Phaser.NinePatchImage instance. However, in some cases, like with `anchor`, you have to run the method `UpdateImageSizes` for the NinePatchImage to be displayed correctly. 49 | 50 | Check the example in `example` folder to see it in action :) 51 | 52 | ### License ### 53 | 54 | This content is released under the (http://opensource.org/licenses/MIT) MIT License. 55 | 56 | -------------------------------------------------------------------------------- /example/nine-patch-phaser-plugin/nine-patch-phaser-plugin.min.js: -------------------------------------------------------------------------------- 1 | !function e(t,r,i){function a(h,s){if(!r[h]){if(!t[h]){var o="function"==typeof require&&require;if(!s&&o)return o(h,!0);if(n)return n(h,!0);var u=new Error("Cannot find module '"+h+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[h]={exports:{}};t[h][0].call(c.exports,function(e){var r=t[h][1][e];return a(r?r:e)},c,c.exports,e,t,r,i)}return r[h].exports}for(var n="function"==typeof require&&require,h=0;h=0;r--)for(var i=2;i>=0;i--){var a=t[r][i];a.x+=this.x,a.y+=this.y}for(var r=0;3>r;r++)for(var i=0;3>i;i++)this.textures[r][i]=new PIXI.Texture(e,t[r][i])}},{key:"CreateDimensionMap",value:function(){for(var e=arguments.length<=0||void 0===arguments[0]?this.width:arguments[0],t=arguments.length<=1||void 0===arguments[1]?this.height:arguments[1],r=this.left,i=this.right,a=this.top,n=this.bottom,h=e-r-i,s=t-a-n,o=[[],[],[]],u=2;u>=0;u--)for(var c=2;c>=0;c--){var f=o[u][c]={};switch(u){case 0:f.height=a,f.y=0;break;case 1:f.height=s,f.y=a;break;case 2:f.height=n,f.y=a+s}switch(c){case 0:f.width=r,f.x=0;break;case 1:f.width=h,f.x=r;break;case 2:f.width=i,f.x=r+h}}return o}},{key:"CreateImages",value:function(e){for(var t=this.textures,r=[[],[],[]],i=0;3>i;i++)for(var a=0;3>a;a++){var n=r[i][a]=this.game.add.image(0,0,t[i][a]);e&&(e.add?e.add(n):e.addChild&&e.addChild(n))}return r}}]),e}();r["default"]=n,t.exports=r["default"]},{}],2:[function(e,t,r){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(r,"__esModule",{value:!0});var n=function(){function e(e,t){for(var r=0;ro;o++)for(var u=0;3>u;u++){var c=i[o][u],f=n[o][u];c.x=f.x-h,c.y=f.y-s,c.width=f.width,c.height=f.height}}},{key:"targetWidth",get:function(){return this.currentWidth},set:function(e){this.currentWidth=e,this.UpdateImageSizes()}},{key:"targetHeight",get:function(){return this.currentHeight},set:function(e){this.currentHeight=e,this.UpdateImageSizes()}}]),t}(Phaser.Image);r["default"]=s,t.exports=r["default"]},{}],3:[function(e,t,r){var i=e("./NinePatchCache");Phaser.Cache.prototype.addNinePatch=function(e,t,r,a,n,h,s){var o=this._ninePatches=this._ninePatches||{};o[e]=new i(this.game,t,r,a,n,h,s),console.log(o)},Phaser.Cache.prototype.getNinePatch=function(e){var t=this._ninePatches=this._ninePatches||{};return t[e]},Phaser.NinePatchImage=e("./NinePatchImage")},{"./NinePatchCache":1,"./NinePatchImage":2}]},{},[3]); -------------------------------------------------------------------------------- /src/NinePatchCache.es6: -------------------------------------------------------------------------------- 1 | export default class NinePatchCache { 2 | /** 3 | * * @param {Phaser.Game} game - A reference to the currently running game. 4 | * @param {String} imageKey - The reference to the Cache entry of the texture to cut from. 5 | * @param {String|Number} imageFrame - If the texture to cut from is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index. 6 | * @param {Number} left - position of left most point of the center patch 7 | * @param {Number} right - position of right most point of the center patch 8 | * @param {Number} top - position of top most point of the center patch 9 | * @param {Number} bottom - position of bottom most point of the center patch 10 | */ 11 | constructor(game, imageKey, imageFrame, left, right, top, bottom) { 12 | this.game = game; 13 | this.imageKey = imageKey; 14 | this.imageFrame = imageFrame; 15 | this.left = left; 16 | this.right = right; 17 | this.top = top; 18 | this.bottom = bottom; 19 | /** @type {Array} The 3x3 Texture Array that would be generated for the 9 patches */ 20 | this.textures = [[], [], []]; 21 | /** Image Cache - Support for earlier version of Phaser */ 22 | let _images = game.cache._images || game.cache._cache.image; 23 | let imageCache = _images[imageKey]; 24 | /** @type {PIXI.BaseTexture} Get the Base Texture to process */ 25 | this.baseTexture = PIXI.BaseTextureCache[imageKey] ? PIXI.BaseTextureCache[imageKey] : imageCache.base; 26 | /** @type {Number} Positions and measures of the texture on the base texture */ 27 | if (imageFrame) { 28 | let frameData = imageCache.frameData; 29 | let frame = frameData._frames[frameData._frameNames[imageFrame]]; 30 | this.x = frame.x; 31 | this.y = frame.y; 32 | this.width = frame.width; 33 | this.height = frame.height; 34 | } else { 35 | /** The texture would cover the entire base texture if it isn't a part of a sprite sheet or texture atlas */ 36 | this.x = 0; 37 | this.y = 0; 38 | this.width = this.baseTexture.width; 39 | this.height = this.baseTexture.height; 40 | } 41 | /** Process the data */ 42 | this.CreateFrameData(); 43 | } 44 | /** Generate the textures */ 45 | CreateFrameData() { 46 | var {imageKey, baseTexture, textures} = this; 47 | /** Calculate the position of each patch relative to the texture */ 48 | var dimensions = this.CreateDimensionMap(); 49 | /** Offset by the position of the frame */ 50 | if (this.imageFrame !== undefined) { 51 | for (let i = 2; i >= 0; i--) { 52 | for (let j = 2; j >= 0; j--) { 53 | let item = dimensions[i][j]; 54 | item.x += this.x; 55 | item.y += this.y; 56 | }; 57 | }; 58 | } 59 | /** Generate the textures by cutting from the base texture */ 60 | for (let i = 0; i < 3; i++) { 61 | for (let j = 0; j < 3; j++) { 62 | this.textures[i][j] = new PIXI.Texture(baseTexture, dimensions[i][j]); 63 | } 64 | } 65 | } 66 | /** 67 | * Get the position of each patch based on the measures specified 68 | * @param {Number} width = this.width 69 | * @param {Number} height = this.height 70 | * @return {Array} The positions array mapped with the patches 71 | */ 72 | CreateDimensionMap(width = this.width, height = this.height) { 73 | var {left, right, top, bottom} = this; 74 | /** position of the patches in the middle (horizontally and vertically) */ 75 | var midH = width - left - right; 76 | var midV = height - top - bottom; 77 | /** 78 | * @type {Array} The positions array mapped with the patches 79 | * Would be returned at the end of this function 80 | */ 81 | var dimensions = [ [], [], [] ]; 82 | /** Set positions for each patch and record in the dimensions*/ 83 | for (let i = 2; i >= 0; i--) { 84 | for (let j = 2; j >= 0; j--) { 85 | let item = dimensions[i][j] = {}; 86 | switch (i) { 87 | case 0: 88 | item.height = top; 89 | item.y = 0; 90 | break; 91 | case 1: 92 | item.height = midV; 93 | item.y = top; 94 | break; 95 | case 2: 96 | item.height = bottom; 97 | item.y = top + midV; 98 | break; 99 | } 100 | switch (j) { 101 | case 0: 102 | item.width = left; 103 | item.x = 0; 104 | break; 105 | case 1: 106 | item.width = midH; 107 | item.x = left; 108 | break; 109 | case 2: 110 | item.width = right; 111 | item.x = left + midH; 112 | break; 113 | } 114 | }; 115 | }; 116 | 117 | return dimensions; 118 | } 119 | /** */ 120 | /** 121 | * Generate patch images 122 | * @param {DisplayObject}[Optional] Either a Phaser.Group or a Phaser.Image/Sprite/... that would contain these images 123 | * @return {Array} 3x3 Array of Phaser.Image for the patches 124 | */ 125 | CreateImages(parent) { 126 | var textures = this.textures; 127 | /** @type {Array} The returned array */ 128 | var images = [ [], [], [] ]; 129 | for (let i = 0; i < 3; i++) { 130 | for (let j = 0; j < 3; j++) { 131 | /** @type {Phaser.Image} The generated image */ 132 | let image = images[i][j] = this.game.add.image(0, 0, textures[i][j]); 133 | /** Add the image to parent */ 134 | if (parent) { 135 | /** TODO: Write an isFunction check */ 136 | if (parent.add) parent.add(image); 137 | else if (parent.addChild) parent.addChild(image); 138 | } 139 | } 140 | } 141 | return images; 142 | } 143 | } -------------------------------------------------------------------------------- /example/nine-patch-phaser-plugin/nine-patch-phaser-plugin.js: -------------------------------------------------------------------------------- 1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= 0; i--) { 73 | for (var j = 2; j >= 0; j--) { 74 | var item = dimensions[i][j]; 75 | item.x += this.x; 76 | item.y += this.y; 77 | }; 78 | }; 79 | } 80 | /** Generate the textures by cutting from the base texture */ 81 | for (var i = 0; i < 3; i++) { 82 | for (var j = 0; j < 3; j++) { 83 | this.textures[i][j] = new PIXI.Texture(baseTexture, dimensions[i][j]); 84 | } 85 | } 86 | } 87 | 88 | /** 89 | * Get the position of each patch based on the measures specified 90 | * @param {Number} width = this.width 91 | * @param {Number} height = this.height 92 | * @return {Array} The positions array mapped with the patches 93 | */ 94 | }, { 95 | key: "CreateDimensionMap", 96 | value: function CreateDimensionMap() { 97 | var width = arguments.length <= 0 || arguments[0] === undefined ? this.width : arguments[0]; 98 | var height = arguments.length <= 1 || arguments[1] === undefined ? this.height : arguments[1]; 99 | var left = this.left; 100 | var right = this.right; 101 | var top = this.top; 102 | var bottom = this.bottom; 103 | 104 | /** position of the patches in the middle (horizontally and vertically) */ 105 | var midH = width - left - right; 106 | var midV = height - top - bottom; 107 | /** 108 | * @type {Array} The positions array mapped with the patches 109 | * Would be returned at the end of this function 110 | */ 111 | var dimensions = [[], [], []]; 112 | /** Set positions for each patch and record in the dimensions*/ 113 | for (var i = 2; i >= 0; i--) { 114 | for (var j = 2; j >= 0; j--) { 115 | var item = dimensions[i][j] = {}; 116 | switch (i) { 117 | case 0: 118 | item.height = top; 119 | item.y = 0; 120 | break; 121 | case 1: 122 | item.height = midV; 123 | item.y = top; 124 | break; 125 | case 2: 126 | item.height = bottom; 127 | item.y = top + midV; 128 | break; 129 | } 130 | switch (j) { 131 | case 0: 132 | item.width = left; 133 | item.x = 0; 134 | break; 135 | case 1: 136 | item.width = midH; 137 | item.x = left; 138 | break; 139 | case 2: 140 | item.width = right; 141 | item.x = left + midH; 142 | break; 143 | } 144 | }; 145 | }; 146 | 147 | return dimensions; 148 | } 149 | 150 | /** */ 151 | /** 152 | * Generate patch images 153 | * @param {DisplayObject}[Optional] Either a Phaser.Group or a Phaser.Image/Sprite/... that would contain these images 154 | * @return {Array} 3x3 Array of Phaser.Image for the patches 155 | */ 156 | }, { 157 | key: "CreateImages", 158 | value: function CreateImages(parent) { 159 | var textures = this.textures; 160 | /** @type {Array} The returned array */ 161 | var images = [[], [], []]; 162 | for (var i = 0; i < 3; i++) { 163 | for (var j = 0; j < 3; j++) { 164 | /** @type {Phaser.Image} The generated image */ 165 | var image = images[i][j] = this.game.add.image(0, 0, textures[i][j]); 166 | /** Add the image to parent */ 167 | if (parent) { 168 | /** TODO: Write an isFunction check */ 169 | if (parent.add) parent.add(image);else if (parent.addChild) parent.addChild(image); 170 | } 171 | } 172 | } 173 | return images; 174 | } 175 | }]); 176 | 177 | return NinePatchCache; 178 | })(); 179 | 180 | exports["default"] = NinePatchCache; 181 | module.exports = exports["default"]; 182 | 183 | },{}],2:[function(require,module,exports){ 184 | /** 185 | * Return true if value is a String 186 | * TODO: Use a better method to prevent error 187 | */ 188 | 'use strict'; 189 | 190 | Object.defineProperty(exports, '__esModule', { 191 | value: true 192 | }); 193 | 194 | var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); 195 | 196 | var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; 197 | 198 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 199 | 200 | function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 201 | 202 | function isString(value) { 203 | return typeof value === 'string'; 204 | } 205 | 206 | var NinePatchImage = (function (_Phaser$Image) { 207 | _inherits(NinePatchImage, _Phaser$Image); 208 | 209 | /** 210 | * @param {Phaser.Game} game - REF Phaser.Image params 211 | * @param {Number} x = 0 - REF Phaser.Image params 212 | * @param {Number} y = 0 - REF Phaser.Image params 213 | * @param {String || NinePatchCache} key - The NinePatchCache used by the NinePatchImage. It can be a string which is a reference to the Cache entry, or an instance of a NinePatchCache. 214 | * @param {NinePatchCache} ninePatchImages - To be deprecated. 215 | */ 216 | 217 | function NinePatchImage(game, x, y, key, ninePatchImages) { 218 | if (x === undefined) x = 0; 219 | if (y === undefined) y = 0; 220 | 221 | _classCallCheck(this, NinePatchImage); 222 | 223 | _get(Object.getPrototypeOf(NinePatchImage.prototype), 'constructor', this).call(this, game, x, y); 224 | game.add.existing(this); 225 | /** Get the NinePatchCache instance */ 226 | if (!ninePatchImages) { 227 | if (typeof key == 'string') { 228 | ninePatchImages = game.cache.getNinePatch(key); 229 | } else if (true /** Check if key is an instance of NinePatchCache */) { 230 | ninePatchImages = key; 231 | } else throw new Error('NinePatchImage key must be a String or an instance of NinePatchCache'); 232 | } 233 | this.ninePatchImages = ninePatchImages; 234 | /** @type {Array} Generate 9 instances of Phaser.Image as the children of this */ 235 | this.images = ninePatchImages.CreateImages(this); 236 | /** Setting measures for this */ 237 | this.currentWidth = ninePatchImages.width; 238 | this.currentHeight = ninePatchImages.height; 239 | /** Update images' positions */ 240 | this.UpdateImageSizes(); 241 | } 242 | 243 | /** Get/Set for measures to update images' positions on chagnges */ 244 | 245 | _createClass(NinePatchImage, [{ 246 | key: 'UpdateImageSizes', 247 | 248 | /** Update images' positions to match the new measures */ 249 | value: function UpdateImageSizes() { 250 | var ninePatchImages = this.ninePatchImages; 251 | var currentWidth = this.currentWidth; 252 | var currentHeight = this.currentHeight; 253 | var images = this.images; 254 | var anchor = this.anchor; 255 | 256 | /** Get the positions for the new measures */ 257 | var dimensions = ninePatchImages.CreateDimensionMap(currentWidth, currentHeight); 258 | /** Calculate the padding to match the anchor */ 259 | var paddingX = anchor.x * currentWidth; 260 | var paddingY = anchor.y * currentHeight; 261 | /** Loop through all images and update the positions */ 262 | for (var i = 0; i < 3; i++) { 263 | for (var j = 0; j < 3; j++) { 264 | var image = images[i][j]; 265 | var dimension = dimensions[i][j]; 266 | image.x = dimension.x - paddingX; 267 | image.y = dimension.y - paddingY; 268 | image.width = dimension.width; 269 | image.height = dimension.height; 270 | } 271 | } 272 | } 273 | }, { 274 | key: 'targetWidth', 275 | get: function get() { 276 | return this.currentWidth; 277 | }, 278 | set: function set(value) { 279 | this.currentWidth = value; 280 | this.UpdateImageSizes(); 281 | } 282 | }, { 283 | key: 'targetHeight', 284 | get: function get() { 285 | return this.currentHeight; 286 | }, 287 | set: function set(value) { 288 | this.currentHeight = value; 289 | this.UpdateImageSizes(); 290 | } 291 | }]); 292 | 293 | return NinePatchImage; 294 | })(Phaser.Image); 295 | 296 | exports['default'] = NinePatchImage; 297 | module.exports = exports['default']; 298 | 299 | },{}],3:[function(require,module,exports){ 300 | var NinePatchCache = require('./NinePatchCache'); 301 | /** 302 | * This function should be called when the image/spritesheet/texture has been loaded 303 | * @param {String} name - the key to refer to the created NinePatchCache 304 | * @param {String} imageKey - REF NinePatchCache 305 | * @param {String} imageFrame - REF NinePatchCache 306 | * @param {Number} left - REF NinePatchCache 307 | * @param {Number} right - REF NinePatchCache 308 | * @param {Number} top - REF NinePatchCache 309 | * @param {Number} bottom - REF NinePatchCache 310 | */ 311 | Phaser.Cache.prototype.addNinePatch = function addNinePatch(name, imageKey, imageFrame, left, right, top, bottom){ 312 | var _ninePatches = this._ninePatches = this._ninePatches || {}; 313 | _ninePatches[name] = new NinePatchCache(this.game, imageKey, imageFrame, left, right, top, bottom); 314 | console.log(_ninePatches) 315 | } 316 | /** Return an instance of NinePatchCache match with the name */ 317 | Phaser.Cache.prototype.getNinePatch = function getNinePatch(name) { 318 | var _ninePatches = this._ninePatches = this._ninePatches || {}; 319 | return _ninePatches[name]; 320 | } 321 | Phaser.NinePatchImage = require('./NinePatchImage'); 322 | },{"./NinePatchCache":1,"./NinePatchImage":2}]},{},[3]); 323 | --------------------------------------------------------------------------------