From 63109ad34513aa2c3541adbeeb33f59723e34a86 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Thu, 22 Mar 2018 00:01:00 +0200 Subject: [PATCH 1/4] fix(assets): Fix asset generation Fix the generation of asset - the filter is incorrect and fails with `Cannot read property 'splashImages' of null, TypeError: Cannot read property 'splashImages' of null` Also fix the scale - it has been incorrectly declared as number, when it is string (1x, 2x, etc.). Use the scale correctly by parsing it and use it when generate the image. Also fix the using of resizeOperation property - it was not passed correctly for iOS assets. --- lib/definitions/project.d.ts | 2 +- .../assets-generation-service.ts | 18 +++++--- lib/services/project-data-service.ts | 43 +++++++++++-------- 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/lib/definitions/project.d.ts b/lib/definitions/project.d.ts index ce00fa481a..0d17303cf4 100644 --- a/lib/definitions/project.d.ts +++ b/lib/definitions/project.d.ts @@ -157,7 +157,7 @@ interface IAssetItem { height: number; filename: string; directory: string; - scale: number; + scale: string; idiom: string; resizeOperation?: string; } diff --git a/lib/services/assets-generation/assets-generation-service.ts b/lib/services/assets-generation/assets-generation-service.ts index 4b2d2e3fd7..291ca4c95d 100644 --- a/lib/services/assets-generation/assets-generation-service.ts +++ b/lib/services/assets-generation/assets-generation-service.ts @@ -1,6 +1,7 @@ import * as Jimp from "jimp"; import * as Color from "color"; import { exported } from "../../common/decorators"; +import { AssetConstants } from "../../constants"; export const enum Operations { OverlayWith = "overlayWith", @@ -39,12 +40,12 @@ export class AssetsGenerationService implements IAssetsGenerationService { const assetsStructure = await this.$projectDataService.getAssetsStructure(generationData); const assetItems = _(assetsStructure) - .filter((assetGroup: IAssetGroup, platform: string) => { - return !generationData.platform || platform.toLowerCase() === generationData.platform.toLowerCase(); - }) + .filter((assetGroup: IAssetGroup, platform: string) => + !generationData.platform || platform.toLowerCase() === generationData.platform.toLowerCase() + ) .map((assetGroup: IAssetGroup) => _.filter(assetGroup, (assetSubGroup: IAssetSubGroup, imageTypeKey: string) => - propertiesToEnumerate.indexOf(imageTypeKey) !== -1 && !assetSubGroup[imageTypeKey] + assetSubGroup && propertiesToEnumerate.indexOf(imageTypeKey) !== -1 && assetSubGroup[imageTypeKey] ) ) .flatten() @@ -55,7 +56,14 @@ export class AssetsGenerationService implements IAssetsGenerationService { for (const assetItem of assetItems) { const operation = assetItem.resizeOperation || Operations.Resize; - const scale = assetItem.scale || 0.8; + let tempScale: number = null; + if (assetItem.scale && !_.isNumber(assetItem.scale)) { + const splittedElements = `${assetItem.scale}`.split(AssetConstants.sizeDelimiter); + tempScale = splittedElements && splittedElements.length && splittedElements[0] && +splittedElements[0]; + } + + const scale = tempScale || 0.8; + const outputPath = assetItem.path; switch (operation) { diff --git a/lib/services/project-data-service.ts b/lib/services/project-data-service.ts index 4a78882c0f..8f40f1e2c1 100644 --- a/lib/services/project-data-service.ts +++ b/lib/services/project-data-service.ts @@ -137,25 +137,32 @@ export class ProjectDataService implements IProjectDataService { image.path = path.join(dirPath, image.filename); } - if (image.size) { - // size is basically x - const [width, height] = image.size.toString().split(AssetConstants.sizeDelimiter); - if (width && height) { - image.width = +width; - image.height = +height; - } - } else { - // Find the image size based on the hardcoded values in the image-definitions.json - _.each(imageDefinitions, (assetSubGroup: IAssetItem[]) => { - _.each(assetSubGroup, assetItem => { - if (assetItem.filename === image.filename && path.basename(assetItem.directory) === path.basename(dirPath)) { - image.width = assetItem.width; - image.height = assetItem.height; - image.size = `${assetItem.width}${AssetConstants.sizeDelimiter}${assetItem.height}`; + // Find the image size based on the hardcoded values in the image-definitions.json + _.each(imageDefinitions, (assetSubGroup: IAssetItem[]) => { + const assetItem = _.find(assetSubGroup, assetElement => + assetElement.filename === image.filename && path.basename(assetElement.directory) === path.basename(dirPath) + ); + + if (assetItem) { + if (image.size) { + // size is basically x + const [width, height] = image.size.toString().split(AssetConstants.sizeDelimiter); + if (width && height) { + image.width = +width; + image.height = +height; } - }); - }); - } + } + + if (!image.width || !image.height) { + image.width = assetItem.width; + image.height = assetItem.height; + image.size = image.size || `${assetItem.width}${AssetConstants.sizeDelimiter}${assetItem.height}`; + } + + // break each + return false; + } + }); }); return content; From 35e259402f27a2bd83040edfab5ce43d5ec4bfe8 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Thu, 22 Mar 2018 00:04:09 +0200 Subject: [PATCH 2/4] chore: Update to latest common lib --- lib/common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/common b/lib/common index 08d16be831..006aba0181 160000 --- a/lib/common +++ b/lib/common @@ -1 +1 @@ -Subproject commit 08d16be831e02654b424a7c34fadb666c0ea2c10 +Subproject commit 006aba01812e21049960ed8b6b1ac28a3f1dbca2 From c9d4d8fac57b080071e397463e2bb8a0ad55d473 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Thu, 22 Mar 2018 12:20:45 +0200 Subject: [PATCH 3/4] fix(assets): Improve image definitions for iOS Set correct sizes for iOS images in image-definitions.json. Also fix the code that resizes the images and overlay images. Add option to have overlayImageScale in the json. We've not set it now, but the code will respect it in case we decide to add it. --- lib/definitions/project.d.ts | 1 + .../assets-generation-service.ts | 25 ++- lib/services/project-data-service.ts | 3 + resources/assets/image-definitions.json | 198 +++++++++++------- 4 files changed, 138 insertions(+), 89 deletions(-) diff --git a/lib/definitions/project.d.ts b/lib/definitions/project.d.ts index 0d17303cf4..01132e0d95 100644 --- a/lib/definitions/project.d.ts +++ b/lib/definitions/project.d.ts @@ -160,6 +160,7 @@ interface IAssetItem { scale: string; idiom: string; resizeOperation?: string; + overlayImageScale?: number; } interface IAssetSubGroup { diff --git a/lib/services/assets-generation/assets-generation-service.ts b/lib/services/assets-generation/assets-generation-service.ts index 291ca4c95d..9f077a8050 100644 --- a/lib/services/assets-generation/assets-generation-service.ts +++ b/lib/services/assets-generation/assets-generation-service.ts @@ -45,7 +45,7 @@ export class AssetsGenerationService implements IAssetsGenerationService { ) .map((assetGroup: IAssetGroup) => _.filter(assetGroup, (assetSubGroup: IAssetSubGroup, imageTypeKey: string) => - assetSubGroup && propertiesToEnumerate.indexOf(imageTypeKey) !== -1 && assetSubGroup[imageTypeKey] + assetSubGroup && propertiesToEnumerate.indexOf(imageTypeKey) !== -1 ) ) .flatten() @@ -57,26 +57,33 @@ export class AssetsGenerationService implements IAssetsGenerationService { for (const assetItem of assetItems) { const operation = assetItem.resizeOperation || Operations.Resize; let tempScale: number = null; - if (assetItem.scale && !_.isNumber(assetItem.scale)) { - const splittedElements = `${assetItem.scale}`.split(AssetConstants.sizeDelimiter); - tempScale = splittedElements && splittedElements.length && splittedElements[0] && +splittedElements[0]; + if (assetItem.scale) { + if (_.isNumber(assetItem.scale)) { + tempScale = assetItem.scale; + } else { + const splittedElements = `${assetItem.scale}`.split(AssetConstants.sizeDelimiter); + tempScale = splittedElements && splittedElements.length && splittedElements[0] && +splittedElements[0]; + } } - const scale = tempScale || 0.8; + const scale = tempScale || 1; const outputPath = assetItem.path; + const width = assetItem.width * scale; + const height = assetItem.height * scale; switch (operation) { case Operations.OverlayWith: - const imageResize = Math.round(Math.min(assetItem.width, assetItem.height) * scale); + const overlayImageScale = assetItem.overlayImageScale || 0.8; + const imageResize = Math.round(Math.min(width, height) * overlayImageScale); const image = await this.resize(generationData.imagePath, imageResize, imageResize); - await this.generateImage(generationData.background, assetItem.width, assetItem.height, outputPath, image); + await this.generateImage(generationData.background, width, height, outputPath, image); break; case Operations.Blank: - await this.generateImage(generationData.background, assetItem.width, assetItem.height, outputPath); + await this.generateImage(generationData.background, width, height, outputPath); break; case Operations.Resize: - const resizedImage = await this.resize(generationData.imagePath, assetItem.width, assetItem.height); + const resizedImage = await this.resize(generationData.imagePath, width, height); resizedImage.write(outputPath); break; default: diff --git a/lib/services/project-data-service.ts b/lib/services/project-data-service.ts index 8f40f1e2c1..1f8d642a42 100644 --- a/lib/services/project-data-service.ts +++ b/lib/services/project-data-service.ts @@ -159,6 +159,9 @@ export class ProjectDataService implements IProjectDataService { image.size = image.size || `${assetItem.width}${AssetConstants.sizeDelimiter}${assetItem.height}`; } + image.resizeOperation = image.resizeOperation || assetItem.resizeOperation; + image.overlayImageScale = image.overlayImageScale || assetItem.overlayImageScale; + // break each return false; } diff --git a/resources/assets/image-definitions.json b/resources/assets/image-definitions.json index 08916a5f43..77af1a66b5 100644 --- a/resources/assets/image-definitions.json +++ b/resources/assets/image-definitions.json @@ -2,124 +2,144 @@ "ios": { "icons": [ { - "width": 180, - "height": 180, + "width": 60, + "height": 60, "directory": "Assets.xcassets/AppIcon.appiconset", - "filename": "icon-60@3x.png" + "filename": "icon-60@3x.png", + "scale": "3x" }, { - "width": 120, - "height": 120, + "width": 60, + "height": 60, "directory": "Assets.xcassets/AppIcon.appiconset", - "filename": "icon-60@2x.png" + "filename": "icon-60@2x.png", + "scale": "3x" }, { "width": 40, "height": 40, "directory": "Assets.xcassets/AppIcon.appiconset", - "filename": "icon-40.png" + "filename": "icon-40.png", + "scale": "1x" }, { - "width": 80, - "height": 80, + "width": 40, + "height": 40, "directory": "Assets.xcassets/AppIcon.appiconset", - "filename": "icon-40@2x.png" + "filename": "icon-40@2x.png", + "scale": "2x" }, { - "width": 120, - "height": 120, + "width": 40, + "height": 40, "directory": "Assets.xcassets/AppIcon.appiconset", - "filename": "icon-40@3x.png" + "filename": "icon-40@3x.png", + "scale": "3x" }, { "width": 50, "height": 50, "directory": "Assets.xcassets/AppIcon.appiconset", - "filename": "icon-50.png" + "filename": "icon-50.png", + "scale": "1x" }, { - "width": 100, - "height": 100, + "width": 50, + "height": 50, "directory": "Assets.xcassets/AppIcon.appiconset", - "filename": "icon-50@2x.png" + "filename": "icon-50@2x.png", + "scale": "2x" }, { "width": 60, "height": 60, "directory": "Assets.xcassets/AppIcon.appiconset", - "filename": "icon-60.png" + "filename": "icon-60.png", + "scale": "1x" }, { "width": 72, "height": 72, "directory": "Assets.xcassets/AppIcon.appiconset", - "filename": "icon-72.png" + "filename": "icon-72.png", + "scale": "1x" }, { - "width": 144, - "height": 144, + "width": 72, + "height": 72, "directory": "Assets.xcassets/AppIcon.appiconset", - "filename": "icon-72@2x.png" + "filename": "icon-72@2x.png", + "scale": "2x" }, { "width": 76, "height": 76, "directory": "Assets.xcassets/AppIcon.appiconset", - "filename": "icon-76.png" + "filename": "icon-76.png", + "scale": "1x" }, { - "width": 152, - "height": 152, + "width": 76, + "height": 76, "directory": "Assets.xcassets/AppIcon.appiconset", - "filename": "icon-76@2x.png" + "filename": "icon-76@2x.png", + "scale": "2x" }, { - "width": 167, - "height": 167, + "width": 83.5, + "height": 83.5, "directory": "Assets.xcassets/AppIcon.appiconset", - "filename": "icon-83.5@2x.png" + "filename": "icon-83.5@2x.png", + "scale": "2x" }, { "width": 120, "height": 120, "directory": "Assets.xcassets/AppIcon.appiconset", - "filename": "icon-120.png" + "filename": "icon-120.png", + "scale": "1x" }, { "width": 29, "height": 29, "directory": "Assets.xcassets/AppIcon.appiconset", - "filename": "icon-29.png" + "filename": "icon-29.png", + "scale": "1x" }, { - "width": 58, - "height": 58, + "width": 29, + "height": 29, "directory": "Assets.xcassets/AppIcon.appiconset", - "filename": "icon-29@2x.png" + "filename": "icon-29@2x.png", + "scale": "2x" }, { - "width": 87, - "height": 87, + "width": 29, + "height": 29, "directory": "Assets.xcassets/AppIcon.appiconset", - "filename": "icon-29@3x.png" + "filename": "icon-29@3x.png", + "scale": "3x" }, { "width": 57, "height": 57, "directory": "Assets.xcassets/AppIcon.appiconset", - "filename": "icon-57.png" + "filename": "icon-57.png", + "scale": "1x" }, { - "width": 114, - "height": 114, + "width": 57, + "height": 57, "directory": "Assets.xcassets/AppIcon.appiconset", - "filename": "icon-57@2x.png" + "filename": "icon-57@2x.png", + "scale": "2x" }, { "width": 1024, "height": 1024, "directory": "Assets.xcassets/AppIcon.appiconset", - "filename": "icon-1024.png" + "filename": "icon-1024.png", + "scale": "1x" } ], "splashBackgrounds": [ @@ -128,21 +148,24 @@ "height": 1024, "directory": "Assets.xcassets/LaunchScreen.AspectFill.imageset", "filename": "LaunchScreen-AspectFill.png", - "resizeOperation": "blank" + "resizeOperation": "blank", + "scale": "1x" }, { - "width": 1536, - "height": 2048, + "width": 768, + "height": 1024, "directory": "Assets.xcassets/LaunchScreen.AspectFill.imageset", "filename": "LaunchScreen-AspectFill@2x.png", - "resizeOperation": "blank" + "resizeOperation": "blank", + "scale": "2x" }, { - "width": 2304, - "height": 3072, + "width": 768, + "height": 1024, "directory": "Assets.xcassets/LaunchScreen.AspectFill.imageset", "filename": "LaunchScreen-AspectFill@3x.png", - "resizeOperation": "blank" + "resizeOperation": "blank", + "scale": "3x" } ], "splashCenterImages": [ @@ -151,107 +174,122 @@ "height": 512, "directory": "Assets.xcassets/LaunchScreen.Center.imageset", "filename": "LaunchScreen-Center.png", - "resizeOperation": "overlayWith" + "resizeOperation": "overlayWith", + "scale": "1x" }, { - "width": 768, - "height": 1024, + "width": 384, + "height": 512, "directory": "Assets.xcassets/LaunchScreen.Center.imageset", "filename": "LaunchScreen-Center@2x.png", - "resizeOperation": "overlayWith" + "resizeOperation": "overlayWith", + "scale": "2x" } ], "splashImages": [ { - "width": 640, - "height": 1136, + "width": 320, + "height": 568, "directory": "Assets.xcassets/LaunchImage.launchimage", "filename": "Default-568h@2x.png", - "resizeOperation": "overlayWith" + "resizeOperation": "overlayWith", + "scale": "2x" }, { "width": 1024, "height": 768, "directory": "Assets.xcassets/LaunchImage.launchimage", "filename": "Default-Landscape.png", - "resizeOperation": "overlayWith" + "resizeOperation": "overlayWith", + "scale": "1x" }, { - "width": 2048, - "height": 1536, + "width": 1024, + "height": 768, "directory": "Assets.xcassets/LaunchImage.launchimage", "filename": "Default-Landscape@2x.png", - "resizeOperation": "overlayWith" + "resizeOperation": "overlayWith", + "scale": "2x" }, { - "width": 2208, - "height": 1242, + "width": 736, + "height": 414, "directory": "Assets.xcassets/LaunchImage.launchimage", "filename": "Default-Landscape@3x.png", - "resizeOperation": "overlayWith" + "resizeOperation": "overlayWith", + "scale": "3x" }, { - "width": 1536, - "height": 2048, + "width": 768, + "height": 1024, "directory": "Assets.xcassets/LaunchImage.launchimage", "filename": "Default-Portrait@2x.png", - "resizeOperation": "overlayWith" + "resizeOperation": "overlayWith", + "scale": "2x" }, { "width": 768, "height": 1024, "directory": "Assets.xcassets/LaunchImage.launchimage", "filename": "Default-Portrait.png", - "resizeOperation": "overlayWith" + "resizeOperation": "overlayWith", + "scale": "1x" }, { - "width": 640, - "height": 960, + "width": 320, + "height": 480, "directory": "Assets.xcassets/LaunchImage.launchimage", "filename": "Default@2x.png", - "resizeOperation": "overlayWith" + "resizeOperation": "overlayWith", + "scale": "2x" }, { "width": 320, "height": 480, "directory": "Assets.xcassets/LaunchImage.launchimage", "filename": "Default.png", - "resizeOperation": "overlayWith" + "resizeOperation": "overlayWith", + "scale": "1x" }, { - "width": 750, - "height": 1344, + "width": 375, + "height": 667, "directory": "Assets.xcassets/LaunchImage.launchimage", "filename": "Default-667h@2x.png", - "resizeOperation": "overlayWith" + "resizeOperation": "overlayWith", + "scale": "2x" }, { - "width": 1242, - "height": 2208, + "width": 414, + "height": 736, "directory": "Assets.xcassets/LaunchImage.launchimage", "filename": "Default-736h@3x.png", - "resizeOperation": "overlayWith" + "resizeOperation": "overlayWith", + "scale": "3x" }, { "width": 2208, "height": 1242, "directory": "Assets.xcassets/LaunchImage.launchimage", "filename": "Default-Landscape-736h.png", - "resizeOperation": "overlayWith" + "resizeOperation": "overlayWith", + "scale": "1x" }, { "width": 1125, "height": 2436, "directory": "Assets.xcassets/LaunchImage.launchimage", "filename": "Default-1125h.png", - "resizeOperation": "overlayWith" + "resizeOperation": "overlayWith", + "scale": "1x" }, { "width": 2436, "height": 1125, "directory": "Assets.xcassets/LaunchImage.launchimage", "filename": "Default-Landscape-X.png", - "resizeOperation": "overlayWith" + "resizeOperation": "overlayWith", + "scale": "1x" } ] }, From 920cb8e9f27f45c1138fce09ade43238295bb40b Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Thu, 22 Mar 2018 14:22:35 +0200 Subject: [PATCH 4/4] chore: fix incorrect assets definitions --- lib/constants.ts | 3 +++ lib/services/assets-generation/assets-generation-service.ts | 6 +++--- lib/services/project-data-service.ts | 2 +- resources/assets/image-definitions.json | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/constants.ts b/lib/constants.ts index e196f57971..0beb79f39c 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -162,4 +162,7 @@ export class AssetConstants { public static assets = "assets"; public static sizeDelimiter = "x"; + + public static defaultScale = 1; + public static defaultOverlayImageScale = 0.8; } diff --git a/lib/services/assets-generation/assets-generation-service.ts b/lib/services/assets-generation/assets-generation-service.ts index 9f077a8050..550fbcd0c2 100644 --- a/lib/services/assets-generation/assets-generation-service.ts +++ b/lib/services/assets-generation/assets-generation-service.ts @@ -1,7 +1,7 @@ import * as Jimp from "jimp"; import * as Color from "color"; import { exported } from "../../common/decorators"; -import { AssetConstants } from "../../constants"; +import { AssetConstants } from '../../constants'; export const enum Operations { OverlayWith = "overlayWith", @@ -66,7 +66,7 @@ export class AssetsGenerationService implements IAssetsGenerationService { } } - const scale = tempScale || 1; + const scale = tempScale || AssetConstants.defaultScale; const outputPath = assetItem.path; const width = assetItem.width * scale; @@ -74,7 +74,7 @@ export class AssetsGenerationService implements IAssetsGenerationService { switch (operation) { case Operations.OverlayWith: - const overlayImageScale = assetItem.overlayImageScale || 0.8; + const overlayImageScale = assetItem.overlayImageScale || AssetConstants.defaultOverlayImageScale; const imageResize = Math.round(Math.min(width, height) * overlayImageScale); const image = await this.resize(generationData.imagePath, imageResize, imageResize); await this.generateImage(generationData.background, width, height, outputPath, image); diff --git a/lib/services/project-data-service.ts b/lib/services/project-data-service.ts index 1f8d642a42..c4c38e17f2 100644 --- a/lib/services/project-data-service.ts +++ b/lib/services/project-data-service.ts @@ -161,7 +161,7 @@ export class ProjectDataService implements IProjectDataService { image.resizeOperation = image.resizeOperation || assetItem.resizeOperation; image.overlayImageScale = image.overlayImageScale || assetItem.overlayImageScale; - + image.scale = image.scale || assetItem.scale; // break each return false; } diff --git a/resources/assets/image-definitions.json b/resources/assets/image-definitions.json index 77af1a66b5..02289c926a 100644 --- a/resources/assets/image-definitions.json +++ b/resources/assets/image-definitions.json @@ -13,7 +13,7 @@ "height": 60, "directory": "Assets.xcassets/AppIcon.appiconset", "filename": "icon-60@2x.png", - "scale": "3x" + "scale": "2x" }, { "width": 40,