var CanvasPool = require('../display/canvas/CanvasPool'); var CanvasTexture = require('./CanvasTexture'); var Class = require('../utils/Class'); var Color = require('../display/color/Color'); var CONST = require('../const'); var EventEmitter = require('eventemitter3'); var Events = require('./events'); var GameEvents = require('../core/events'); var GenerateTexture = require('../create/GenerateTexture'); var GetValue = require('../utils/object/GetValue'); var Parser = require('./parsers'); var Texture = require('./Texture'); var TextureManager = new Class({ Extends: EventEmitter, initialize: function TextureManager(game){ EventEmitter.call(this); this.game = game; this.name = 'TextureManager'; this.list = { } ; this._tempCanvas = CanvasPool.create2D(this, 1, 1); this._tempContext = this._tempCanvas.getContext('2d'); this._pending = 0; game.events.once(GameEvents.BOOT, this.boot, this); } , boot: function (){ this._pending = 2; this.on(Events.LOAD, this.updatePending, this); this.on(Events.ERROR, this.updatePending, this); this.addBase64('__DEFAULT', this.game.config.defaultImage); this.addBase64('__MISSING', this.game.config.missingImage); this.game.events.once(GameEvents.DESTROY, this.destroy, this); } , updatePending: function (){ this._pending-- ; if (this._pending === 0) { this.off(Events.LOAD); this.off(Events.ERROR); this.emit(Events.READY); } } , checkKey: function (key){ if (this.exists(key)) { console.error('Texture key already in use: ' + key); return false ; } return true ; } , remove: function (key){ if (typeof key === 'string') { if (this.exists(key)) { key = this.get(key); } else { console.warn('No texture found matching key: ' + key); return this; } } if (this.list.hasOwnProperty(key.key)) { key.destroy(); this.emit(Events.REMOVE, key.key); } return this; } , removeKey: function (key){ if (this.list.hasOwnProperty(key)) { delete this.list[key]; } return this; } , addBase64: function (key, data){ if (this.checkKey(key)) { var _this = this; var image = new Image(); image.onerror = function (){ _this.emit(Events.ERROR, key); } ; image.onload = function (){ var texture = _this.create(key, image); Parser.Image(texture, 0); _this.emit(Events.ADD, key, texture); _this.emit(Events.LOAD, key, texture); } ; _AN_Write_src('src', image, false , data); } return this; } , getBase64: function (key, frame, type, encoderOptions){ if (type === undefined) { type = 'image/png'; } if (encoderOptions === undefined) { encoderOptions = 0.92; } var data = ''; var textureFrame = this.getFrame(key, frame); if (textureFrame && (textureFrame.source.isRenderTexture || textureFrame.source.isGLTexture)) { console.warn('Cannot getBase64 from WebGL Texture'); } else if (textureFrame) { var cd = textureFrame.canvasData; var canvas = CanvasPool.create2D(this, cd.width, cd.height); var ctx = canvas.getContext('2d'); ctx.drawImage(textureFrame.source.image, cd.x, cd.y, cd.width, cd.height, 0, 0, cd.width, cd.height); data = canvas.toDataURL(type, encoderOptions); CanvasPool.remove(canvas); } return data; } , addImage: function (key, source, dataSource){ var texture = null ; if (this.checkKey(key)) { texture = this.create(key, source); Parser.Image(texture, 0); if (dataSource) { texture.setDataSource(dataSource); } this.emit(Events.ADD, key, texture); } return texture; } , addGLTexture: function (key, glTexture, width, height){ var texture = null ; if (this.checkKey(key)) { texture = this.create(key, glTexture, width, height); texture.add('__BASE', 0, 0, 0, width, height); this.emit(Events.ADD, key, texture); } return texture; } , addRenderTexture: function (key, renderTexture){ var texture = null ; if (this.checkKey(key)) { texture = this.create(key, renderTexture); texture.add('__BASE', 0, 0, 0, renderTexture.width, renderTexture.height); this.emit(Events.ADD, key, texture); } return texture; } , generate: function (key, config){ if (this.checkKey(key)) { var canvas = CanvasPool.create(this, 1, 1); config.canvas = canvas; GenerateTexture(config); return this.addCanvas(key, canvas); } else { return null ; } } , createCanvas: function (key, width, height){ if (width === undefined) { width = 256; } if (height === undefined) { height = 256; } if (this.checkKey(key)) { var canvas = CanvasPool.create(this, width, height, CONST.CANVAS, true ); return this.addCanvas(key, canvas); } return null ; } , addCanvas: function (key, source, skipCache){ if (skipCache === undefined) { skipCache = false ; } var texture = null ; if (skipCache) { texture = new CanvasTexture(this, key, source, source.width, source.height); } else if (this.checkKey(key)) { texture = new CanvasTexture(this, key, source, source.width, source.height); this.list[key] = texture; this.emit(Events.ADD, key, texture); } return texture; } , addAtlas: function (key, source, data, dataSource){ if (Array.isArray(data.textures) || Array.isArray(data.frames)) { return this.addAtlasJSONArray(key, source, data, dataSource); } else { return this.addAtlasJSONHash(key, source, data, dataSource); } } , addAtlasJSONArray: function (key, source, data, dataSource){ var texture = null ; if (this.checkKey(key)) { texture = this.create(key, source); if (Array.isArray(data)) { var singleAtlasFile = (_AN_Read_length('length', data) === 1); for (var i = 0; i < (_AN_Read_length('length', texture.source)); i++ ){ var atlasData = singleAtlasFile? data[0]: data[i]; Parser.JSONArray(texture, i, atlasData); } } else { Parser.JSONArray(texture, 0, data); } if (dataSource) { texture.setDataSource(dataSource); } this.emit(Events.ADD, key, texture); } return texture; } , addAtlasJSONHash: function (key, source, data, dataSource){ var texture = null ; if (this.checkKey(key)) { texture = this.create(key, source); if (Array.isArray(data)) { for (var i = 0; i < (_AN_Read_length('length', data)); i++ ){ Parser.JSONHash(texture, i, data[i]); } } else { Parser.JSONHash(texture, 0, data); } if (dataSource) { texture.setDataSource(dataSource); } this.emit(Events.ADD, key, texture); } return texture; } , addAtlasXML: function (key, source, data, dataSource){ var texture = null ; if (this.checkKey(key)) { texture = this.create(key, source); Parser.AtlasXML(texture, 0, data); if (dataSource) { texture.setDataSource(dataSource); } this.emit(Events.ADD, key, texture); } return texture; } , addUnityAtlas: function (key, source, data, dataSource){ var texture = null ; if (this.checkKey(key)) { texture = this.create(key, source); Parser.UnityYAML(texture, 0, data); if (dataSource) { texture.setDataSource(dataSource); } this.emit(Events.ADD, key, texture); } return texture; } , addSpriteSheet: function (key, source, config){ var texture = null ; if (this.checkKey(key)) { texture = this.create(key, source); var width = texture.source[0].width; var height = texture.source[0].height; Parser.SpriteSheet(texture, 0, 0, 0, width, height, config); this.emit(Events.ADD, key, texture); } return texture; } , addSpriteSheetFromAtlas: function (key, config){ if (!this.checkKey(key)) { return null ; } var atlasKey = GetValue(config, 'atlas', null ); var atlasFrame = GetValue(config, 'frame', null ); if (!atlasKey || !atlasFrame) { return ; } var atlas = this.get(atlasKey); var sheet = atlas.get(atlasFrame); if (sheet) { var texture = this.create(key, sheet.source.image); if (sheet.trimmed) { Parser.SpriteSheetFromAtlas(texture, sheet, config); } else { Parser.SpriteSheet(texture, 0, sheet.cutX, sheet.cutY, sheet.cutWidth, sheet.cutHeight, config); } this.emit(Events.ADD, key, texture); return texture; } } , create: function (key, source, width, height){ var texture = null ; if (this.checkKey(key)) { texture = new Texture(this, key, source, width, height); this.list[key] = texture; } return texture; } , exists: function (key){ return (this.list.hasOwnProperty(key)); } , get: function (key){ if (key === undefined) { key = '__DEFAULT'; } if (this.list[key]) { return this.list[key]; } else if (key instanceof Texture) { return key; } else { return this.list.__MISSING; } } , cloneFrame: function (key, frame){ if (this.list[key]) { return this.list[key].get(frame).clone(); } } , getFrame: function (key, frame){ if (this.list[key]) { return this.list[key].get(frame); } } , getTextureKeys: function (){ var output = [] ; for (var key in this.list){ if (key !== '__DEFAULT' && key !== '__MISSING') { output.push(key); } } return output; } , getPixel: function (x, y, key, frame){ var textureFrame = this.getFrame(key, frame); if (textureFrame) { x -= textureFrame.x; y -= textureFrame.y; var data = textureFrame.data.cut; x += data.x; y += data.y; if (x >= data.x && x < data.r && y >= data.y && y < data.b) { var ctx = this._tempContext; ctx.clearRect(0, 0, 1, 1); ctx.drawImage(textureFrame.source.image, x, y, 1, 1, 0, 0, 1, 1); var rgb = ctx.getImageData(0, 0, 1, 1); return new Color(rgb.data[0], rgb.data[1], rgb.data[2], rgb.data[3]); } } return null ; } , getPixelAlpha: function (x, y, key, frame){ var textureFrame = this.getFrame(key, frame); if (textureFrame) { x -= textureFrame.x; y -= textureFrame.y; var data = textureFrame.data.cut; x += data.x; y += data.y; if (x >= data.x && x < data.r && y >= data.y && y < data.b) { var ctx = this._tempContext; ctx.clearRect(0, 0, 1, 1); ctx.drawImage(textureFrame.source.image, x, y, 1, 1, 0, 0, 1, 1); var rgb = ctx.getImageData(0, 0, 1, 1); return rgb.data[3]; } } return null ; } , setTexture: function (gameObject, key, frame){ if (this.list[key]) { gameObject.texture = this.list[key]; gameObject.frame = gameObject.texture.get(frame); } return gameObject; } , renameTexture: function (currentKey, newKey){ var texture = this.get(currentKey); if (texture && currentKey !== newKey) { texture.key = newKey; this.list[newKey] = texture; delete this.list[currentKey]; return true ; } return false ; } , each: function (callback, scope){ var args = [null ] ; for (var i = 1; i < (_AN_Read_length('length', arguments)); i++ ){ args.push(arguments[i]); } for (var texture in this.list){ args[0] = this.list[texture]; callback.apply(scope, args); } } , destroy: function (){ for (var texture in this.list){ this.list[texture].destroy(); } this.list = { } ; this.game = null ; CanvasPool.remove(this._tempCanvas); } } ); module.exports = TextureManager;