├── .eslintrc.json ├── LICENSE ├── README.md ├── main.js └── package.json /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint:recommended", 3 | "rules": { 4 | "comma-dangle": 0, 5 | "no-console": 0, 6 | "no-constant-condition": 0, 7 | "quotes": ["warn", "single"], 8 | "semi": 1 9 | }, 10 | "parserOptions": { 11 | "ecmaVersion": 6, 12 | "ecmaFeatures": { 13 | "jsx": true 14 | } 15 | }, 16 | "env": { 17 | "browser": true, 18 | "node": true, 19 | "es6": true, 20 | "mocha": true 21 | }, 22 | "plugins": [ 23 | ], 24 | "globals": { 25 | "tap": false, 26 | "unused": false, 27 | "Editor": false, 28 | "Helper": false, 29 | "Vue": false, 30 | "Polymer": false, 31 | "expect": false, 32 | "sinon": false, 33 | "assert": false, 34 | "_Scene": false, 35 | "cc": false, 36 | "CC_EDITOR": false, 37 | "CC_TEST": false 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | zilongshanren https://zilongshanren.com 2 | 3 | Copyright (c) 2016-2017 - zilongshanren 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 13 | all 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 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Cocos Creator Unpack TextureAtlas Plugin 2 | === 3 | 4 | This is a tiny package for unpacking TexturePacker assets in Cocos Creator. 5 | 6 | ## Installation 7 | Please refer to [The official docs](https://github.com/cocos-creator/creator-docs/blob/master/source/en/extension/install-and-share.md ). 8 | 9 | 10 | ### Requirements 11 | - Cocos Creator v1.3+ 12 | 13 | ## How to use 14 | - Select a **TexturePacker assets** in the **assets** Panel of Cocos Creator. (The TexturePacker assets is the imported **plist** file). 15 | - Choose "unpack" menu item from the main menu **Packages/unpack-textureatlas**. 16 | - Enjoy. 17 | 18 | ## Limitations 19 | - The texture atlas exported by TexturePacker with triangular information could not be extractd successfully. 20 | 21 | ## License 22 | [MIT](./LICENSE) 23 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | Copyright (c) 2016-2017 zilongshanren 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | ****************************************************************************/ 22 | 23 | 'use strict'; 24 | const Fs = require('fire-fs'); 25 | const Path = require('fire-path'); 26 | const Async = require('async'); 27 | const Del = require('del'); 28 | 29 | let sharpPath; 30 | if (Editor.dev) { 31 | sharpPath = 'sharp'; 32 | } else { 33 | sharpPath = Editor.url('unpack://utils/sharp'); 34 | } 35 | const Sharp = require(sharpPath); 36 | 37 | const dontSelectCorrectAssetMsg = { 38 | type: 'warning', 39 | buttons: ['OK'], 40 | titile: 'Unpack Texture Packer Atlas', 41 | message: 'Please select a Texture Packer asset at first!', 42 | defaultId: 0, 43 | noLink: true 44 | }; 45 | 46 | module.exports = { 47 | load () { 48 | // execute when package loaded 49 | }, 50 | 51 | unload () { 52 | // execute when package unloaded 53 | }, 54 | 55 | // register your ipc messages here 56 | messages: { 57 | 'unpack' () { 58 | Editor.Metrics.trackEvent({ 59 | category: 'Packages', 60 | label: 'unpack-textureatlas', 61 | action: 'Open By Menu' 62 | }, null); 63 | 64 | let currentSelection = Editor.Selection.curSelection('asset'); 65 | if (currentSelection.length > 0) { 66 | let selectionUUid = currentSelection[0]; 67 | let selectionMeta = Editor.assetdb.loadMetaByUuid(selectionUUid); 68 | let selectionUrl = Editor.assetdb.uuidToUrl(selectionUUid); 69 | let assetInfo = Editor.assetdb.assetInfoByUuid(selectionUUid); 70 | const textureAtlasPath = Editor.assetdb.uuidToFspath(selectionMeta.rawTextureUuid); 71 | 72 | 73 | if (!textureAtlasPath) { 74 | Editor.Dialog.messageBox(dontSelectCorrectAssetMsg); 75 | return; 76 | } 77 | let textureAtlasSubMetas = selectionMeta.getSubMetas(); 78 | 79 | if (assetInfo.type === 'sprite-atlas' 80 | && selectionMeta.type === 'Texture Packer' 81 | && textureAtlasSubMetas) { 82 | // In Creator Editor version 2.2.2,use Editor.Project.path 83 | let extractedImageSaveFolder = Path.join(Editor.Project.path, 'temp', Path.basenameNoExt(textureAtlasPath) + '_unpack'); 84 | Fs.mkdirsSync(extractedImageSaveFolder); 85 | 86 | let spriteFrameNames = Object.keys(textureAtlasSubMetas); 87 | Async.forEach(spriteFrameNames, function (spriteFrameName, next) { 88 | let spriteFrameObj = textureAtlasSubMetas[spriteFrameName]; 89 | let isRotated = spriteFrameObj.rotated; 90 | let originalSize = cc.size(spriteFrameObj.rawWidth, spriteFrameObj.rawHeight); 91 | let rect = cc.rect(spriteFrameObj.trimX, spriteFrameObj.trimY, spriteFrameObj.width,spriteFrameObj.height); 92 | let offset = cc.p(spriteFrameObj.offsetX, spriteFrameObj.offsetY); 93 | let trimmedLeft = Math.ceil(offset.x + (originalSize.width - rect.width) / 2); 94 | let trimmedRight = Math.ceil((originalSize.width - rect.width) / 2 - offset.x); 95 | let trimmedTop = Math.ceil((originalSize.height - rect.height) / 2 - offset.y); 96 | let trimmedBottom = Math.ceil(offset.y + (originalSize.height - rect.height) / 2); 97 | 98 | let sharpCallback = (err) => { 99 | if (err) { 100 | Editor.error('Generating ' + spriteFrameName + ' error occurs, details:' + err); 101 | } 102 | 103 | Editor.log(spriteFrameName + ' is generated successfully!'); 104 | next(); 105 | }; 106 | 107 | let extractedSmallPngSavePath = Path.join(extractedImageSaveFolder, spriteFrameName); 108 | if (isRotated) { 109 | 110 | Sharp(textureAtlasPath).extract({left: rect.x, top: rect.y, width: rect.height, height:rect.width}) 111 | // .background('rgba(0,0,0,0)') 112 | .extend({top: trimmedTop, bottom: trimmedBottom, left: trimmedLeft, right: trimmedRight}) 113 | .rotate(270) 114 | .toFile(extractedSmallPngSavePath, sharpCallback); 115 | 116 | } else { 117 | Sharp(textureAtlasPath).extract({left: rect.x, top: rect.y, width: rect.width, height:rect.height}) 118 | // .background('rgba(0,0,0,0)') -- In Creator Editor version 2.2.2,background is undefined 119 | .extend({top: trimmedTop, bottom: trimmedBottom, left: trimmedLeft, right: trimmedRight}) 120 | .rotate(0) 121 | .toFile(extractedSmallPngSavePath, sharpCallback); 122 | } 123 | }, () => { 124 | Editor.log(`There are ${spriteFrameNames.length} textures are generated!`); 125 | //start importing the generated textures folder 126 | Editor.Ipc.sendToMain( 'asset-db:import-assets', [extractedImageSaveFolder], Path.dirname(selectionUrl), true, (err) => { 127 | if (err) Editor.log('Importing assets error occurs: details' + err); 128 | 129 | Del(extractedImageSaveFolder, { force: true }); 130 | }, -1); 131 | 132 | }); // end of Async.forEach 133 | 134 | } else { 135 | Editor.Dialog.messageBox(dontSelectCorrectAssetMsg); 136 | } 137 | } else { 138 | Editor.Dialog.messageBox(dontSelectCorrectAssetMsg); 139 | } 140 | }, 141 | }, 142 | }; 143 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "unpack-textureatlas", 3 | "version": "0.0.1", 4 | "description": "A package for unpacking texture atlas created with TexturePacker.", 5 | "author": "zilongshanren", 6 | "main": "main.js", 7 | "main-menu": { 8 | "i18n:MAIN_MENU.package.title/unpack-textureatlas/unpack": { 9 | "message": "unpack-textureatlas:unpack" 10 | } 11 | } 12 | } 13 | --------------------------------------------------------------------------------