diff --git a/__TESTS_BUNDLE_SIZE__/bundleSizeTestCases.ts b/__TESTS_BUNDLE_SIZE__/bundleSizeTestCases.ts index 6cf67ea3..d6876ba7 100644 --- a/__TESTS_BUNDLE_SIZE__/bundleSizeTestCases.ts +++ b/__TESTS_BUNDLE_SIZE__/bundleSizeTestCases.ts @@ -74,7 +74,7 @@ const bundleSizeTestCases:ITestCase[] = [ }, { name: 'Import all of the SDK', - sizeLimitInKB: 127, + sizeLimitInKB: 128, importsArray: [ importFromPackage('* as CloudinaryURLGEN') ] @@ -88,7 +88,7 @@ const bundleSizeTestCases:ITestCase[] = [ }, { name: 'Import All Actions', - sizeLimitInKB: 54, + sizeLimitInKB: 55, importsArray: [ importFromPackage('Actions') ] diff --git a/__TESTS__/unit/fromJson/overlayUnderlay.fromJson.test.ts b/__TESTS__/unit/fromJson/overlayUnderlay.fromJson.test.ts index 41fa9218..34a0295c 100644 --- a/__TESTS__/unit/fromJson/overlayUnderlay.fromJson.test.ts +++ b/__TESTS__/unit/fromJson/overlayUnderlay.fromJson.test.ts @@ -31,7 +31,7 @@ describe('Overlay & Underlay fromJson', () => { actionType: 'overlay', source, position, - blendMode: 'multiply' + blendMode: {blendModeType: 'multiply'} }; const overlayTransformation = fromJson({actions: [overlayModel]}); @@ -62,14 +62,14 @@ describe('Overlay & Underlay fromJson', () => { source, position, timelinePosition, - blendMode: 'multiply' + blendMode: {blendModeType: 'antiRemoval', level: '96'} }; const overlayTransformation = fromJson({actions: [overlayModel]}); const underlayTransformation = fromJson({actions: [{...overlayModel, actionType: 'underlay'}]}); - expect(overlayTransformation.toString()).toStrictEqual('l_video:dog.mp4/ar_7.0,c_scale,w_100/du_2,e_multiply,fl_layer_apply,fl_tiled,g_north_east,so_1,x_1,y_2'); - expect(underlayTransformation.toString()).toStrictEqual('u_video:dog.mp4/ar_7.0,c_scale,w_100/du_2,e_multiply,fl_layer_apply,fl_tiled,g_north_east,so_1,x_1,y_2'); + expect(overlayTransformation.toString()).toStrictEqual('l_video:dog.mp4/ar_7.0,c_scale,w_100/du_2,e_anti_removal:96,fl_layer_apply,fl_tiled,g_north_east,so_1,x_1,y_2'); + expect(underlayTransformation.toString()).toStrictEqual('u_video:dog.mp4/ar_7.0,c_scale,w_100/du_2,e_anti_removal:96,fl_layer_apply,fl_tiled,g_north_east,so_1,x_1,y_2'); }); it('Should generate Overlay for fetch source', () => { @@ -88,14 +88,14 @@ describe('Overlay & Underlay fromJson', () => { actionType: 'overlay', source, position, - blendMode: 'multiply' + blendMode: {blendModeType: 'antiRemoval'} }; const overlayTransformation = fromJson({actions: [overlayModel]}); const underlayTransformation = fromJson({actions: [{...overlayModel, actionType: 'underlay'}]}); - expect(overlayTransformation.toString()).toStrictEqual('l_fetch:aHR0cHM6Ly9zb21lL2ltYWdlLmpwZw==/ar_7.0,c_scale,w_100/e_multiply,fl_layer_apply,fl_tiled,g_north_east,x_1,y_2'); - expect(underlayTransformation.toString()).toStrictEqual('u_fetch:aHR0cHM6Ly9zb21lL2ltYWdlLmpwZw==/ar_7.0,c_scale,w_100/e_multiply,fl_layer_apply,fl_tiled,g_north_east,x_1,y_2'); + expect(overlayTransformation.toString()).toStrictEqual('l_fetch:aHR0cHM6Ly9zb21lL2ltYWdlLmpwZw==/ar_7.0,c_scale,w_100/e_anti_removal,fl_layer_apply,fl_tiled,g_north_east,x_1,y_2'); + expect(underlayTransformation.toString()).toStrictEqual('u_fetch:aHR0cHM6Ly9zb21lL2ltYWdlLmpwZw==/ar_7.0,c_scale,w_100/e_anti_removal,fl_layer_apply,fl_tiled,g_north_east,x_1,y_2'); }); it('Should generate Overlay for text source', () => { diff --git a/__TESTS__/unit/toJson/overlayUnderlay.toJson.test.ts b/__TESTS__/unit/toJson/overlayUnderlay.toJson.test.ts index 46e0dd93..be26ec19 100644 --- a/__TESTS__/unit/toJson/overlayUnderlay.toJson.test.ts +++ b/__TESTS__/unit/toJson/overlayUnderlay.toJson.test.ts @@ -48,7 +48,7 @@ describe('Overlay & Underlay toJson', () => { allowOverflow: true, gravity: {gravityType: 'direction', compass: 'north_east'} }, - blendMode: 'multiply' + blendMode: { blendModeType:'multiply' } } ] }); @@ -119,7 +119,7 @@ describe('Overlay & Underlay toJson', () => { allowOverflow: true, gravity: {gravityType: 'direction', compass: 'north_east'} }, - blendMode: 'multiply' + blendMode: {blendModeType: 'multiply'} } ] }); @@ -228,4 +228,38 @@ describe('Overlay & Underlay toJson', () => { ] }); }); + + it('Should generate Overlay model for source with Blendmode.antiRemoval', () => { + const transformation = new Transformation(); + transformation.addAction( + Overlay.source(Source.fetch('https://some/image.jpg').transformation(new Transformation().resize(scale(100).aspectRatio(7)))) + .position(new Position().offsetX(1).offsetY(2).tiled().allowOverflow().gravity(Gravity.compass(Compass.northEast()))) + .blendMode(BlendMode.antiRemoval(95)) + ); + + expect(transformation.toJson()).toStrictEqual({ + actions: [ + { + actionType: 'overlay', + source: { + sourceType: 'fetch', + url: 'https://some/image.jpg', + transformation: { + actions: [ + {actionType: 'scale', dimensions: {width: 100, aspectRatio: '7.0'}} + ] + } + }, + position: { + offsetX: 1, + offsetY: 2, + tiled: true, + allowOverflow: true, + gravity: {gravityType: 'direction', compass: 'north_east'} + }, + blendMode: {blendModeType: 'antiRemoval', level: '95'} + } + ] + }); + }); }); diff --git a/src/actions/layer/LayerAction.ts b/src/actions/layer/LayerAction.ts index 6e8a3743..035fb3b9 100644 --- a/src/actions/layer/LayerAction.ts +++ b/src/actions/layer/LayerAction.ts @@ -17,6 +17,7 @@ import {createTimelinePositionFromModel} from "../../internal/models/createTimel import {ISourceModel} from "../../internal/models/ISourceModel.js"; import {ITimelinePositionModel} from "../../internal/models/ITimelinePositionModel.js"; import {IPositionModel} from "../../internal/models/IPositionModel.js"; +import {ACTION_TYPE_TO_BLEND_MODE_MAP} from "../../internal/internalConstants.js"; /** @@ -91,8 +92,13 @@ class LayerAction extends Action { */ blendMode(blendMode: BlendModeType|BlendModeQualifier): this { this._blendMode = blendMode; - this._actionModel.blendMode = `${blendMode}`.replace('e_', ''); + const [mode, level] = `${blendMode}`.replace('e_', '').split(":"); + if (mode === 'anti_removal') { + this._actionModel.blendMode = level ? {blendModeType: 'antiRemoval', level: level} : {blendModeType: 'antiRemoval'}; + }else { + this._actionModel.blendMode = {blendModeType: mode}; + } return this; } @@ -171,7 +177,12 @@ class LayerAction extends Action { } if (blendMode) { - result.blendMode(blendMode as unknown as BlendModeQualifier); + const blendModeType = ACTION_TYPE_TO_BLEND_MODE_MAP[blendMode.blendModeType] || blendMode.blendModeType; + if(blendMode?.level) { + result.blendMode(new BlendModeQualifier(blendModeType, blendMode.level as number)); + }else{ + result.blendMode(new BlendModeQualifier(blendModeType)); + } } return result; diff --git a/src/internal/internalConstants.ts b/src/internal/internalConstants.ts index 34f088c7..29d54c23 100644 --- a/src/internal/internalConstants.ts +++ b/src/internal/internalConstants.ts @@ -139,6 +139,10 @@ export const COLOR_SPACE_MODEL_MODE_TO_COLOR_SPACE_MODE_MAP: Record = { + 'antiRemoval': 'anti_removal' +}; + export const CHROMA_MODEL_ENUM_TO_CHROMA_VALUE = objectFlip(CHROMA_VALUE_TO_CHROMA_MODEL_ENUM); export const COLOR_SPACE_MODE_TO_COLOR_SPACE_MODEL_MODE_MAP = objectFlip(COLOR_SPACE_MODEL_MODE_TO_COLOR_SPACE_MODE_MAP); diff --git a/src/internal/models/IOverlayActionModel.ts b/src/internal/models/IOverlayActionModel.ts index a38c299f..854bd56b 100644 --- a/src/internal/models/IOverlayActionModel.ts +++ b/src/internal/models/IOverlayActionModel.ts @@ -8,5 +8,5 @@ export interface IOverlayActionModel extends IActionModel { source: ISourceModel; position?: IPositionModel; timelinePosition?: ITimelinePositionModel; - blendMode?: string; + blendMode?: {blendModeType?: string, level?: number|string}; }