UNPKG

generator-rn-toolbox-gv

Version:

React-Native generators to kickstart your project

233 lines (207 loc) 6.46 kB
const gm = require('gm').subClass({ imageMagick: true }); const fs = require('fs-extra'); const path = require('path'); const Promise = require('bluebird'); require('colors'); Promise.promisifyAll(gm.prototype); /* eslint-disable no-multi-spaces */ const iosIconSizes = [ { size: 20, multipliers: [1, 2, 3] }, { size: 29, multipliers: [1, 2, 3] }, { size: 40, multipliers: [1, 2, 3] }, { size: 50, multipliers: [1, 2] }, { size: 57, multipliers: [1, 2] }, { size: 60, multipliers: [2, 3] }, { size: 72, multipliers: [1, 2] }, { size: 76, multipliers: [1, 2] }, { size: 83.5, multipliers: [2] }, { size: 1024, multipliers: [1] }, ]; const androidIconSizes = [ { value: 36, density: 'ldpi' }, { value: 48, density: 'mdpi' }, { value: 72, density: 'hdpi' }, { value: 96, density: 'xhdpi' }, { value: 144, density: 'xxhdpi' }, { value: 192, density: 'xxxhdpi' }, ]; const androidSplashSizes = [ { width: 320, height: 240, density: 'land-ldpi' }, { width: 480, height: 320, density: 'land-mdpi' }, { width: 800, height: 480, density: 'land-hdpi' }, { width: 1280, height: 720, density: 'land-xhdpi' }, { width: 1600, height: 960, density: 'land-xxhdpi' }, { width: 1920, height: 1280, density: 'land-xxxhdpi' }, { width: 240, height: 320, density: 'port-ldpi' }, { width: 320, height: 480, density: 'port-mdpi' }, { width: 480, height: 800, density: 'port-hdpi' }, { width: 720, height: 1280, density: 'port-xhdpi' }, { width: 960, height: 1600, density: 'port-xxhdpi' }, { width: 1280, height: 1920, density: 'port-xxxhdpi' }, ]; // See http://iconhandbook.co.uk/reference/chart/android/ const androidNotificationIconSizes = [ { value: 24, density: 'ldpi' }, { value: 24, density: 'mdpi' }, { value: 36, density: 'hdpi' }, { value: 48, density: 'xhdpi' }, { value: 72, density: 'xxhdpi' }, { value: 96, density: 'xxxhdpi' }, ]; const iosSplashSizes = [ { name: 'Default-Portrait-812h@3x', width: 1125, height: 2436 }, { name: 'Default-Landscape-812h@3x', width: 2436, height: 1125 }, { name: 'Default-568h@2x', width: 640, height: 1136 }, { name: 'Default-667h@2x', width: 750, height: 1334 }, { name: 'Default-Portrait-736h@3x', width: 1242, height: 2208 }, { name: 'Default-Landscape-736h@3x', width: 2208, height: 1242 }, { name: 'Default-Landscape@2x', width: 2048, height: 1536 }, { name: 'Default-Landscape', width: 1024, height: 768 }, { name: 'Default-Portrait@2x', width: 1536, height: 2048 }, { name: 'Default-Portrait', width: 768, height: 1024 }, { name: 'Default@2x', width: 640, height: 960 }, ]; const itunesIconSize = { name: 'itunes-icon.png', value: 1024 }; const playStoreIconSize = { name: 'play-store-icon.png', value: 512 }; const playStoreImageSize = { name: 'play-store-image.png', width: 1024, height: 500, }; /* eslint-enable no-multi-spaces */ const getResizedImageGraphic = (sourcePath, width, height) => { const maxSize = Math.max(width, height); return gm(path.normalize(sourcePath)) .resize(maxSize, maxSize) .gravity('center') .crop( width, height, height > width ? (height - width) / 2 : 0, width > height ? (width - height) / 2 : 0 ); }; const checkImageIsSquare = sourcePath => gm(path.normalize(sourcePath)) .sizeAsync() .then(size => { if (size.width !== size.height) { console.log('Please use a square image'.red); process.exit(1); } }); const generateResizedAssets = ( sourcePath, destinationPath, width, givenHeight ) => { const height = givenHeight || width; const directory = path.dirname(destinationPath); if (!fs.existsSync(directory)) { fs.mkdirpSync(directory); } const psdSafeSourcePath = `${sourcePath}${ sourcePath.split('.').pop() === 'psd' ? '[0]' : '' }`; return checkImageIsSquare(psdSafeSourcePath).then(() => getResizedImageGraphic(psdSafeSourcePath, width, height) .writeAsync(path.normalize(destinationPath)) .then(() => console.log(`Wrote ${destinationPath}`)) ); }; const generateIosIcons = (iconSource, iosIconFolder) => Promise.all( iosIconSizes.map(size => Promise.all( size.multipliers.map(multiplier => generateResizedAssets( iconSource, `${iosIconFolder}/icon-${size.size}@${multiplier}x.png`, size.size * multiplier ) ) ) ) ); const generateAndroidIcons = ( iconSource, assetsOutputPath, androidSrcDirectory ) => Promise.all( androidIconSizes.map(size => generateResizedAssets( iconSource, `${assetsOutputPath}/android/app/src/${androidSrcDirectory}/res/mipmap-${ size.density }/ic_launcher.png`, size.value ) ) ); const generateIosSplashScreen = (splashSource, iosSplashFolder) => Promise.all( iosSplashSizes.map(size => generateResizedAssets( splashSource, `${iosSplashFolder}/${size.name}.png`, size.width, size.height ) ) ); const generateAndroidSplashScreen = ( splashSource, assetsOutputPath, androidSrcDirectory ) => androidSplashSizes.map(size => generateResizedAssets( splashSource, `${assetsOutputPath}/android/app/src/${androidSrcDirectory}/res/drawable-${ size.density }/launch_screen.png`, size.width, size.height ) ); const generateAndroidNotificationIcons = ( iconSource, assetsOutputPath, androidSrcDirectory ) => androidNotificationIconSizes.map(size => generateResizedAssets( iconSource, `${assetsOutputPath}/android/app/src/${androidSrcDirectory}/res/mipmap-${ size.density }/ic_notification.png`, size.value ) ); const generatePlayStoreIcon = iconSource => generateResizedAssets( iconSource, playStoreIconSize.name, playStoreIconSize.value ); const generateItunesIcon = iconSource => generateResizedAssets(iconSource, itunesIconSize.name, itunesIconSize.value); const generatePlayStoreImage = iconSource => generateResizedAssets( iconSource, playStoreImageSize.name, playStoreImageSize.width, playStoreImageSize.height ); module.exports = { generateIosSplashScreen, generateAndroidIcons, generateIosIcons, generateAndroidSplashScreen, generateAndroidNotificationIcons, generatePlayStoreIcon, generateItunesIcon, generatePlayStoreImage, };