mirror of
https://github.com/igorski/bitmappery.git
synced 2026-08-03 12:31:37 +02:00
Implemented white balance filter, grouped quick adjustments into their own fieldset
This commit is contained in:
@@ -51,6 +51,33 @@
|
||||
/>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="fieldset">
|
||||
<legend v-t="'quickAdjustments'" />
|
||||
<div class="wrapper wrapper--toggle">
|
||||
<label v-t="'whiteBalance'"></label>
|
||||
<toggle-button
|
||||
v-model="internalValue.quick.whiteBalance"
|
||||
name="invert"
|
||||
sync
|
||||
/>
|
||||
</div>
|
||||
<div class="wrapper wrapper--toggle">
|
||||
<label v-t="'invert'"></label>
|
||||
<toggle-button
|
||||
v-model="internalValue.quick.invert"
|
||||
name="invert"
|
||||
sync
|
||||
/>
|
||||
</div>
|
||||
<div class="wrapper wrapper--toggle">
|
||||
<label v-t="'grayscale'"></label>
|
||||
<toggle-button
|
||||
v-model="internalValue.quick.desaturate"
|
||||
name="desaturate"
|
||||
sync
|
||||
/>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="fieldset">
|
||||
<legend v-t="'colorAdjustments'" />
|
||||
<div class="wrapper wrapper--slider">
|
||||
@@ -122,22 +149,6 @@
|
||||
</fieldset>
|
||||
<fieldset class="fieldset fieldset--duotone">
|
||||
<legend v-t="'filters'" />
|
||||
<div class="wrapper wrapper--toggle">
|
||||
<label v-t="'invert'"></label>
|
||||
<toggle-button
|
||||
v-model="internalValue.invert"
|
||||
name="invert"
|
||||
sync
|
||||
/>
|
||||
</div>
|
||||
<div class="wrapper wrapper--toggle">
|
||||
<label v-t="'grayscale'"></label>
|
||||
<toggle-button
|
||||
v-model="internalValue.desaturate"
|
||||
name="desaturate"
|
||||
sync
|
||||
/>
|
||||
</div>
|
||||
<div class="wrapper wrapper--toggle">
|
||||
<label
|
||||
for="duotone"
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
"brightness": "Brightness",
|
||||
"vibrance": "Vibrance",
|
||||
"invert": "Invert",
|
||||
"whiteBalance": "White balance",
|
||||
"quickAdjustments": "Quick adjustments",
|
||||
"threshold": "Threshold",
|
||||
"grayscale": "Grayscale",
|
||||
"duotone": "Duotone",
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<template>
|
||||
<div class="tool-option">
|
||||
<h3 v-t="'fill'"></h3>
|
||||
<div class="wrapper wrapper--toggle wrapper--full">
|
||||
<div class="wrapper wrapper--toggle">
|
||||
<label v-t="'smartFill'"></label>
|
||||
<toggle-button
|
||||
v-model="smartFill"
|
||||
|
||||
@@ -21,13 +21,32 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
import { BlendModes } from "@/definitions/blend-modes";
|
||||
import { DeepPartial } from "@/model/types/_util";
|
||||
import type { Filters } from "@/model/types/filters";
|
||||
|
||||
export type FiltersProps = Partial<Filters>;
|
||||
export type FiltersProps = DeepPartial<Filters>;
|
||||
|
||||
export const DEFAULT_DUOTONE_1 = "#FF0000";
|
||||
export const DEFAULT_DUOTONE_2 = "#0099FF";
|
||||
|
||||
const DEFAULT_QUICK_SETTINGS = {
|
||||
desaturate : false,
|
||||
invert : false,
|
||||
whiteBalance : false,
|
||||
};
|
||||
|
||||
const DEFAULT_DUOTONE = {
|
||||
enabled: false,
|
||||
color1: DEFAULT_DUOTONE_1,
|
||||
color2: DEFAULT_DUOTONE_2,
|
||||
};
|
||||
|
||||
const DEFAULT_HSL = {
|
||||
hue: 0,
|
||||
sat: 0,
|
||||
lightness: 0,
|
||||
};
|
||||
|
||||
let defaultFilters: Filters | null = null;
|
||||
|
||||
const FiltersFactory = {
|
||||
@@ -40,18 +59,9 @@ const FiltersFactory = {
|
||||
contrast = 0,
|
||||
vibrance = .5,
|
||||
threshold = -1, // -1 == off, working range is 0 - 255
|
||||
desaturate = false,
|
||||
invert = false,
|
||||
duotone = {
|
||||
enabled: false,
|
||||
color1: DEFAULT_DUOTONE_1,
|
||||
color2: DEFAULT_DUOTONE_2,
|
||||
},
|
||||
hsl = {
|
||||
hue: 0,
|
||||
sat: 0,
|
||||
lightness: 0,
|
||||
},
|
||||
quick = DEFAULT_QUICK_SETTINGS,
|
||||
duotone = DEFAULT_DUOTONE,
|
||||
hsl = DEFAULT_HSL,
|
||||
blur = 0,
|
||||
}: FiltersProps = {}): Filters {
|
||||
return {
|
||||
@@ -61,12 +71,20 @@ const FiltersFactory = {
|
||||
gamma,
|
||||
brightness,
|
||||
contrast,
|
||||
desaturate,
|
||||
invert,
|
||||
vibrance,
|
||||
threshold,
|
||||
duotone,
|
||||
hsl,
|
||||
quick: {
|
||||
...DEFAULT_QUICK_SETTINGS,
|
||||
...quick
|
||||
},
|
||||
hsl: {
|
||||
...DEFAULT_HSL,
|
||||
...hsl,
|
||||
},
|
||||
duotone: {
|
||||
...DEFAULT_DUOTONE,
|
||||
...duotone,
|
||||
},
|
||||
blur,
|
||||
};
|
||||
},
|
||||
@@ -76,7 +94,7 @@ const FiltersFactory = {
|
||||
* for project storage
|
||||
*/
|
||||
serialize( filters: Filters ): any {
|
||||
const { duotone, hsl } = filters;
|
||||
const { duotone, hsl, quick } = filters;
|
||||
return {
|
||||
e: filters.enabled,
|
||||
m: filters.blendMode,
|
||||
@@ -84,8 +102,9 @@ const FiltersFactory = {
|
||||
g: filters.gamma,
|
||||
b: filters.brightness,
|
||||
c: filters.contrast,
|
||||
d: filters.desaturate,
|
||||
i: filters.invert,
|
||||
d: quick.desaturate,
|
||||
i: quick.invert,
|
||||
w: quick.whiteBalance,
|
||||
v: filters.vibrance,
|
||||
t: filters.threshold,
|
||||
de: duotone.enabled,
|
||||
@@ -103,30 +122,33 @@ const FiltersFactory = {
|
||||
* inside a stored projects layer
|
||||
*/
|
||||
deserialize( filters: any = {} ): Filters {
|
||||
return FiltersFactory.create({
|
||||
enabled: filters.e,
|
||||
blendMode: filters.m,
|
||||
opacity: filters.o,
|
||||
gamma: filters.g,
|
||||
brightness: filters.b,
|
||||
contrast: filters.c,
|
||||
desaturate: filters.d,
|
||||
vibrance: filters.v,
|
||||
threshold: filters.t,
|
||||
// these can be undefined as these were added in later app versions
|
||||
invert: filters.i ?? false,
|
||||
duotone: {
|
||||
// nullish coalescing fallbacks as some properties were added in later app versions
|
||||
return FiltersFactory.create({
|
||||
enabled: filters.e,
|
||||
blendMode: filters.m,
|
||||
opacity: filters.o,
|
||||
gamma: filters.g,
|
||||
brightness: filters.b,
|
||||
contrast: filters.c,
|
||||
vibrance: filters.v,
|
||||
threshold: filters.t,
|
||||
quick: {
|
||||
desaturate: filters.d,
|
||||
invert: filters.i ?? false,
|
||||
whiteBalance: filters.w ?? false,
|
||||
},
|
||||
duotone: {
|
||||
enabled: filters.de ?? false,
|
||||
color1: filters.d1 ?? DEFAULT_DUOTONE_1,
|
||||
color2: filters.d2 ?? DEFAULT_DUOTONE_2,
|
||||
},
|
||||
hsl: {
|
||||
},
|
||||
hsl: {
|
||||
hue: filters.hh ?? 0,
|
||||
sat: filters.hs ?? 0,
|
||||
lightness: filters.hl ?? 0,
|
||||
},
|
||||
blur: filters.bl,
|
||||
});
|
||||
},
|
||||
blur: filters.bl,
|
||||
});
|
||||
}
|
||||
};
|
||||
export default FiltersFactory;
|
||||
@@ -151,15 +173,20 @@ export const isEqual = ( filters: Filters, filtersToCompareTo?: Filters ): boole
|
||||
filters.gamma === filtersToCompareTo.gamma &&
|
||||
filters.brightness === filtersToCompareTo.brightness &&
|
||||
filters.contrast === filtersToCompareTo.contrast &&
|
||||
filters.desaturate === filtersToCompareTo.desaturate &&
|
||||
filters.invert === filtersToCompareTo.invert &&
|
||||
filters.vibrance === filtersToCompareTo.vibrance &&
|
||||
filters.threshold === filtersToCompareTo.threshold &&
|
||||
// quick filters
|
||||
filters.quick.desaturate === filtersToCompareTo.quick.desaturate &&
|
||||
filters.quick.invert === filtersToCompareTo.quick.invert &&
|
||||
filters.quick.whiteBalance === filtersToCompareTo.quick.whiteBalance &&
|
||||
// duotone
|
||||
filters.duotone.enabled === filtersToCompareTo.duotone.enabled &&
|
||||
filters.duotone.color1 === filtersToCompareTo.duotone.color1 &&
|
||||
filters.duotone.color2 === filtersToCompareTo.duotone.color2 &&
|
||||
// HSL
|
||||
filters.hsl.hue === filtersToCompareTo.hsl.hue &&
|
||||
filters.hsl.sat === filtersToCompareTo.hsl.sat &&
|
||||
filters.hsl.lightness === filtersToCompareTo.hsl.lightness &&
|
||||
// blur
|
||||
filters.blur === filtersToCompareTo.blur;
|
||||
};
|
||||
|
||||
13
src/model/types/_util.ts
Normal file
13
src/model/types/_util.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export type DeepPartial<T> = T extends Function
|
||||
? T
|
||||
: T extends Array<infer InferredArrayMember>
|
||||
? _DeepPartialArray<InferredArrayMember>
|
||||
: T extends object
|
||||
? _DeepPartialObject<T>
|
||||
: T | undefined;
|
||||
|
||||
type _DeepPartialArray<T> = Array<DeepPartial<T>>;
|
||||
|
||||
type _DeepPartialObject<T> = {
|
||||
[Key in keyof T]?: DeepPartial<T[Key]>;
|
||||
};
|
||||
@@ -22,6 +22,24 @@
|
||||
*/
|
||||
import type { BlendModes } from "@/definitions/blend-modes";
|
||||
|
||||
type DuoToneFilter = {
|
||||
enabled: boolean;
|
||||
color1?: string;
|
||||
color2?: string;
|
||||
};
|
||||
|
||||
type QuickFilter = {
|
||||
desaturate: boolean;
|
||||
invert: boolean;
|
||||
whiteBalance: boolean;
|
||||
};
|
||||
|
||||
type HSLFilter = {
|
||||
hue: number, // -180 to +180 range (degrees)
|
||||
sat: number, // -1 to +1 range
|
||||
lightness: number, // -1 to +1 range
|
||||
};
|
||||
|
||||
export type Filters = {
|
||||
enabled: boolean;
|
||||
blendMode: BlendModes;
|
||||
@@ -31,17 +49,8 @@ export type Filters = {
|
||||
contrast: number;
|
||||
vibrance: number;
|
||||
threshold: number;
|
||||
desaturate: boolean;
|
||||
invert: boolean;
|
||||
duotone: {
|
||||
enabled: boolean;
|
||||
color1?: string;
|
||||
color2?: string;
|
||||
};
|
||||
hsl: {
|
||||
hue: number, // -180 to +180 range (degrees)
|
||||
sat: number, // -1 to +1 range
|
||||
lightness: number, // -1 to +1 range
|
||||
};
|
||||
quick: QuickFilter;
|
||||
duotone: DuoToneFilter;
|
||||
hsl: HSLFilter;
|
||||
blur: number;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -33,6 +33,9 @@ const defaultFilters = FiltersFactory.create();
|
||||
/**
|
||||
* Apply generic adjustment filters (brightness, contrast, gamma, vibrance, threshold)
|
||||
* onto provided RGBA pixel Array.
|
||||
*
|
||||
* These can be combined in a single function as these filters do not
|
||||
* require an initial pass (for instant to calculate averages, etc.)
|
||||
*/
|
||||
export const applyAdjustments = ( pixels: Uint8ClampedArray, filters: Filters ): void =>
|
||||
{
|
||||
@@ -41,18 +44,19 @@ export const applyAdjustments = ( pixels: Uint8ClampedArray, filters: Filters ):
|
||||
const gamma = filters.gamma * 2; // 0 to 2 range
|
||||
const vibrance = -(( filters.vibrance * 200 ) - 100 ); // -100 to 100 range
|
||||
|
||||
const { desaturate, invert, threshold } = filters;
|
||||
|
||||
let r, g, b, a;
|
||||
let grayScale, max, avg, amt;
|
||||
const gammaSquared = gamma * gamma;
|
||||
|
||||
const doBrightness = filters.brightness !== defaultFilters.brightness;
|
||||
const doContrast = filters.contrast !== defaultFilters.contrast;
|
||||
const doGamma = filters.gamma !== defaultFilters.gamma;
|
||||
const doVibrance = filters.vibrance !== defaultFilters.vibrance;
|
||||
const doThreshold = filters.threshold !== defaultFilters.threshold;
|
||||
const doInvert = filters.invert !== defaultFilters.invert;
|
||||
const doInvert = filters.quick.invert;
|
||||
const doDesaturate = filters.quick.desaturate;
|
||||
|
||||
const { threshold } = filters;
|
||||
|
||||
let r, g, b, a;
|
||||
let grayScale, max, avg, amt;
|
||||
const gammaSquared = gamma * gamma;
|
||||
|
||||
// loop through the pixels, note we increment the iterator by four
|
||||
// as each pixel is defined by four RGBA channel values : red, green, blue and the alpha channel
|
||||
@@ -84,7 +88,7 @@ export const applyAdjustments = ( pixels: Uint8ClampedArray, filters: Filters ):
|
||||
}
|
||||
|
||||
// desaturate
|
||||
if ( desaturate ) {
|
||||
if ( doDesaturate ) {
|
||||
grayScale = r * 0.3 + g * 0.59 + b * 0.11;
|
||||
r = grayScale;
|
||||
g = grayScale;
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
*/
|
||||
import { RGBtoHSL, HSLtoRGB } from "@/utils/color-util";
|
||||
|
||||
const HALF_PI = Math.PI / 2;
|
||||
|
||||
/**
|
||||
* Applies HSL balancing onto provided data
|
||||
*
|
||||
|
||||
33
src/rendering/filters/white-balance.ts
Normal file
33
src/rendering/filters/white-balance.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
export const applyWhiteBalance = ( pixels: Uint8ClampedArray ): void => {
|
||||
const totalPixels = pixels.length / 4;
|
||||
|
||||
let totalR = 0, totalG = 0, totalB = 0;
|
||||
|
||||
// Step 1: Calculate the sum of all RGB values
|
||||
for ( let i = 0, len = pixels.length; i < len; i += 4) {
|
||||
totalR += pixels[ i ];
|
||||
totalG += pixels[ i + 1 ];
|
||||
totalB += pixels[ i + 2 ];
|
||||
}
|
||||
|
||||
// Step 2: Find the average value for each channel
|
||||
const avgR = totalR / totalPixels;
|
||||
const avgG = totalG / totalPixels;
|
||||
const avgB = totalB / totalPixels;
|
||||
|
||||
// Step 3: Calculate the overall average brightness
|
||||
const avgGray = ( avgR + avgG + avgB ) / 3;
|
||||
|
||||
// Step 4: Calculate scaling factors for each channel
|
||||
const scaleR = avgGray / avgR;
|
||||
const scaleG = avgGray / avgG;
|
||||
const scaleB = avgGray / avgB;
|
||||
|
||||
// Step 5: Apply the scaling factors to every pixel
|
||||
for ( let i = 0, len = pixels.length; i < len; i += 4 ) {
|
||||
pixels[i] = Math.min(255, pixels[i] * scaleR); // New Red
|
||||
pixels[i + 1] = Math.min(255, pixels[i + 1] * scaleG); // New Green
|
||||
pixels[i + 2] = Math.min(255, pixels[i + 2] * scaleB); // New Blue
|
||||
// data[i+3] is Alpha (transparency), leave it unchanged
|
||||
}
|
||||
};
|
||||
@@ -28,6 +28,14 @@ $inputWidth: 65%;
|
||||
margin-bottom: variables.$spacing-small;
|
||||
}
|
||||
|
||||
&--toggle {
|
||||
justify-content: space-between;
|
||||
|
||||
&.wrapper--full {
|
||||
justify-content: initial;
|
||||
}
|
||||
}
|
||||
|
||||
// use where there is no <label> element
|
||||
&--full {
|
||||
width: 200%;
|
||||
|
||||
@@ -27,6 +27,7 @@ import type { WasmFilterInstance } from "@/utils/wasm-util";
|
||||
import { applyAdjustments } from "@/rendering/filters/adjustments";
|
||||
import { applyBlur } from "@/rendering/filters/blur";
|
||||
import { applyDuotone } from "@/rendering/filters/duotone";
|
||||
import { applyWhiteBalance } from "../rendering/filters/white-balance";
|
||||
import { applyHSL } from "@/rendering/filters/hsl";
|
||||
import wasmJs from "@/wasm/bin/filters.js";
|
||||
|
||||
@@ -86,6 +87,9 @@ function renderFilters( imageData: ImageData, filters: Filters ): Uint8ClampedAr
|
||||
applyBlur( pixels, imageData.width, imageData.height, filters.blur );
|
||||
}
|
||||
|
||||
if ( filters.quick.whiteBalance ) {
|
||||
applyWhiteBalance( pixels );
|
||||
}
|
||||
applyAdjustments( pixels, filters );
|
||||
|
||||
if ( filters.duotone.enabled ) {
|
||||
@@ -100,12 +104,12 @@ function renderFilters( imageData: ImageData, filters: Filters ): Uint8ClampedAr
|
||||
|
||||
/* internal methods */
|
||||
|
||||
function renderFiltersWasm( imageData: ImageData, filters: any ): Uint8ClampedArray {
|
||||
function renderFiltersWasm( imageData: ImageData, filters: Filters ): Uint8ClampedArray {
|
||||
const brightness = ( filters.brightness * 2 );//( filters.brightness * 2 ) - 1; // -1 to 1 range
|
||||
const contrast = Math.pow((( filters.contrast * 100 ) + 100 ) / 100, 2 ); // -100 to 100 range
|
||||
const gamma = ( filters.gamma * 2 ); // 0 to 2 range
|
||||
const vibrance = -(( filters.vibrance * 200 ) - 100 ); // -100 to 100 range
|
||||
const { desaturate, invert, threshold } = filters;
|
||||
const { threshold } = filters;
|
||||
|
||||
const doBrightness = filters.brightness !== defaultFilters.brightness;
|
||||
const doContrast = filters.contrast !== defaultFilters.contrast;
|
||||
@@ -114,8 +118,10 @@ function renderFiltersWasm( imageData: ImageData, filters: any ): Uint8ClampedAr
|
||||
|
||||
// @todo these are not supported by the WASM variant yet
|
||||
|
||||
const doInvert = invert !== defaultFilters.invert;
|
||||
const doInvert = filters.quick.invert;
|
||||
const doThreshold = threshold !== defaultFilters.threshold;
|
||||
const doDesaturate = filters.quick.desaturate;
|
||||
const doWhiteBalance = filters.quick.whiteBalance;
|
||||
const doDuotone = filters.duotone.enabled !== defaultFilters.duotone.enabled;
|
||||
const doHSL = filters.hsl.hue !== 0 || filters.hsl.sat !== 0 || filters.hsl.lightness !== 0;
|
||||
const doBlur = filters.blur > 0;
|
||||
@@ -126,7 +132,7 @@ function renderFiltersWasm( imageData: ImageData, filters: any ): Uint8ClampedAr
|
||||
wasmInstance._filter(
|
||||
memory, length,
|
||||
gamma, brightness, contrast, vibrance,/* threshold, duotone.color1, duotone.color2 */
|
||||
doGamma, desaturate, doBrightness, doContrast, doVibrance/*, doThreshold, doDuotone, doHSL, doBlur*/
|
||||
doGamma, doDesaturate, doBrightness, doContrast, doVibrance/*, doWhiteBalance, doThreshold, doDuotone, doHSL, doBlur*/
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -15,13 +15,16 @@ describe( "Filters factory", () => {
|
||||
contrast: 0,
|
||||
vibrance: .5,
|
||||
threshold: -1,
|
||||
desaturate: false,
|
||||
invert: false,
|
||||
duotone: {
|
||||
enabled: false,
|
||||
color1: DEFAULT_DUOTONE_1,
|
||||
color2: DEFAULT_DUOTONE_2,
|
||||
},
|
||||
quick: {
|
||||
desaturate: false,
|
||||
invert: false,
|
||||
whiteBalance: false,
|
||||
},
|
||||
hsl: {
|
||||
hue: 0,
|
||||
sat: 0,
|
||||
@@ -41,8 +44,11 @@ describe( "Filters factory", () => {
|
||||
contrast: .3,
|
||||
vibrance: .2,
|
||||
threshold: 127,
|
||||
desaturate: true,
|
||||
invert: true,
|
||||
quick: {
|
||||
desaturate: true,
|
||||
invert: true,
|
||||
whiteBalance: true,
|
||||
},
|
||||
duotone: {
|
||||
enabled: true,
|
||||
color1: "#FF9900",
|
||||
@@ -64,8 +70,11 @@ describe( "Filters factory", () => {
|
||||
contrast: .3,
|
||||
vibrance: .2,
|
||||
threshold: 127,
|
||||
desaturate: true,
|
||||
invert: true,
|
||||
quick: {
|
||||
desaturate: true,
|
||||
invert: true,
|
||||
whiteBalance: true,
|
||||
},
|
||||
duotone: {
|
||||
enabled: true,
|
||||
color1: "#FF9900",
|
||||
@@ -92,8 +101,11 @@ describe( "Filters factory", () => {
|
||||
contrast: .3,
|
||||
vibrance: .2,
|
||||
threshold: 255,
|
||||
desaturate: true,
|
||||
invert: true,
|
||||
quick: {
|
||||
desaturate: true,
|
||||
invert: true,
|
||||
whiteBalance: true,
|
||||
},
|
||||
duotone: {
|
||||
enabled: true,
|
||||
color1: "#FF9900",
|
||||
@@ -141,10 +153,13 @@ describe( "Filters factory", () => {
|
||||
filter = FiltersFactory.create({ threshold: 0 });
|
||||
expect( hasFilters( filter )).toBe( true );
|
||||
|
||||
filter = FiltersFactory.create({ desaturate: true });
|
||||
filter = FiltersFactory.create({ quick: { desaturate: true } });
|
||||
expect( hasFilters( filter )).toBe( true );
|
||||
|
||||
filter = FiltersFactory.create({ invert: true });
|
||||
filter = FiltersFactory.create({ quick: { invert: true } });
|
||||
expect( hasFilters( filter )).toBe( true );
|
||||
|
||||
filter = FiltersFactory.create({ quick: { whiteBalance: true } });
|
||||
expect( hasFilters( filter )).toBe( true );
|
||||
|
||||
// we don't need to check for duotone colors as the enabled flag for the Object is sufficient
|
||||
@@ -152,7 +167,7 @@ describe( "Filters factory", () => {
|
||||
filter = FiltersFactory.create({ duotone: { enabled: true }});
|
||||
expect( hasFilters( filter )).toBe( true );
|
||||
|
||||
filter = FiltersFactory.create({ hsl: { hue: 180, sat: 26, lightness: -50 }});
|
||||
filter = FiltersFactory.create({ hsl: { hue: 180 }});
|
||||
expect( hasFilters( filter )).toBe( true );
|
||||
|
||||
filter = FiltersFactory.create({ blur: 25 });
|
||||
@@ -163,15 +178,34 @@ describe( "Filters factory", () => {
|
||||
it( "should know when two filters instances are equal", () => {
|
||||
const defaultFilter = FiltersFactory.create();
|
||||
[
|
||||
"enabled", "blendMode", "opacity",
|
||||
"gamma", "brightness", "contrast",
|
||||
"vibrance", "threshold", "desaturate",
|
||||
"invert", "blur"
|
||||
"enabled", "blendMode", "opacity", "gamma", "brightness", "contrast",
|
||||
"vibrance", "threshold", "blur"
|
||||
]
|
||||
.forEach( property => {
|
||||
const filters = FiltersFactory.create({ [ property ]: .88 });
|
||||
expect( isEqual( filters, defaultFilter )).toBe( false );
|
||||
});
|
||||
|
||||
expect( isEqual(
|
||||
FiltersFactory.create({ quick: { desaturate: true }}), defaultFilter
|
||||
)).toBe( false );
|
||||
|
||||
expect( isEqual(
|
||||
FiltersFactory.create({ quick: { invert: true }}), defaultFilter
|
||||
)).toBe( false );
|
||||
|
||||
expect( isEqual(
|
||||
FiltersFactory.create({ quick: { whiteBalance: true }}), defaultFilter
|
||||
)).toBe( false );
|
||||
|
||||
expect( isEqual(
|
||||
FiltersFactory.create({ duotone: { enabled: true }}), defaultFilter
|
||||
)).toBe( false );
|
||||
|
||||
expect( isEqual(
|
||||
FiltersFactory.create({ hsl: { hue: 90 }}), defaultFilter
|
||||
)).toBe( false );
|
||||
|
||||
expect( isEqual( defaultFilter, FiltersFactory.create() )).toBe( true );
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user