@radialapps/memories-vips-editor 0.1.5 → 0.1.6
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/README.md +1 -0
- package/dist/transforms/flip.d.ts +18 -0
- package/dist/transforms/flip.d.ts.map +1 -0
- package/dist/transforms/flip.js +43 -0
- package/dist/transforms/flip.js.map +1 -0
- package/dist/transforms/index.d.ts.map +1 -1
- package/dist/transforms/index.js +2 -0
- package/dist/transforms/index.js.map +1 -1
- package/dist/types.d.ts +3 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/src/transforms/flip.ts +64 -0
- package/src/transforms/index.ts +2 -0
- package/src/types.ts +5 -2
package/README.md
CHANGED
|
@@ -100,6 +100,7 @@ multiples stay exact with no band change.
|
|
|
100
100
|
| `blur` / `sharpen` | `radius` 0..100 / +`amount` 0..5 | shared kernel + `convsep` (mix) |
|
|
101
101
|
| `crop` | `x`,`y`,`width`,`height` 0..1 fractions | `extract_area` (rounded+clamped) |
|
|
102
102
|
| `rotate` | `angle` −180..180 (clockwise °) | `rot()` @90s, else `rotate()` |
|
|
103
|
+
| `flip` | `direction` horizontal/vertical | `fliphor` / `flipver` |
|
|
103
104
|
|
|
104
105
|
Excluded (no clean VIPS mapping): `denoise`, `noise`, `curves`,
|
|
105
106
|
`lensBlur`/`tiltShift`/`zoomBlur`, halftones, warps.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ParamControl, RenderContext, Target, Transform } from './transform.js';
|
|
2
|
+
export type FlipDirection = 'horizontal' | 'vertical';
|
|
3
|
+
export interface FlipEdit {
|
|
4
|
+
edit: 'flip';
|
|
5
|
+
/** Mirror axis: 'horizontal' mirrors left-right. Default 'horizontal'. */
|
|
6
|
+
direction?: FlipDirection;
|
|
7
|
+
}
|
|
8
|
+
type Full = Required<FlipEdit>;
|
|
9
|
+
export declare class FlipTransform implements Transform<'flip', FlipEdit> {
|
|
10
|
+
readonly edit: "flip";
|
|
11
|
+
controls: ParamControl[];
|
|
12
|
+
defaults(): Full;
|
|
13
|
+
validate(params: FlipEdit): string[];
|
|
14
|
+
normalize(params: FlipEdit): Full;
|
|
15
|
+
apply(ctx: RenderContext, from: Target, to: Target, params: Full): Target;
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=flip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flip.d.ts","sourceRoot":"","sources":["../../src/transforms/flip.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAErF,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,UAAU,CAAC;AAEtD,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B;AAED,KAAK,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAe/B,qBAAa,aAAc,YAAW,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC/D,SAAgB,IAAI,EAAG,MAAM,CAAU;IAChC,QAAQ,EAAE,YAAY,EAAE,CAAM;IAE9B,QAAQ,IAAI,IAAI;IAIhB,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,EAAE;IAUpC,SAAS,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI;IAOjC,KAAK,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAG,MAAM;CAOjF"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const FRAG = `
|
|
2
|
+
precision mediump float;
|
|
3
|
+
uniform sampler2D texture;
|
|
4
|
+
uniform int vertical;
|
|
5
|
+
varying vec2 texCoord;
|
|
6
|
+
void main() {
|
|
7
|
+
vec2 uv = vertical == 1
|
|
8
|
+
? vec2(texCoord.x, 1.0 - texCoord.y)
|
|
9
|
+
: vec2(1.0 - texCoord.x, texCoord.y);
|
|
10
|
+
gl_FragColor = texture2D(texture, uv);
|
|
11
|
+
}
|
|
12
|
+
`;
|
|
13
|
+
export class FlipTransform {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.edit = 'flip';
|
|
16
|
+
this.controls = [];
|
|
17
|
+
}
|
|
18
|
+
defaults() {
|
|
19
|
+
return { edit: 'flip', direction: 'horizontal' };
|
|
20
|
+
}
|
|
21
|
+
validate(params) {
|
|
22
|
+
if (params.direction !== undefined &&
|
|
23
|
+
params.direction !== 'horizontal' &&
|
|
24
|
+
params.direction !== 'vertical')
|
|
25
|
+
return ['direction must be "horizontal" or "vertical"'];
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
normalize(params) {
|
|
29
|
+
return {
|
|
30
|
+
edit: 'flip',
|
|
31
|
+
direction: params.direction === 'vertical' ? 'vertical' : 'horizontal',
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
apply(ctx, from, to, params) {
|
|
35
|
+
ctx.pass(FRAG, from, to, (gl, p) => {
|
|
36
|
+
const uV = gl.getUniformLocation(p, 'vertical');
|
|
37
|
+
if (uV)
|
|
38
|
+
gl.uniform1i(uV, params.direction === 'vertical' ? 1 : 0);
|
|
39
|
+
});
|
|
40
|
+
return to;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=flip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flip.js","sourceRoot":"","sources":["../../src/transforms/flip.ts"],"names":[],"mappings":"AAkBA,MAAM,IAAI,GAAG;;;;;;;;;;;CAWZ,CAAC;AAEF,MAAM,OAAO,aAAa;IAA1B;QACkB,SAAI,GAAG,MAAe,CAAC;QAChC,aAAQ,GAAmB,EAAE,CAAC;IA8BvC,CAAC;IA5BQ,QAAQ;QACb,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;IACnD,CAAC;IAEM,QAAQ,CAAC,MAAgB;QAC9B,IACE,MAAM,CAAC,SAAS,KAAK,SAAS;YAC9B,MAAM,CAAC,SAAS,KAAK,YAAY;YACjC,MAAM,CAAC,SAAS,KAAK,UAAU;YAE/B,OAAO,CAAC,8CAA8C,CAAC,CAAC;QAC1D,OAAO,EAAE,CAAC;IACZ,CAAC;IAEM,SAAS,CAAC,MAAgB;QAC/B,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,SAAS,EAAE,MAAM,CAAC,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY;SACvE,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,GAAkB,EAAE,IAAY,EAAE,EAAU,EAAE,MAAY;QACrE,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;YACjC,MAAM,EAAE,GAAG,EAAE,CAAC,kBAAkB,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;YAChD,IAAI,EAAE;gBAAE,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;QACH,OAAO,EAAE,CAAC;IACZ,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transforms/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAU,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transforms/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAU,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAkBxD,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAiBlE,CAAC;AAEF,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,CAKjD;AAED,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAI9C"}
|
package/dist/transforms/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { BlurTransform } from './blur.js';
|
|
|
3
3
|
import { BrightnessContrastTransform } from './brightnessContrast.js';
|
|
4
4
|
import { CropTransform } from './crop.js';
|
|
5
5
|
import { ExposureTransform } from './exposure.js';
|
|
6
|
+
import { FlipTransform } from './flip.js';
|
|
6
7
|
import { GrayscaleTransform } from './grayscale.js';
|
|
7
8
|
import { HighlightsTransform } from './highlights.js';
|
|
8
9
|
import { HueSaturationTransform } from './hueSaturation.js';
|
|
@@ -30,6 +31,7 @@ export const TRANSFORMS = {
|
|
|
30
31
|
grayscale: new GrayscaleTransform(),
|
|
31
32
|
crop: new CropTransform(),
|
|
32
33
|
rotate: new RotateTransform(),
|
|
34
|
+
flip: new FlipTransform(),
|
|
33
35
|
};
|
|
34
36
|
/** Human-readable problems; empty means the edit is VIPS-appliable. */
|
|
35
37
|
export function validateEdit(edit) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/transforms/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,MAAM,EAAkB,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,CAAC,MAAM,UAAU,GAAgD;IACrE,kBAAkB,EAAE,IAAI,2BAA2B,EAAE;IACrD,QAAQ,EAAE,IAAI,iBAAiB,EAAE;IACjC,aAAa,EAAE,IAAI,sBAAsB,EAAE;IAC3C,KAAK,EAAE,IAAI,cAAc,EAAE;IAC3B,QAAQ,EAAE,IAAI,iBAAiB,EAAE;IACjC,IAAI,EAAE,IAAI,aAAa,EAAE;IACzB,OAAO,EAAE,IAAI,gBAAgB,EAAE;IAC/B,QAAQ,EAAE,IAAI,iBAAiB,EAAE;IACjC,OAAO,EAAE,IAAI,gBAAgB,EAAE;IAC/B,UAAU,EAAE,IAAI,mBAAmB,EAAE;IACrC,MAAM,EAAE,IAAI,eAAe,EAAE;IAC7B,MAAM,EAAE,IAAI,eAAe,EAAE;IAC7B,SAAS,EAAE,IAAI,kBAAkB,EAAE;IACnC,IAAI,EAAE,IAAI,aAAa,EAAE;IACzB,MAAM,EAAE,IAAI,eAAe,EAAE;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/transforms/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,MAAM,EAAkB,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,CAAC,MAAM,UAAU,GAAgD;IACrE,kBAAkB,EAAE,IAAI,2BAA2B,EAAE;IACrD,QAAQ,EAAE,IAAI,iBAAiB,EAAE;IACjC,aAAa,EAAE,IAAI,sBAAsB,EAAE;IAC3C,KAAK,EAAE,IAAI,cAAc,EAAE;IAC3B,QAAQ,EAAE,IAAI,iBAAiB,EAAE;IACjC,IAAI,EAAE,IAAI,aAAa,EAAE;IACzB,OAAO,EAAE,IAAI,gBAAgB,EAAE;IAC/B,QAAQ,EAAE,IAAI,iBAAiB,EAAE;IACjC,OAAO,EAAE,IAAI,gBAAgB,EAAE;IAC/B,UAAU,EAAE,IAAI,mBAAmB,EAAE;IACrC,MAAM,EAAE,IAAI,eAAe,EAAE;IAC7B,MAAM,EAAE,IAAI,eAAe,EAAE;IAC7B,SAAS,EAAE,IAAI,kBAAkB,EAAE;IACnC,IAAI,EAAE,IAAI,aAAa,EAAE;IACzB,MAAM,EAAE,IAAI,eAAe,EAAE;IAC7B,IAAI,EAAE,IAAI,aAAa,EAAE;CAC1B,CAAC;AAEF,uEAAuE;AACvE,MAAM,UAAU,YAAY,CAAC,IAAU;IACrC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,CAAC,wBAAwB,CAAC,CAAC;IACjF,MAAM,CAAC,GAAG,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,CAAC,CAAC;QAAE,OAAO,CAAC,gBAAgB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrD,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,aAAa,CAAC,IAAU;IACtC,MAAM,CAAC,GAAG,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7D,OAAO,CAAC,CAAC,SAAS,CAAC,IAAI,CAAS,CAAC;AACnC,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { BlurEdit } from './transforms/blur.js';
|
|
|
2
2
|
import type { BrightnessContrastEdit } from './transforms/brightnessContrast.js';
|
|
3
3
|
import type { CropEdit } from './transforms/crop.js';
|
|
4
4
|
import type { ExposureEdit } from './transforms/exposure.js';
|
|
5
|
+
import type { FlipEdit } from './transforms/flip.js';
|
|
5
6
|
import type { GrayscaleEdit } from './transforms/grayscale.js';
|
|
6
7
|
import type { HighlightsEdit } from './transforms/highlights.js';
|
|
7
8
|
import type { HueSaturationEdit } from './transforms/hueSaturation.js';
|
|
@@ -13,8 +14,8 @@ import type { SharpenEdit } from './transforms/sharpen.js';
|
|
|
13
14
|
import type { VibranceEdit } from './transforms/vibrance.js';
|
|
14
15
|
import type { VignetteEdit } from './transforms/vignette.js';
|
|
15
16
|
import type { WarmthEdit } from './transforms/warmth.js';
|
|
16
|
-
export type EditName = 'brightnessContrast' | 'exposure' | 'hueSaturation' | 'sepia' | 'vibrance' | 'blur' | 'sharpen' | 'vignette' | 'shadows' | 'highlights' | 'warmth' | 'invert' | 'grayscale' | 'crop' | 'rotate';
|
|
17
|
-
export type Edit = BrightnessContrastEdit | ExposureEdit | HueSaturationEdit | SepiaEdit | VibranceEdit | BlurEdit | SharpenEdit | VignetteEdit | ShadowsEdit | HighlightsEdit | WarmthEdit | InvertEdit | GrayscaleEdit | CropEdit | RotateEdit;
|
|
17
|
+
export type EditName = 'brightnessContrast' | 'exposure' | 'hueSaturation' | 'sepia' | 'vibrance' | 'blur' | 'sharpen' | 'vignette' | 'shadows' | 'highlights' | 'warmth' | 'invert' | 'grayscale' | 'crop' | 'rotate' | 'flip';
|
|
18
|
+
export type Edit = BrightnessContrastEdit | ExposureEdit | HueSaturationEdit | SepiaEdit | VibranceEdit | BlurEdit | SharpenEdit | VignetteEdit | ShadowsEdit | HighlightsEdit | WarmthEdit | InvertEdit | GrayscaleEdit | CropEdit | RotateEdit | FlipEdit;
|
|
18
19
|
export declare const EDIT_STATE_VERSION: 1;
|
|
19
20
|
export interface EditState {
|
|
20
21
|
version: typeof EDIT_STATE_VERSION;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AACjF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,MAAM,QAAQ,GAChB,oBAAoB,GACpB,UAAU,GACV,eAAe,GACf,OAAO,GACP,UAAU,GACV,MAAM,GACN,SAAS,GACT,UAAU,GACV,SAAS,GACT,YAAY,GACZ,QAAQ,GACR,QAAQ,GACR,WAAW,GACX,MAAM,GACN,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AACjF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,MAAM,QAAQ,GAChB,oBAAoB,GACpB,UAAU,GACV,eAAe,GACf,OAAO,GACP,UAAU,GACV,MAAM,GACN,SAAS,GACT,UAAU,GACV,SAAS,GACT,YAAY,GACZ,QAAQ,GACR,QAAQ,GACR,WAAW,GACX,MAAM,GACN,QAAQ,GACR,MAAM,CAAC;AAEX,MAAM,MAAM,IAAI,GACZ,sBAAsB,GACtB,YAAY,GACZ,iBAAiB,GACjB,SAAS,GACT,YAAY,GACZ,QAAQ,GACR,WAAW,GACX,YAAY,GACZ,WAAW,GACX,cAAc,GACd,UAAU,GACV,UAAU,GACV,aAAa,GACb,QAAQ,GACR,UAAU,GACV,QAAQ,CAAC;AAEb,eAAO,MAAM,kBAAkB,EAAG,CAAU,CAAC;AAE7C,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,OAAO,kBAAkB,CAAC;IACnC,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAED,wBAAgB,UAAU,IAAI,SAAS,CAEtC"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AA4DA,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAU,CAAC;AAO7C,MAAM,UAAU,UAAU;IACxB,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AACpD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@radialapps/memories-vips-editor",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Headless WebGL preview library for vips-static edits. Renders an ordered edit list on a caller-provided canvas; serializes the same list as JSON for the vips-preview CLI (convert/thumbnail ... \"edits\": [...]).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// flip.ts — mirror left-right (horizontal) or top-bottom (vertical).
|
|
2
|
+
//
|
|
3
|
+
// Pure UV swizzle (like rotate's quarter-turn path): exact under any
|
|
4
|
+
// precision, dims unchanged, alpha mirrors along untouched. The VIPS side
|
|
5
|
+
// (src/transforms/flip.h) uses fliphor()/flipver() and marks the edit
|
|
6
|
+
// geometric so the gainmap mirrors with the base image.
|
|
7
|
+
import type { ParamControl, RenderContext, Target, Transform } from './transform.js';
|
|
8
|
+
|
|
9
|
+
export type FlipDirection = 'horizontal' | 'vertical';
|
|
10
|
+
|
|
11
|
+
export interface FlipEdit {
|
|
12
|
+
edit: 'flip';
|
|
13
|
+
/** Mirror axis: 'horizontal' mirrors left-right. Default 'horizontal'. */
|
|
14
|
+
direction?: FlipDirection;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
type Full = Required<FlipEdit>;
|
|
18
|
+
|
|
19
|
+
const FRAG = `
|
|
20
|
+
precision mediump float;
|
|
21
|
+
uniform sampler2D texture;
|
|
22
|
+
uniform int vertical;
|
|
23
|
+
varying vec2 texCoord;
|
|
24
|
+
void main() {
|
|
25
|
+
vec2 uv = vertical == 1
|
|
26
|
+
? vec2(texCoord.x, 1.0 - texCoord.y)
|
|
27
|
+
: vec2(1.0 - texCoord.x, texCoord.y);
|
|
28
|
+
gl_FragColor = texture2D(texture, uv);
|
|
29
|
+
}
|
|
30
|
+
`;
|
|
31
|
+
|
|
32
|
+
export class FlipTransform implements Transform<'flip', FlipEdit> {
|
|
33
|
+
public readonly edit = 'flip' as const;
|
|
34
|
+
public controls: ParamControl[] = [];
|
|
35
|
+
|
|
36
|
+
public defaults(): Full {
|
|
37
|
+
return { edit: 'flip', direction: 'horizontal' };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public validate(params: FlipEdit): string[] {
|
|
41
|
+
if (
|
|
42
|
+
params.direction !== undefined &&
|
|
43
|
+
params.direction !== 'horizontal' &&
|
|
44
|
+
params.direction !== 'vertical'
|
|
45
|
+
)
|
|
46
|
+
return ['direction must be "horizontal" or "vertical"'];
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public normalize(params: FlipEdit): Full {
|
|
51
|
+
return {
|
|
52
|
+
edit: 'flip',
|
|
53
|
+
direction: params.direction === 'vertical' ? 'vertical' : 'horizontal',
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
public apply(ctx: RenderContext, from: Target, to: Target, params: Full): Target {
|
|
58
|
+
ctx.pass(FRAG, from, to, (gl, p) => {
|
|
59
|
+
const uV = gl.getUniformLocation(p, 'vertical');
|
|
60
|
+
if (uV) gl.uniform1i(uV, params.direction === 'vertical' ? 1 : 0);
|
|
61
|
+
});
|
|
62
|
+
return to;
|
|
63
|
+
}
|
|
64
|
+
}
|
package/src/transforms/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { BlurTransform } from './blur.js';
|
|
|
9
9
|
import { BrightnessContrastTransform } from './brightnessContrast.js';
|
|
10
10
|
import { CropTransform } from './crop.js';
|
|
11
11
|
import { ExposureTransform } from './exposure.js';
|
|
12
|
+
import { FlipTransform } from './flip.js';
|
|
12
13
|
import { GrayscaleTransform } from './grayscale.js';
|
|
13
14
|
import { HighlightsTransform } from './highlights.js';
|
|
14
15
|
import { HueSaturationTransform } from './hueSaturation.js';
|
|
@@ -37,6 +38,7 @@ export const TRANSFORMS: Record<EditName, Transform<string, object>> = {
|
|
|
37
38
|
grayscale: new GrayscaleTransform(),
|
|
38
39
|
crop: new CropTransform(),
|
|
39
40
|
rotate: new RotateTransform(),
|
|
41
|
+
flip: new FlipTransform(),
|
|
40
42
|
};
|
|
41
43
|
|
|
42
44
|
/** Human-readable problems; empty means the edit is VIPS-appliable. */
|
package/src/types.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type { BlurEdit } from './transforms/blur.js';
|
|
|
9
9
|
import type { BrightnessContrastEdit } from './transforms/brightnessContrast.js';
|
|
10
10
|
import type { CropEdit } from './transforms/crop.js';
|
|
11
11
|
import type { ExposureEdit } from './transforms/exposure.js';
|
|
12
|
+
import type { FlipEdit } from './transforms/flip.js';
|
|
12
13
|
import type { GrayscaleEdit } from './transforms/grayscale.js';
|
|
13
14
|
import type { HighlightsEdit } from './transforms/highlights.js';
|
|
14
15
|
import type { HueSaturationEdit } from './transforms/hueSaturation.js';
|
|
@@ -36,7 +37,8 @@ export type EditName =
|
|
|
36
37
|
| 'invert'
|
|
37
38
|
| 'grayscale'
|
|
38
39
|
| 'crop'
|
|
39
|
-
| 'rotate'
|
|
40
|
+
| 'rotate'
|
|
41
|
+
| 'flip';
|
|
40
42
|
|
|
41
43
|
export type Edit =
|
|
42
44
|
| BrightnessContrastEdit
|
|
@@ -53,7 +55,8 @@ export type Edit =
|
|
|
53
55
|
| InvertEdit
|
|
54
56
|
| GrayscaleEdit
|
|
55
57
|
| CropEdit
|
|
56
|
-
| RotateEdit
|
|
58
|
+
| RotateEdit
|
|
59
|
+
| FlipEdit;
|
|
57
60
|
|
|
58
61
|
export const EDIT_STATE_VERSION = 1 as const;
|
|
59
62
|
|