@flighthq/effects 0.3.0-next.906.07cea63 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bevelEffect.d.ts +3 -1
- package/dist/bevelEffect.d.ts.map +1 -1
- package/dist/bevelEffect.js +12 -0
- package/dist/bevelEffect.js.map +1 -1
- package/dist/blendModeMath.d.ts.map +1 -1
- package/dist/blendModeMath.js +4 -0
- package/dist/blendModeMath.js.map +1 -1
- package/dist/bloomEffect.d.ts +3 -1
- package/dist/bloomEffect.d.ts.map +1 -1
- package/dist/bloomEffect.js +11 -0
- package/dist/bloomEffect.js.map +1 -1
- package/dist/blurEffect.d.ts +3 -1
- package/dist/blurEffect.d.ts.map +1 -1
- package/dist/blurEffect.js +10 -0
- package/dist/blurEffect.js.map +1 -1
- package/dist/bokehDepthOfFieldEffect.d.ts +3 -1
- package/dist/bokehDepthOfFieldEffect.d.ts.map +1 -1
- package/dist/bokehDepthOfFieldEffect.js +11 -0
- package/dist/bokehDepthOfFieldEffect.js.map +1 -1
- package/dist/contactShadowsEffect.d.ts +3 -1
- package/dist/contactShadowsEffect.d.ts.map +1 -1
- package/dist/contactShadowsEffect.js +11 -0
- package/dist/contactShadowsEffect.js.map +1 -1
- package/dist/contract.d.ts +1 -0
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +1 -0
- package/dist/contract.js.map +1 -1
- package/dist/convolutionEffect.d.ts +3 -1
- package/dist/convolutionEffect.d.ts.map +1 -1
- package/dist/convolutionEffect.js +17 -0
- package/dist/convolutionEffect.js.map +1 -1
- package/dist/directionalBlurEffect.d.ts +3 -1
- package/dist/directionalBlurEffect.d.ts.map +1 -1
- package/dist/directionalBlurEffect.js +16 -0
- package/dist/directionalBlurEffect.js.map +1 -1
- package/dist/displacementEffect.d.ts +3 -1
- package/dist/displacementEffect.d.ts.map +1 -1
- package/dist/displacementEffect.js +13 -0
- package/dist/displacementEffect.js.map +1 -1
- package/dist/dropShadowEffect.d.ts +3 -1
- package/dist/dropShadowEffect.d.ts.map +1 -1
- package/dist/dropShadowEffect.js +12 -0
- package/dist/dropShadowEffect.js.map +1 -1
- package/dist/glitchEffect.d.ts +3 -1
- package/dist/glitchEffect.d.ts.map +1 -1
- package/dist/glitchEffect.js +13 -0
- package/dist/glitchEffect.js.map +1 -1
- package/dist/gradientBevelEffect.d.ts +3 -1
- package/dist/gradientBevelEffect.d.ts.map +1 -1
- package/dist/gradientBevelEffect.js +12 -0
- package/dist/gradientBevelEffect.js.map +1 -1
- package/dist/gradientGlowEffect.d.ts +3 -1
- package/dist/gradientGlowEffect.d.ts.map +1 -1
- package/dist/gradientGlowEffect.js +10 -0
- package/dist/gradientGlowEffect.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/innerGlowEffect.d.ts +3 -1
- package/dist/innerGlowEffect.d.ts.map +1 -1
- package/dist/innerGlowEffect.js +10 -0
- package/dist/innerGlowEffect.js.map +1 -1
- package/dist/innerShadowEffect.d.ts +3 -1
- package/dist/innerShadowEffect.d.ts.map +1 -1
- package/dist/innerShadowEffect.js +12 -0
- package/dist/innerShadowEffect.js.map +1 -1
- package/dist/medianEffect.d.ts +3 -1
- package/dist/medianEffect.d.ts.map +1 -1
- package/dist/medianEffect.js +11 -0
- package/dist/medianEffect.js.map +1 -1
- package/dist/outerGlowEffect.d.ts +3 -1
- package/dist/outerGlowEffect.d.ts.map +1 -1
- package/dist/outerGlowEffect.js +10 -0
- package/dist/outerGlowEffect.js.map +1 -1
- package/dist/outlineEffect.d.ts +3 -1
- package/dist/outlineEffect.d.ts.map +1 -1
- package/dist/outlineEffect.js +11 -0
- package/dist/outlineEffect.js.map +1 -1
- package/dist/renderEffectPadding.d.ts +7 -0
- package/dist/renderEffectPadding.d.ts.map +1 -0
- package/dist/renderEffectPadding.js +70 -0
- package/dist/renderEffectPadding.js.map +1 -0
- package/dist/tiltShiftEffect.d.ts +3 -1
- package/dist/tiltShiftEffect.d.ts.map +1 -1
- package/dist/tiltShiftEffect.js +11 -0
- package/dist/tiltShiftEffect.js.map +1 -1
- package/package.json +6 -2
- package/src/bevelEffect.test.ts +24 -1
- package/src/blendModeMath.test.ts +15 -0
- package/src/bloomEffect.test.ts +31 -1
- package/src/blurEffect.test.ts +26 -1
- package/src/bokehDepthOfFieldEffect.test.ts +28 -1
- package/src/contactShadowsEffect.test.ts +28 -1
- package/src/convolutionEffect.test.ts +28 -1
- package/src/directionalBlurEffect.test.ts +28 -1
- package/src/displacementEffect.test.ts +28 -1
- package/src/dropShadowEffect.test.ts +28 -1
- package/src/glitchEffect.test.ts +24 -1
- package/src/gradientBevelEffect.test.ts +32 -1
- package/src/gradientGlowEffect.test.ts +27 -1
- package/src/innerGlowEffect.test.ts +28 -1
- package/src/innerShadowEffect.test.ts +30 -1
- package/src/medianEffect.test.ts +24 -1
- package/src/outerGlowEffect.test.ts +28 -1
- package/src/outlineEffect.test.ts +24 -1
- package/src/renderEffectPadding.test.ts +114 -0
- package/src/tiltShiftEffect.test.ts +28 -1
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createRenderState, getRenderStateRuntime } from '@flighthq/render/contract';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
createConvolutionEffect,
|
|
5
|
+
getConvolutionEffectPadding,
|
|
6
|
+
registerConvolutionEffectPaddingResolver,
|
|
7
|
+
} from './convolutionEffect';
|
|
2
8
|
|
|
3
9
|
describe('createConvolutionEffect', () => {
|
|
4
10
|
it('tags the intent type', () => {
|
|
@@ -18,3 +24,24 @@ describe('createConvolutionEffect', () => {
|
|
|
18
24
|
expect(effect).toMatchObject({ bias: 8, preserveAlpha: false });
|
|
19
25
|
});
|
|
20
26
|
});
|
|
27
|
+
|
|
28
|
+
describe('getConvolutionEffectPadding', () => {
|
|
29
|
+
it('preserves the exact asymmetric reach of even kernels', () => {
|
|
30
|
+
expect(getConvolutionEffectPadding(createConvolutionEffect({ matrix: [1, 1], matrixX: 2, matrixY: 1 }))).toEqual({
|
|
31
|
+
bottom: 0,
|
|
32
|
+
left: 0,
|
|
33
|
+
right: 1,
|
|
34
|
+
top: 0,
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('registerConvolutionEffectPaddingResolver', () => {
|
|
40
|
+
it('registers the convolution footprint on only the supplied state', () => {
|
|
41
|
+
const state = createRenderState();
|
|
42
|
+
const other = createRenderState();
|
|
43
|
+
registerConvolutionEffectPaddingResolver(state);
|
|
44
|
+
expect(getRenderStateRuntime(state).renderEffectPaddingResolverRegistry?.has('ConvolutionEffect')).toBe(true);
|
|
45
|
+
expect(getRenderStateRuntime(other).renderEffectPaddingResolverRegistry).toBeNull();
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createRenderState, getRenderStateRuntime } from '@flighthq/render/contract';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
createDirectionalBlurEffect,
|
|
5
|
+
getDirectionalBlurEffectPadding,
|
|
6
|
+
registerDirectionalBlurEffectPaddingResolver,
|
|
7
|
+
} from './directionalBlurEffect';
|
|
2
8
|
|
|
3
9
|
describe('createDirectionalBlurEffect', () => {
|
|
4
10
|
it('tags the intent type', () => {
|
|
@@ -9,3 +15,24 @@ describe('createDirectionalBlurEffect', () => {
|
|
|
9
15
|
expect(createDirectionalBlurEffect({ angle: 1, length: 8 })).toMatchObject({ angle: 1, length: 8 });
|
|
10
16
|
});
|
|
11
17
|
});
|
|
18
|
+
|
|
19
|
+
describe('getDirectionalBlurEffectPadding', () => {
|
|
20
|
+
it('projects the centered half-length onto both axes', () => {
|
|
21
|
+
expect(getDirectionalBlurEffectPadding(createDirectionalBlurEffect({ angle: Math.PI / 2, length: 9 }))).toEqual({
|
|
22
|
+
bottom: 5,
|
|
23
|
+
left: 0,
|
|
24
|
+
right: 0,
|
|
25
|
+
top: 5,
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe('registerDirectionalBlurEffectPaddingResolver', () => {
|
|
31
|
+
it('registers the directional-blur footprint on only the supplied state', () => {
|
|
32
|
+
const state = createRenderState();
|
|
33
|
+
const other = createRenderState();
|
|
34
|
+
registerDirectionalBlurEffectPaddingResolver(state);
|
|
35
|
+
expect(getRenderStateRuntime(state).renderEffectPaddingResolverRegistry?.has('DirectionalBlurEffect')).toBe(true);
|
|
36
|
+
expect(getRenderStateRuntime(other).renderEffectPaddingResolverRegistry).toBeNull();
|
|
37
|
+
});
|
|
38
|
+
});
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createRenderState, getRenderStateRuntime } from '@flighthq/render/contract';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
createDisplacementEffect,
|
|
5
|
+
getDisplacementEffectPadding,
|
|
6
|
+
registerDisplacementEffectPaddingResolver,
|
|
7
|
+
} from './displacementEffect';
|
|
2
8
|
|
|
3
9
|
describe('createDisplacementEffect', () => {
|
|
4
10
|
it('tags the intent type', () => {
|
|
@@ -13,3 +19,24 @@ describe('createDisplacementEffect', () => {
|
|
|
13
19
|
});
|
|
14
20
|
});
|
|
15
21
|
});
|
|
22
|
+
|
|
23
|
+
describe('getDisplacementEffectPadding', () => {
|
|
24
|
+
it('covers the shader maximum two-axis sine warp', () => {
|
|
25
|
+
expect(getDisplacementEffectPadding(createDisplacementEffect({ intensity: 5 }))).toEqual({
|
|
26
|
+
bottom: 5,
|
|
27
|
+
left: 8,
|
|
28
|
+
right: 8,
|
|
29
|
+
top: 5,
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe('registerDisplacementEffectPaddingResolver', () => {
|
|
35
|
+
it('registers the displacement footprint on only the supplied state', () => {
|
|
36
|
+
const state = createRenderState();
|
|
37
|
+
const other = createRenderState();
|
|
38
|
+
registerDisplacementEffectPaddingResolver(state);
|
|
39
|
+
expect(getRenderStateRuntime(state).renderEffectPaddingResolverRegistry?.has('DisplacementEffect')).toBe(true);
|
|
40
|
+
expect(getRenderStateRuntime(other).renderEffectPaddingResolverRegistry).toBeNull();
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createRenderState, getRenderStateRuntime } from '@flighthq/render/contract';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
createDropShadowEffect,
|
|
5
|
+
getDropShadowEffectPadding,
|
|
6
|
+
registerDropShadowEffectPaddingResolver,
|
|
7
|
+
} from './dropShadowEffect';
|
|
2
8
|
|
|
3
9
|
describe('createDropShadowEffect', () => {
|
|
4
10
|
it('tags the intent type', () => {
|
|
@@ -12,3 +18,24 @@ describe('createDropShadowEffect', () => {
|
|
|
12
18
|
});
|
|
13
19
|
});
|
|
14
20
|
});
|
|
21
|
+
|
|
22
|
+
describe('getDropShadowEffectPadding', () => {
|
|
23
|
+
it('adds the offset only to the reached side of the Gaussian footprint', () => {
|
|
24
|
+
expect(getDropShadowEffectPadding(createDropShadowEffect({ angle: 0, blurX: 2, blurY: 3, distance: 5 }))).toEqual({
|
|
25
|
+
bottom: 9,
|
|
26
|
+
left: 6,
|
|
27
|
+
right: 11,
|
|
28
|
+
top: 9,
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe('registerDropShadowEffectPaddingResolver', () => {
|
|
34
|
+
it('registers the drop-shadow footprint on only the supplied state', () => {
|
|
35
|
+
const state = createRenderState();
|
|
36
|
+
const other = createRenderState();
|
|
37
|
+
registerDropShadowEffectPaddingResolver(state);
|
|
38
|
+
expect(getRenderStateRuntime(state).renderEffectPaddingResolverRegistry?.has('DropShadowEffect')).toBe(true);
|
|
39
|
+
expect(getRenderStateRuntime(other).renderEffectPaddingResolverRegistry).toBeNull();
|
|
40
|
+
});
|
|
41
|
+
});
|
package/src/glitchEffect.test.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createRenderState, getRenderStateRuntime } from '@flighthq/render/contract';
|
|
2
|
+
|
|
3
|
+
import { createGlitchEffect, getGlitchEffectPadding, registerGlitchEffectPaddingResolver } from './glitchEffect';
|
|
2
4
|
|
|
3
5
|
describe('createGlitchEffect', () => {
|
|
4
6
|
it('tags the intent type', () => {
|
|
@@ -14,3 +16,24 @@ describe('createGlitchEffect', () => {
|
|
|
14
16
|
});
|
|
15
17
|
});
|
|
16
18
|
});
|
|
19
|
+
|
|
20
|
+
describe('getGlitchEffectPadding', () => {
|
|
21
|
+
it('covers horizontal tears and the maximum RGB channel separation', () => {
|
|
22
|
+
expect(getGlitchEffectPadding(createGlitchEffect({ colorShift: 10, intensity: 0.5 }))).toEqual({
|
|
23
|
+
bottom: 0,
|
|
24
|
+
left: 34,
|
|
25
|
+
right: 34,
|
|
26
|
+
top: 0,
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
describe('registerGlitchEffectPaddingResolver', () => {
|
|
32
|
+
it('registers the glitch footprint on only the supplied state', () => {
|
|
33
|
+
const state = createRenderState();
|
|
34
|
+
const other = createRenderState();
|
|
35
|
+
registerGlitchEffectPaddingResolver(state);
|
|
36
|
+
expect(getRenderStateRuntime(state).renderEffectPaddingResolverRegistry?.has('GlitchEffect')).toBe(true);
|
|
37
|
+
expect(getRenderStateRuntime(other).renderEffectPaddingResolverRegistry).toBeNull();
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createRenderState, getRenderStateRuntime } from '@flighthq/render/contract';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
createGradientBevelEffect,
|
|
5
|
+
getGradientBevelEffectPadding,
|
|
6
|
+
registerGradientBevelEffectPaddingResolver,
|
|
7
|
+
} from './gradientBevelEffect';
|
|
2
8
|
|
|
3
9
|
describe('createGradientBevelEffect', () => {
|
|
4
10
|
it('tags the intent type', () => {
|
|
@@ -19,3 +25,28 @@ describe('createGradientBevelEffect', () => {
|
|
|
19
25
|
).toMatchObject({ sourceMode: 'hide', strength: 2 });
|
|
20
26
|
});
|
|
21
27
|
});
|
|
28
|
+
|
|
29
|
+
describe('getGradientBevelEffectPadding', () => {
|
|
30
|
+
it('adds the directional offset only to the reached sides of the Gaussian footprint', () => {
|
|
31
|
+
const effect = createGradientBevelEffect({
|
|
32
|
+
alphas: [1, 1],
|
|
33
|
+
angle: -90,
|
|
34
|
+
blurX: 2,
|
|
35
|
+
blurY: 3,
|
|
36
|
+
colors: [0xff0000, 0x00ff00],
|
|
37
|
+
distance: 5,
|
|
38
|
+
ratios: [0, 255],
|
|
39
|
+
});
|
|
40
|
+
expect(getGradientBevelEffectPadding(effect)).toEqual({ bottom: 9, left: 6, right: 6, top: 14 });
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe('registerGradientBevelEffectPaddingResolver', () => {
|
|
45
|
+
it('registers the gradient-bevel footprint on only the supplied state', () => {
|
|
46
|
+
const state = createRenderState();
|
|
47
|
+
const other = createRenderState();
|
|
48
|
+
registerGradientBevelEffectPaddingResolver(state);
|
|
49
|
+
expect(getRenderStateRuntime(state).renderEffectPaddingResolverRegistry?.has('GradientBevelEffect')).toBe(true);
|
|
50
|
+
expect(getRenderStateRuntime(other).renderEffectPaddingResolverRegistry).toBeNull();
|
|
51
|
+
});
|
|
52
|
+
});
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createRenderState, getRenderStateRuntime } from '@flighthq/render/contract';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
createGradientGlowEffect,
|
|
5
|
+
getGradientGlowEffectPadding,
|
|
6
|
+
registerGradientGlowEffectPaddingResolver,
|
|
7
|
+
} from './gradientGlowEffect';
|
|
2
8
|
|
|
3
9
|
describe('createGradientGlowEffect', () => {
|
|
4
10
|
it('tags the intent type', () => {
|
|
@@ -19,3 +25,23 @@ describe('createGradientGlowEffect', () => {
|
|
|
19
25
|
).toMatchObject({ sourceMode: 'knockout', strength: 2 });
|
|
20
26
|
});
|
|
21
27
|
});
|
|
28
|
+
|
|
29
|
+
describe('getGradientGlowEffectPadding', () => {
|
|
30
|
+
it('uses the three-sigma extent independently on both axes', () => {
|
|
31
|
+
expect(
|
|
32
|
+
getGradientGlowEffectPadding(
|
|
33
|
+
createGradientGlowEffect({ alphas: [1], blurX: 2.1, blurY: 3, colors: [0xffffff], ratios: [0] }),
|
|
34
|
+
),
|
|
35
|
+
).toEqual({ bottom: 9, left: 7, right: 7, top: 9 });
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('registerGradientGlowEffectPaddingResolver', () => {
|
|
40
|
+
it('registers the gradient-glow footprint on only the supplied state', () => {
|
|
41
|
+
const state = createRenderState();
|
|
42
|
+
const other = createRenderState();
|
|
43
|
+
registerGradientGlowEffectPaddingResolver(state);
|
|
44
|
+
expect(getRenderStateRuntime(state).renderEffectPaddingResolverRegistry?.has('GradientGlowEffect')).toBe(true);
|
|
45
|
+
expect(getRenderStateRuntime(other).renderEffectPaddingResolverRegistry).toBeNull();
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createRenderState, getRenderStateRuntime } from '@flighthq/render/contract';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
createInnerGlowEffect,
|
|
5
|
+
getInnerGlowEffectPadding,
|
|
6
|
+
registerInnerGlowEffectPaddingResolver,
|
|
7
|
+
} from './innerGlowEffect';
|
|
2
8
|
|
|
3
9
|
describe('createInnerGlowEffect', () => {
|
|
4
10
|
it('tags the intent type', () => {
|
|
@@ -13,3 +19,24 @@ describe('createInnerGlowEffect', () => {
|
|
|
13
19
|
expect(createInnerGlowEffect({ sourceMode: 'hide' })).toMatchObject({ sourceMode: 'hide' });
|
|
14
20
|
});
|
|
15
21
|
});
|
|
22
|
+
|
|
23
|
+
describe('getInnerGlowEffectPadding', () => {
|
|
24
|
+
it('uses a three-sigma Gaussian footprint', () => {
|
|
25
|
+
expect(getInnerGlowEffectPadding(createInnerGlowEffect({ blurX: 2, blurY: 3 }))).toEqual({
|
|
26
|
+
bottom: 9,
|
|
27
|
+
left: 6,
|
|
28
|
+
right: 6,
|
|
29
|
+
top: 9,
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe('registerInnerGlowEffectPaddingResolver', () => {
|
|
35
|
+
it('registers the inner-glow footprint on only the supplied state', () => {
|
|
36
|
+
const state = createRenderState();
|
|
37
|
+
const other = createRenderState();
|
|
38
|
+
registerInnerGlowEffectPaddingResolver(state);
|
|
39
|
+
expect(getRenderStateRuntime(state).renderEffectPaddingResolverRegistry?.has('InnerGlowEffect')).toBe(true);
|
|
40
|
+
expect(getRenderStateRuntime(other).renderEffectPaddingResolverRegistry).toBeNull();
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createRenderState, getRenderStateRuntime } from '@flighthq/render/contract';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
createInnerShadowEffect,
|
|
5
|
+
getInnerShadowEffectPadding,
|
|
6
|
+
registerInnerShadowEffectPaddingResolver,
|
|
7
|
+
} from './innerShadowEffect';
|
|
2
8
|
|
|
3
9
|
describe('createInnerShadowEffect', () => {
|
|
4
10
|
it('tags the intent type', () => {
|
|
@@ -13,3 +19,26 @@ describe('createInnerShadowEffect', () => {
|
|
|
13
19
|
expect(createInnerShadowEffect({ sourceMode: 'hide' })).toMatchObject({ sourceMode: 'hide' });
|
|
14
20
|
});
|
|
15
21
|
});
|
|
22
|
+
|
|
23
|
+
describe('getInnerShadowEffectPadding', () => {
|
|
24
|
+
it('preserves the directional exterior samples needed by the clipped inner pass', () => {
|
|
25
|
+
expect(
|
|
26
|
+
getInnerShadowEffectPadding(createInnerShadowEffect({ angle: 90, blurX: 2, blurY: 3, distance: 5 })),
|
|
27
|
+
).toEqual({
|
|
28
|
+
bottom: 14,
|
|
29
|
+
left: 6,
|
|
30
|
+
right: 6,
|
|
31
|
+
top: 9,
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe('registerInnerShadowEffectPaddingResolver', () => {
|
|
37
|
+
it('registers the inner-shadow footprint on only the supplied state', () => {
|
|
38
|
+
const state = createRenderState();
|
|
39
|
+
const other = createRenderState();
|
|
40
|
+
registerInnerShadowEffectPaddingResolver(state);
|
|
41
|
+
expect(getRenderStateRuntime(state).renderEffectPaddingResolverRegistry?.has('InnerShadowEffect')).toBe(true);
|
|
42
|
+
expect(getRenderStateRuntime(other).renderEffectPaddingResolverRegistry).toBeNull();
|
|
43
|
+
});
|
|
44
|
+
});
|
package/src/medianEffect.test.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createRenderState, getRenderStateRuntime } from '@flighthq/render/contract';
|
|
2
|
+
|
|
3
|
+
import { createMedianEffect, getMedianEffectPadding, registerMedianEffectPaddingResolver } from './medianEffect';
|
|
2
4
|
|
|
3
5
|
describe('createMedianEffect', () => {
|
|
4
6
|
it('tags the intent type', () => {
|
|
@@ -9,3 +11,24 @@ describe('createMedianEffect', () => {
|
|
|
9
11
|
expect(createMedianEffect({ radius: 2 })).toMatchObject({ radius: 2 });
|
|
10
12
|
});
|
|
11
13
|
});
|
|
14
|
+
|
|
15
|
+
describe('getMedianEffectPadding', () => {
|
|
16
|
+
it('uses the rounded neighborhood radius on every side', () => {
|
|
17
|
+
expect(getMedianEffectPadding(createMedianEffect({ radius: 1.6 }))).toEqual({
|
|
18
|
+
bottom: 2,
|
|
19
|
+
left: 2,
|
|
20
|
+
right: 2,
|
|
21
|
+
top: 2,
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe('registerMedianEffectPaddingResolver', () => {
|
|
27
|
+
it('registers the median footprint on only the supplied state', () => {
|
|
28
|
+
const state = createRenderState();
|
|
29
|
+
const other = createRenderState();
|
|
30
|
+
registerMedianEffectPaddingResolver(state);
|
|
31
|
+
expect(getRenderStateRuntime(state).renderEffectPaddingResolverRegistry?.has('MedianEffect')).toBe(true);
|
|
32
|
+
expect(getRenderStateRuntime(other).renderEffectPaddingResolverRegistry).toBeNull();
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createRenderState, getRenderStateRuntime } from '@flighthq/render/contract';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
createOuterGlowEffect,
|
|
5
|
+
getOuterGlowEffectPadding,
|
|
6
|
+
registerOuterGlowEffectPaddingResolver,
|
|
7
|
+
} from './outerGlowEffect';
|
|
2
8
|
|
|
3
9
|
describe('createOuterGlowEffect', () => {
|
|
4
10
|
it('tags the intent type', () => {
|
|
@@ -12,3 +18,24 @@ describe('createOuterGlowEffect', () => {
|
|
|
12
18
|
});
|
|
13
19
|
});
|
|
14
20
|
});
|
|
21
|
+
|
|
22
|
+
describe('getOuterGlowEffectPadding', () => {
|
|
23
|
+
it('uses a three-sigma Gaussian footprint', () => {
|
|
24
|
+
expect(getOuterGlowEffectPadding(createOuterGlowEffect({ blurX: 2, blurY: 3 }))).toEqual({
|
|
25
|
+
bottom: 9,
|
|
26
|
+
left: 6,
|
|
27
|
+
right: 6,
|
|
28
|
+
top: 9,
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe('registerOuterGlowEffectPaddingResolver', () => {
|
|
34
|
+
it('registers the outer-glow footprint on only the supplied state', () => {
|
|
35
|
+
const state = createRenderState();
|
|
36
|
+
const other = createRenderState();
|
|
37
|
+
registerOuterGlowEffectPaddingResolver(state);
|
|
38
|
+
expect(getRenderStateRuntime(state).renderEffectPaddingResolverRegistry?.has('OuterGlowEffect')).toBe(true);
|
|
39
|
+
expect(getRenderStateRuntime(other).renderEffectPaddingResolverRegistry).toBeNull();
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createRenderState, getRenderStateRuntime } from '@flighthq/render/contract';
|
|
2
|
+
|
|
3
|
+
import { createOutlineEffect, getOutlineEffectPadding, registerOutlineEffectPaddingResolver } from './outlineEffect';
|
|
2
4
|
|
|
3
5
|
describe('createOutlineEffect', () => {
|
|
4
6
|
it('tags the intent type', () => {
|
|
@@ -13,3 +15,24 @@ describe('createOutlineEffect', () => {
|
|
|
13
15
|
});
|
|
14
16
|
});
|
|
15
17
|
});
|
|
18
|
+
|
|
19
|
+
describe('getOutlineEffectPadding', () => {
|
|
20
|
+
it('uses the Sobel sampling thickness on every side', () => {
|
|
21
|
+
expect(getOutlineEffectPadding(createOutlineEffect({ thickness: 1.5 }))).toEqual({
|
|
22
|
+
bottom: 2,
|
|
23
|
+
left: 2,
|
|
24
|
+
right: 2,
|
|
25
|
+
top: 2,
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe('registerOutlineEffectPaddingResolver', () => {
|
|
31
|
+
it('registers the outline footprint on only the supplied state', () => {
|
|
32
|
+
const state = createRenderState();
|
|
33
|
+
const other = createRenderState();
|
|
34
|
+
registerOutlineEffectPaddingResolver(state);
|
|
35
|
+
expect(getRenderStateRuntime(state).renderEffectPaddingResolverRegistry?.has('OutlineEffect')).toBe(true);
|
|
36
|
+
expect(getRenderStateRuntime(other).renderEffectPaddingResolverRegistry).toBeNull();
|
|
37
|
+
});
|
|
38
|
+
});
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { createRenderState, enableRenderRegistrySignals, getRenderStateRuntime } from '@flighthq/render/contract';
|
|
2
|
+
import { connectSignal } from '@flighthq/signals/contract';
|
|
3
|
+
import type { RenderEffect, RenderState } from '@flighthq/types/contract';
|
|
4
|
+
import { RenderRegistry } from '@flighthq/types/contract';
|
|
5
|
+
|
|
6
|
+
import { createBlurEffect, registerBlurEffectPaddingResolver } from './blurEffect';
|
|
7
|
+
import {
|
|
8
|
+
computeRenderEffectPadding,
|
|
9
|
+
explainRenderEffectPadding,
|
|
10
|
+
getDirectionalRenderEffectPadding,
|
|
11
|
+
getGaussianRenderEffectPadding,
|
|
12
|
+
registerRenderEffectPaddingResolver,
|
|
13
|
+
} from './renderEffectPadding';
|
|
14
|
+
|
|
15
|
+
describe('computeRenderEffectPadding', () => {
|
|
16
|
+
let state: RenderState;
|
|
17
|
+
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
state = createRenderState();
|
|
20
|
+
registerBlurEffectPaddingResolver(state);
|
|
21
|
+
registerRenderEffectPaddingResolver(state, 'acme.Pointwise', () => ({
|
|
22
|
+
bottom: 0,
|
|
23
|
+
left: 0,
|
|
24
|
+
right: 0,
|
|
25
|
+
top: 0,
|
|
26
|
+
}));
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('adds each side across a sequential effect chain while pointwise effects add zero', () => {
|
|
30
|
+
expect(
|
|
31
|
+
computeRenderEffectPadding(state, [
|
|
32
|
+
createBlurEffect({ blurX: 2, blurY: 1 }),
|
|
33
|
+
{ kind: 'acme.Pointwise' } as RenderEffect,
|
|
34
|
+
createBlurEffect({ blurX: 1, blurY: 4 }),
|
|
35
|
+
]),
|
|
36
|
+
).toEqual({ bottom: 15, left: 9, right: 9, top: 15 });
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('returns a zero sentinel for an unregistered kind', () => {
|
|
40
|
+
const effect = { kind: 'acme.Missing' } as RenderEffect;
|
|
41
|
+
expect(computeRenderEffectPadding(state, effect)).toEqual({ bottom: 0, left: 0, right: 0, top: 0 });
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('emits a shared registry miss only when the signal seam is enabled', () => {
|
|
45
|
+
const misses: Array<readonly [RenderRegistry, string]> = [];
|
|
46
|
+
connectSignal(enableRenderRegistrySignals(state).onRegistryMiss, (registry, kind) => {
|
|
47
|
+
misses.push([registry, kind]);
|
|
48
|
+
});
|
|
49
|
+
expect(computeRenderEffectPadding(state, { kind: 'acme.Missing' } as RenderEffect)).toEqual({
|
|
50
|
+
bottom: 0,
|
|
51
|
+
left: 0,
|
|
52
|
+
right: 0,
|
|
53
|
+
top: 0,
|
|
54
|
+
});
|
|
55
|
+
expect(misses).toEqual([[RenderRegistry.EffectPaddingResolver, 'acme.Missing']]);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
describe('explainRenderEffectPadding', () => {
|
|
60
|
+
it('reports every missing resolver kind while preserving resolved padding', () => {
|
|
61
|
+
const state = createRenderState();
|
|
62
|
+
registerBlurEffectPaddingResolver(state);
|
|
63
|
+
|
|
64
|
+
expect(
|
|
65
|
+
explainRenderEffectPadding(state, [
|
|
66
|
+
createBlurEffect({ blurX: 2, blurY: 3 }),
|
|
67
|
+
{ kind: 'acme.Missing' } as RenderEffect,
|
|
68
|
+
]),
|
|
69
|
+
).toEqual({
|
|
70
|
+
missingKinds: ['acme.Missing'],
|
|
71
|
+
padding: { bottom: 9, left: 6, right: 6, top: 9 },
|
|
72
|
+
status: 'missing-resolver',
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
describe('getDirectionalRenderEffectPadding', () => {
|
|
78
|
+
it('adds positive screen-space offsets only to the reached sides', () => {
|
|
79
|
+
expect(getDirectionalRenderEffectPadding(2, 3, 4.25, 5.5)).toEqual({
|
|
80
|
+
bottom: 15,
|
|
81
|
+
left: 6,
|
|
82
|
+
right: 11,
|
|
83
|
+
top: 9,
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('adds negative screen-space offsets only to left and top', () => {
|
|
88
|
+
expect(getDirectionalRenderEffectPadding(1, 1, -2.5, -4.25)).toEqual({
|
|
89
|
+
bottom: 3,
|
|
90
|
+
left: 6,
|
|
91
|
+
right: 3,
|
|
92
|
+
top: 8,
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
describe('getGaussianRenderEffectPadding', () => {
|
|
98
|
+
it('uses a sanitized three-sigma extent on each axis', () => {
|
|
99
|
+
expect(getGaussianRenderEffectPadding(2.1, -4)).toEqual({ bottom: 0, left: 7, right: 7, top: 0 });
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
describe('registerRenderEffectPaddingResolver', () => {
|
|
104
|
+
it('adds and removes a state-local resolver', () => {
|
|
105
|
+
const state = createRenderState();
|
|
106
|
+
const resolver = vi.fn(() => ({ bottom: 1, left: 2, right: 3, top: 4 }));
|
|
107
|
+
|
|
108
|
+
registerRenderEffectPaddingResolver(state, 'acme.Effect', resolver);
|
|
109
|
+
expect(getRenderStateRuntime(state).renderEffectPaddingResolverRegistry?.get('acme.Effect')).toBe(resolver);
|
|
110
|
+
|
|
111
|
+
registerRenderEffectPaddingResolver(state, 'acme.Effect', null);
|
|
112
|
+
expect(getRenderStateRuntime(state).renderEffectPaddingResolverRegistry?.has('acme.Effect')).toBe(false);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createRenderState, getRenderStateRuntime } from '@flighthq/render/contract';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
createTiltShiftEffect,
|
|
5
|
+
getTiltShiftEffectPadding,
|
|
6
|
+
registerTiltShiftEffectPaddingResolver,
|
|
7
|
+
} from './tiltShiftEffect';
|
|
2
8
|
|
|
3
9
|
describe('createTiltShiftEffect', () => {
|
|
4
10
|
it('tags the intent type', () => {
|
|
@@ -13,3 +19,24 @@ describe('createTiltShiftEffect', () => {
|
|
|
13
19
|
});
|
|
14
20
|
});
|
|
15
21
|
});
|
|
22
|
+
|
|
23
|
+
describe('getTiltShiftEffectPadding', () => {
|
|
24
|
+
it('covers the seven-tap vertical blur reach', () => {
|
|
25
|
+
expect(getTiltShiftEffectPadding(createTiltShiftEffect({ blur: 2.5 }))).toEqual({
|
|
26
|
+
bottom: 8,
|
|
27
|
+
left: 0,
|
|
28
|
+
right: 0,
|
|
29
|
+
top: 8,
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe('registerTiltShiftEffectPaddingResolver', () => {
|
|
35
|
+
it('registers the tilt-shift footprint on only the supplied state', () => {
|
|
36
|
+
const state = createRenderState();
|
|
37
|
+
const other = createRenderState();
|
|
38
|
+
registerTiltShiftEffectPaddingResolver(state);
|
|
39
|
+
expect(getRenderStateRuntime(state).renderEffectPaddingResolverRegistry?.has('TiltShiftEffect')).toBe(true);
|
|
40
|
+
expect(getRenderStateRuntime(other).renderEffectPaddingResolverRegistry).toBeNull();
|
|
41
|
+
});
|
|
42
|
+
});
|