├── .gitignore ├── .npm └── plugin │ └── generateAssets │ ├── .gitignore │ ├── README │ └── npm-shrinkwrap.json ├── package.js ├── README.md └── assets.js /.gitignore: -------------------------------------------------------------------------------- 1 | .versions 2 | -------------------------------------------------------------------------------- /.npm/plugin/generateAssets/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.npm/plugin/generateAssets/README: -------------------------------------------------------------------------------- 1 | This directory and the files immediately inside it are automatically generated 2 | when you change this package's NPM dependencies. Commit the files in this 3 | directory (npm-shrinkwrap.json, .gitignore, and this README) to source control 4 | so that others run the same versions of sub-dependencies. 5 | 6 | You should NOT check in the node_modules directory that Meteor automatically 7 | creates; if you are using git, the .gitignore file tells git to ignore it. 8 | -------------------------------------------------------------------------------- /package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'poetic:assets', 3 | version: '0.0.3', 4 | summary: 'TiCons wrapper for automatically generating icon and splash screen assets', 5 | git: 'https://github.com/poetic/assets', 6 | documentation: 'README.md' 7 | }); 8 | 9 | Package.onUse(function (api) { 10 | api.use('isobuild:compiler-plugin@1.0.0'); 11 | }); 12 | 13 | Package.registerBuildPlugin({ 14 | name: 'generateAssets', 15 | sources: ['assets.js'], 16 | npmDependencies: { 17 | 'fs-extra': '0.24.0', 18 | 'ticons': '0.15.3' 19 | } 20 | }); 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Assets 2 | 3 | Automatically generates icons and splash screen assets. 4 | 5 | ### Installation 6 | 7 | `$ meteor add poetic:assets` 8 | 9 | ### Configuration 10 | 11 | ###### How to Use: 12 | Before running your meteor app add any launch/splash screen images and app icons to the root directory of your folder. App icons should be named icon.png and launch/splash screen images should be named splash.png. Check requirements for iOS icons below. Once the files are generated the package will no longer generate new icons or splash images in order to speed up meteor configuration at startup. 13 | 14 | ###### File Structure: 15 | ``` 16 | Sample Project 17 | └───client 18 | └───server 19 | └───lib 20 | └───public 21 | └───private 22 | └───assets 23 | └───icons 24 | │ icon.png 25 | etc. 26 | └───splash 27 | │ splash.png 28 | etc. 29 | ``` 30 | 31 | ### Mobile 32 | When running your meteor project on an ios simulator simply set up your `mobile-config.js` to show both app icons and launch screens at launch. Check out [meteor documentation](http://docs.meteor.com/#/full/mobileconfigjs) to make sure your mobile-config.js file is set up properly. The generated images should include all those needed for each iPhone size. Check out the size guide below for further reference. 33 | ###### App Icons: private/assets/icon 34 | 35 | ``` 36 | iPhone: 60 X 60: appicon-60.png 37 | iPhone: 120 X 120: appicon-60@2x.png 38 | iPhone: 180 X 180: appicon-60@3x.png 39 | iPad: 76 X 76: appicon-76.png 40 | iPad: 152 X 152: appicon-76@2x.png 41 | android_ldpi: drawable-ldpi.png 42 | android_mdpi: drawable-mdpi.png 43 | android_hdpi: drawable-hdpi.png 44 | android_xhdpi: drawable-xhdpi.png 45 | ``` 46 | ###### Launch Screens: private/assets/splash 47 | ``` 48 | iPhone: Default.png 49 | iPhone_2x: Default@2x.png 50 | iPhone5: Default-568h@2x.png 51 | iPhone6: Default-667h@2x.png 52 | iPhone6p_portrait: Default-Portrait-736h@3x.png 53 | iPad Portrait: 768 X 1004: ios-Default-Portrait.png 54 | iPad Portrait: 1536 X 2008: ios-Default-Portrait@2x.png 55 | iPad Landscape: 1024 X 748: ios-Default-Landscape 56 | iPad Landscape: 2048 X 1496: ios-Default-Landscape@2x 57 | android_ldpi_portrait: drawable-ldpi.png 58 | android_mdpi_portrait: drawable-mdpi.png 59 | android_hdpi_portrait: drawable-hdpi.png 60 | android_xhdpi_portrait: drawablexhhdpi.png 61 | ``` 62 | 63 | 64 | ### Installation Cont. 65 | ###### iOS Icons 66 | For the best result png image must first be in the shape of a square, same width and height, and no smaller than 180 x 180 (1024 x 1024 recommended). 67 | 68 | ###### Splash Images 69 | Splash screen sizes should correspond to the density and generalized size of the user's display. For best results use a square image of 1600x1600 pixels that includes the minimal amount of padding, making sure that the outer most pixels are all of the same color. The logo should generally be placed in the middle of the image for the best look. 70 | 71 | *This packages uses the npm package [TIcons](https://github.com/FokkeZB/TiCons-CLI). 72 | -------------------------------------------------------------------------------- /assets.js: -------------------------------------------------------------------------------- 1 | var fs = Npm.require('fs-extra'), 2 | path = Npm.require('path'), 3 | ticons = Npm.require('ticons'); 4 | 5 | 6 | Plugin.registerCompiler({ 7 | filenames: ['icon.png', 'splash.png'] 8 | }, function () { 9 | var compiler = new AssetsCompiler(); 10 | return compiler; 11 | }); 12 | 13 | function AssetsCompiler() {} 14 | 15 | AssetsCompiler.prototype.processFilesForTarget = function (files) { 16 | 17 | fs.lstat('private/assets/', function(err, stats){ 18 | if(err){ 19 | files.forEach(function (file) { 20 | var baseDir = process.env.PWD; 21 | var assetsDir = path.join(process.env.PWD, 'private/assets'); 22 | var cacheDir = path.join(baseDir, '.meteor/local/assets'); 23 | var fileName = file.getBasename(); 24 | var fileType = null; 25 | var type = null; 26 | 27 | if (fileName === 'splash.png') { 28 | fileType = 'splashes'; 29 | cacheDir = path.join(cacheDir, 'splash'); 30 | 31 | } else if (fileName === 'icon.png') { 32 | fileType = 'icons'; 33 | cacheDir = path.join(cacheDir, 'icons'); 34 | } 35 | 36 | ticons[fileType]({ 37 | input: fileName, 38 | outputDir: cacheDir, 39 | platforms: ['iphone','ipad','android'], 40 | sdkVersion: '4.0.0', 41 | }, function (err, output) { 42 | if (err) { 43 | throw err; 44 | } 45 | 46 | var filesToCopy; 47 | switch(fileType){ 48 | case 'splashes': 49 | filesToCopy = { 50 | 'Resources/iPhone': 'splash', 51 | 'platform/android/res/drawable-hdpi/background.9.png': 'splash/drawable-hdpi.png', 52 | 'platform/android/res/drawable-mdpi/background.9.png': 'splash/drawable-mdpi.png', 53 | 'platform/android/res/drawable-xhdpi/background.9.png': 'splash/drawable-xhdpi.png', 54 | 'platform/android/res/drawable-xxhdpi/background.9.png': 'splash/drawable-xxhdpi.png' 55 | } 56 | break; 57 | case 'icons': { 58 | filesToCopy = { 59 | 'Resources/iPhone': 'icon', 60 | '/MarketplaceArtwork.png':'icon/appicon-512.png', 61 | '/DefaultIcon.png': 'icon/appicon-1028.png', 62 | 'platform/android/res/drawable-mdpi/appicon.png': 'icon/drawable-mdpi.png', 63 | 'platform/android/res/drawable-hdpi/appicon.png':'icon/drawable-hdpi.png', 64 | 'platform/android/res/drawable-xhdpi/appicon.png':'icon/drawable-xhdpi.png', 65 | 'platform/android/res/drawable-xxhdpi/appicon.png':'icon/drawable-xxhdpi.png' 66 | } 67 | break; 68 | } 69 | } 70 | 71 | for (key in filesToCopy) { 72 | var fromPath = path.join(cacheDir, key); 73 | var toPath = path.join(assetsDir, filesToCopy[key]); 74 | fs.copy(fromPath, toPath, function (err) { 75 | if (err) { 76 | console.log("ERROR: " + err); 77 | } 78 | }); 79 | } 80 | 81 | }); 82 | }); 83 | } 84 | }); 85 | }; 86 | -------------------------------------------------------------------------------- /.npm/plugin/generateAssets/npm-shrinkwrap.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "fs-extra": { 4 | "version": "0.24.0", 5 | "dependencies": { 6 | "graceful-fs": { 7 | "version": "4.1.2" 8 | }, 9 | "jsonfile": { 10 | "version": "2.2.2" 11 | }, 12 | "path-is-absolute": { 13 | "version": "1.0.0" 14 | }, 15 | "rimraf": { 16 | "version": "2.4.3", 17 | "dependencies": { 18 | "glob": { 19 | "version": "5.0.15", 20 | "dependencies": { 21 | "inflight": { 22 | "version": "1.0.4", 23 | "dependencies": { 24 | "wrappy": { 25 | "version": "1.0.1" 26 | } 27 | } 28 | }, 29 | "inherits": { 30 | "version": "2.0.1" 31 | }, 32 | "minimatch": { 33 | "version": "3.0.0", 34 | "dependencies": { 35 | "brace-expansion": { 36 | "version": "1.1.1", 37 | "dependencies": { 38 | "balanced-match": { 39 | "version": "0.2.0" 40 | }, 41 | "concat-map": { 42 | "version": "0.0.1" 43 | } 44 | } 45 | } 46 | } 47 | }, 48 | "once": { 49 | "version": "1.3.2", 50 | "dependencies": { 51 | "wrappy": { 52 | "version": "1.0.1" 53 | } 54 | } 55 | } 56 | } 57 | } 58 | } 59 | } 60 | } 61 | }, 62 | "ticons": { 63 | "version": "0.15.3", 64 | "dependencies": { 65 | "async": { 66 | "version": "0.2.10" 67 | }, 68 | "colors": { 69 | "version": "0.6.2" 70 | }, 71 | "commander": { 72 | "version": "2.8.1", 73 | "dependencies": { 74 | "graceful-readlink": { 75 | "version": "1.0.1" 76 | } 77 | } 78 | }, 79 | "fs-extended": { 80 | "version": "0.2.1" 81 | }, 82 | "gm": { 83 | "version": "1.17.0", 84 | "dependencies": { 85 | "debug": { 86 | "version": "0.7.0" 87 | }, 88 | "array-series": { 89 | "version": "0.1.5" 90 | }, 91 | "array-parallel": { 92 | "version": "0.1.3" 93 | }, 94 | "through": { 95 | "version": "2.3.8" 96 | } 97 | } 98 | }, 99 | "semver": { 100 | "version": "5.0.3" 101 | }, 102 | "underscore": { 103 | "version": "1.8.3" 104 | }, 105 | "update-notifier": { 106 | "version": "0.1.10", 107 | "dependencies": { 108 | "chalk": { 109 | "version": "0.4.0", 110 | "dependencies": { 111 | "has-color": { 112 | "version": "0.1.7" 113 | }, 114 | "ansi-styles": { 115 | "version": "1.0.0" 116 | }, 117 | "strip-ansi": { 118 | "version": "0.1.1" 119 | } 120 | } 121 | }, 122 | "configstore": { 123 | "version": "0.3.2", 124 | "dependencies": { 125 | "graceful-fs": { 126 | "version": "3.0.8" 127 | }, 128 | "js-yaml": { 129 | "version": "3.4.3", 130 | "dependencies": { 131 | "argparse": { 132 | "version": "1.0.2", 133 | "dependencies": { 134 | "lodash": { 135 | "version": "3.10.1" 136 | }, 137 | "sprintf-js": { 138 | "version": "1.0.3" 139 | } 140 | } 141 | }, 142 | "esprima": { 143 | "version": "2.6.0" 144 | } 145 | } 146 | }, 147 | "mkdirp": { 148 | "version": "0.5.1", 149 | "dependencies": { 150 | "minimist": { 151 | "version": "0.0.8" 152 | } 153 | } 154 | }, 155 | "object-assign": { 156 | "version": "2.1.1" 157 | }, 158 | "osenv": { 159 | "version": "0.1.3", 160 | "dependencies": { 161 | "os-homedir": { 162 | "version": "1.0.1" 163 | }, 164 | "os-tmpdir": { 165 | "version": "1.0.1" 166 | } 167 | } 168 | }, 169 | "user-home": { 170 | "version": "1.1.1" 171 | }, 172 | "uuid": { 173 | "version": "2.0.1" 174 | }, 175 | "xdg-basedir": { 176 | "version": "1.0.1" 177 | } 178 | } 179 | }, 180 | "request": { 181 | "version": "2.64.0", 182 | "dependencies": { 183 | "bl": { 184 | "version": "1.0.0", 185 | "dependencies": { 186 | "readable-stream": { 187 | "version": "2.0.2", 188 | "dependencies": { 189 | "core-util-is": { 190 | "version": "1.0.1" 191 | }, 192 | "inherits": { 193 | "version": "2.0.1" 194 | }, 195 | "isarray": { 196 | "version": "0.0.1" 197 | }, 198 | "process-nextick-args": { 199 | "version": "1.0.3" 200 | }, 201 | "string_decoder": { 202 | "version": "0.10.31" 203 | }, 204 | "util-deprecate": { 205 | "version": "1.0.2" 206 | } 207 | } 208 | } 209 | } 210 | }, 211 | "caseless": { 212 | "version": "0.11.0" 213 | }, 214 | "extend": { 215 | "version": "3.0.0" 216 | }, 217 | "forever-agent": { 218 | "version": "0.6.1" 219 | }, 220 | "form-data": { 221 | "version": "1.0.0-rc3", 222 | "dependencies": { 223 | "async": { 224 | "version": "1.4.2" 225 | } 226 | } 227 | }, 228 | "json-stringify-safe": { 229 | "version": "5.0.1" 230 | }, 231 | "mime-types": { 232 | "version": "2.1.7", 233 | "dependencies": { 234 | "mime-db": { 235 | "version": "1.19.0" 236 | } 237 | } 238 | }, 239 | "node-uuid": { 240 | "version": "1.4.3" 241 | }, 242 | "qs": { 243 | "version": "5.1.0" 244 | }, 245 | "tunnel-agent": { 246 | "version": "0.4.1" 247 | }, 248 | "tough-cookie": { 249 | "version": "2.2.0" 250 | }, 251 | "http-signature": { 252 | "version": "0.11.0", 253 | "dependencies": { 254 | "assert-plus": { 255 | "version": "0.1.5" 256 | }, 257 | "asn1": { 258 | "version": "0.1.11" 259 | }, 260 | "ctype": { 261 | "version": "0.5.3" 262 | } 263 | } 264 | }, 265 | "oauth-sign": { 266 | "version": "0.8.0" 267 | }, 268 | "hawk": { 269 | "version": "3.1.0", 270 | "dependencies": { 271 | "hoek": { 272 | "version": "2.16.3" 273 | }, 274 | "boom": { 275 | "version": "2.9.0" 276 | }, 277 | "cryptiles": { 278 | "version": "2.0.5" 279 | }, 280 | "sntp": { 281 | "version": "1.0.9" 282 | } 283 | } 284 | }, 285 | "aws-sign2": { 286 | "version": "0.5.0" 287 | }, 288 | "stringstream": { 289 | "version": "0.0.4" 290 | }, 291 | "combined-stream": { 292 | "version": "1.0.5", 293 | "dependencies": { 294 | "delayed-stream": { 295 | "version": "1.0.0" 296 | } 297 | } 298 | }, 299 | "isstream": { 300 | "version": "0.1.2" 301 | }, 302 | "har-validator": { 303 | "version": "1.8.0", 304 | "dependencies": { 305 | "bluebird": { 306 | "version": "2.10.2" 307 | }, 308 | "chalk": { 309 | "version": "1.1.1", 310 | "dependencies": { 311 | "ansi-styles": { 312 | "version": "2.1.0" 313 | }, 314 | "escape-string-regexp": { 315 | "version": "1.0.3" 316 | }, 317 | "has-ansi": { 318 | "version": "2.0.0", 319 | "dependencies": { 320 | "ansi-regex": { 321 | "version": "2.0.0" 322 | } 323 | } 324 | }, 325 | "strip-ansi": { 326 | "version": "3.0.0", 327 | "dependencies": { 328 | "ansi-regex": { 329 | "version": "2.0.0" 330 | } 331 | } 332 | }, 333 | "supports-color": { 334 | "version": "2.0.0" 335 | } 336 | } 337 | }, 338 | "is-my-json-valid": { 339 | "version": "2.12.2", 340 | "dependencies": { 341 | "generate-function": { 342 | "version": "2.0.0" 343 | }, 344 | "generate-object-property": { 345 | "version": "1.2.0", 346 | "dependencies": { 347 | "is-property": { 348 | "version": "1.0.2" 349 | } 350 | } 351 | }, 352 | "jsonpointer": { 353 | "version": "2.0.0" 354 | }, 355 | "xtend": { 356 | "version": "4.0.0" 357 | } 358 | } 359 | } 360 | } 361 | } 362 | } 363 | }, 364 | "semver": { 365 | "version": "2.3.2" 366 | } 367 | } 368 | } 369 | } 370 | } 371 | } 372 | } 373 | --------------------------------------------------------------------------------