mirror of
https://github.com/igorski/bitmappery.git
synced 2026-07-26 08:47:43 +02:00
Add rel to Layer structure
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Igor Zinken 2020-2025 - https://www.igorski.nl
|
||||
* Igor Zinken 2020-2026 - https://www.igorski.nl
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
@@ -24,6 +24,11 @@ import type { Point } from "zcanvas";
|
||||
import type { BlendModes } from "./blend-modes";
|
||||
import type { LayerTypes } from "./layer-types";
|
||||
|
||||
export type LayerRel = {
|
||||
type: "none" | "group" | "tile";
|
||||
id?: string;
|
||||
};
|
||||
|
||||
export type Layer = {
|
||||
id: string;
|
||||
name: string;
|
||||
@@ -41,6 +46,7 @@ export type Layer = {
|
||||
transform: Transform;
|
||||
filters: Filters;
|
||||
text: Text;
|
||||
rel: LayerRel;
|
||||
};
|
||||
|
||||
export type Transform = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Igor Zinken 2020-2025 - https://www.igorski.nl
|
||||
* Igor Zinken 2020-2026 - https://www.igorski.nl
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
@@ -22,7 +22,7 @@
|
||||
*/
|
||||
import type { Rectangle } from "zcanvas";
|
||||
import { LayerTypes, DEFAULT_LAYER_NAME, DEFAULT_TEXT_LAYER_NAME } from "@/definitions/layer-types";
|
||||
import type { Layer } from "@/definitions/document";
|
||||
import type { Layer, LayerRel } from "@/definitions/document";
|
||||
import { imageToBase64, base64toCanvas } from "@/utils/canvas-util";
|
||||
import TransformFactory, { type TransformProps } from "@/factories/transform-factory";
|
||||
import FiltersFactory from "@/factories/filters-factory";
|
||||
@@ -32,10 +32,11 @@ import type { TextProps } from "@/factories/text-factory";
|
||||
|
||||
let UID_COUNTER = 0;
|
||||
|
||||
export type LayerProps = Partial<Omit<Layer, "transform" | "filters" | "text">> & {
|
||||
export type LayerProps = Partial<Omit<Layer, "transform" | "filters" | "text" | "rel">> & {
|
||||
transform?: TransformProps;
|
||||
filters?: FiltersProps;
|
||||
text?: TextProps;
|
||||
rel?: Partial<LayerRel>;
|
||||
};
|
||||
|
||||
const LayerFactory = {
|
||||
@@ -46,7 +47,7 @@ const LayerFactory = {
|
||||
name = DEFAULT_LAYER_NAME,
|
||||
type = LayerTypes.LAYER_GRAPHIC, transparent = true, source = null, mask = null,
|
||||
left = 0, top = 0, maskX = 0, maskY = 0, width = 1, height = 1, visible = true,
|
||||
transform = {}, filters = {}, text = {}
|
||||
transform = {}, filters = {}, text = {}, rel = {},
|
||||
}: LayerProps = {}): Layer {
|
||||
return {
|
||||
id: `layer_${( ++UID_COUNTER )}`,
|
||||
@@ -65,6 +66,10 @@ const LayerFactory = {
|
||||
text: TextFactory.create( text ),
|
||||
transform: TransformFactory.create( transform ),
|
||||
filters: FiltersFactory.create( filters ),
|
||||
rel: {
|
||||
type: "none",
|
||||
...rel,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
@@ -89,6 +94,10 @@ const LayerFactory = {
|
||||
f: TransformFactory.serialize( layer.transform ),
|
||||
fl: FiltersFactory.serialize( layer.filters ),
|
||||
v: layer.visible,
|
||||
r: {
|
||||
t: layer.rel.type,
|
||||
i: layer.rel.id,
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
@@ -116,6 +125,10 @@ const LayerFactory = {
|
||||
text,
|
||||
transform: TransformFactory.deserialize( layer.f ),
|
||||
filters: FiltersFactory.deserialize( layer.fl ),
|
||||
rel: layer.r ? {
|
||||
type: layer.r.t,
|
||||
id: layer.r.i,
|
||||
} : {}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -45,6 +45,9 @@ describe( "Layer factory", () => {
|
||||
text: mockText,
|
||||
transform: mockTransform,
|
||||
filters: mockFilters,
|
||||
rel: {
|
||||
type: "none",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -73,7 +76,11 @@ describe( "Layer factory", () => {
|
||||
visible: false,
|
||||
text: { value: "Lorem ipsum" },
|
||||
transform: { rotation: 270 },
|
||||
filters: { contrast: .7 }
|
||||
filters: { contrast: .7 },
|
||||
rel: {
|
||||
type: "group",
|
||||
id: "Foo",
|
||||
},
|
||||
});
|
||||
expect( layer ).toEqual({
|
||||
id: expect.any( String ),
|
||||
@@ -92,7 +99,11 @@ describe( "Layer factory", () => {
|
||||
text: { value: "Lorem ipsum" },
|
||||
transform: { rotation: 270 },
|
||||
filters: { contrast: .7 },
|
||||
})
|
||||
rel: {
|
||||
type: "group",
|
||||
id: "Foo",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
describe( "and providing a name to the Layer", () => {
|
||||
@@ -131,7 +142,11 @@ describe( "Layer factory", () => {
|
||||
visible: false,
|
||||
text: { value: "Lorem ipsum" },
|
||||
transform: { rotation: 270 },
|
||||
filters: { contrast: .7 }
|
||||
filters: { contrast: .7 },
|
||||
rel: {
|
||||
type: "tile",
|
||||
id: "1",
|
||||
},
|
||||
});
|
||||
const serializeTextSpy = vi.spyOn( TextFactory, "serialize" ).mockImplementation( args => args );
|
||||
const deserializeTextSpy = vi.spyOn( TextFactory, "deserialize" ).mockImplementation( args => args );
|
||||
@@ -160,6 +175,11 @@ describe( "Layer factory", () => {
|
||||
expect( deserializeTransformSpy ).toHaveBeenCalledWith( layer.transform );
|
||||
expect( deserializeFiltersSpy ).toHaveBeenCalledWith( layer.filters );
|
||||
|
||||
expect( deserialized.rel ).toEqual({
|
||||
type: "tile",
|
||||
id: "1",
|
||||
});
|
||||
|
||||
// note id's are unique per created session instance and therefor will differ
|
||||
expect({
|
||||
...deserialized,
|
||||
@@ -169,6 +189,17 @@ describe( "Layer factory", () => {
|
||||
id: expect.any( String ),
|
||||
});
|
||||
});
|
||||
|
||||
it( "should deserialize with a default rel structure for legacy serialized layers", async () => {
|
||||
const serialized = LayerFactory.serialize( LayerFactory.create());
|
||||
delete serialized.r;
|
||||
|
||||
const deserialized = await LayerFactory.deserialize( serialized );
|
||||
|
||||
expect( deserialized.rel ).toEqual({
|
||||
type: "none",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it( "should be able to return a rectangle for a Layer", () => {
|
||||
|
||||
Reference in New Issue
Block a user