feat(ui): add x,y,scaleX,scaleY,rotation to objects

This commit is contained in:
psychedelicious 2024-06-06 18:19:39 +10:00
parent 3fbe65bbcf
commit 99d8b3a7bf
3 changed files with 86 additions and 31 deletions

View File

@ -19,18 +19,23 @@ import { v4 as uuidv4 } from 'uuid';
* @param name The konva name for the line * @param name The konva name for the line
*/ */
export const createBrushLine = (brushLine: BrushLine, layerObjectGroup: Konva.Group, name: string): Konva.Line => { export const createBrushLine = (brushLine: BrushLine, layerObjectGroup: Konva.Group, name: string): Konva.Line => {
const { id, strokeWidth, color, x, y, scaleX, scaleY, rotation } = brushLine;
const konvaLine = new Konva.Line({ const konvaLine = new Konva.Line({
id: brushLine.id, id,
key: brushLine.id,
name, name,
strokeWidth: brushLine.strokeWidth, strokeWidth,
tension: 0, tension: 0,
lineCap: 'round', lineCap: 'round',
lineJoin: 'round', lineJoin: 'round',
shadowForStrokeEnabled: false, shadowForStrokeEnabled: false,
globalCompositeOperation: 'source-over', globalCompositeOperation: 'source-over',
listening: false, listening: false,
stroke: rgbaColorToString(brushLine.color), stroke: rgbaColorToString(color),
x,
y,
scaleX,
scaleY,
rotation,
}); });
layerObjectGroup.add(konvaLine); layerObjectGroup.add(konvaLine);
return konvaLine; return konvaLine;
@ -43,11 +48,11 @@ export const createBrushLine = (brushLine: BrushLine, layerObjectGroup: Konva.Gr
* @param name The konva name for the line * @param name The konva name for the line
*/ */
export const createEraserLine = (eraserLine: EraserLine, layerObjectGroup: Konva.Group, name: string): Konva.Line => { export const createEraserLine = (eraserLine: EraserLine, layerObjectGroup: Konva.Group, name: string): Konva.Line => {
const { id, strokeWidth, x, y, scaleX, scaleY, rotation } = eraserLine;
const konvaLine = new Konva.Line({ const konvaLine = new Konva.Line({
id: eraserLine.id, id,
key: eraserLine.id,
name, name,
strokeWidth: eraserLine.strokeWidth, strokeWidth,
tension: 0, tension: 0,
lineCap: 'round', lineCap: 'round',
lineJoin: 'round', lineJoin: 'round',
@ -55,6 +60,11 @@ export const createEraserLine = (eraserLine: EraserLine, layerObjectGroup: Konva
globalCompositeOperation: 'destination-out', globalCompositeOperation: 'destination-out',
listening: false, listening: false,
stroke: rgbaColorToString(DEFAULT_RGBA_COLOR), stroke: rgbaColorToString(DEFAULT_RGBA_COLOR),
x,
y,
scaleX,
scaleY,
rotation,
}); });
layerObjectGroup.add(konvaLine); layerObjectGroup.add(konvaLine);
return konvaLine; return konvaLine;
@ -67,14 +77,18 @@ export const createEraserLine = (eraserLine: EraserLine, layerObjectGroup: Konva
* @param name The konva name for the rect * @param name The konva name for the rect
*/ */
export const createRectShape = (rectShape: RectShape, layerObjectGroup: Konva.Group, name: string): Konva.Rect => { export const createRectShape = (rectShape: RectShape, layerObjectGroup: Konva.Group, name: string): Konva.Rect => {
const { id, x, y, width, height, scaleX, scaleY, rotation } = rectShape;
const konvaRect = new Konva.Rect({ const konvaRect = new Konva.Rect({
id: rectShape.id, id,
key: rectShape.id,
name, name,
x: rectShape.x, x,
y: rectShape.y, y,
width: rectShape.width, width,
height: rectShape.height, height,
scaleX,
scaleY,
rotation,
listening: false, listening: false,
fill: rgbaColorToString(rectShape.color), fill: rgbaColorToString(rectShape.color),
}); });
@ -125,7 +139,20 @@ export const createImageObjectGroup = async (
layerObjectGroup: Konva.Group, layerObjectGroup: Konva.Group,
name: string name: string
): Promise<Konva.Group> => { ): Promise<Konva.Group> => {
const konvaImageGroup = new Konva.Group({ id: imageObject.id, name, listening: false }); const { id, x, y, width, height, scaleX, scaleY, rotation } = imageObject;
const konvaImageGroup = new Konva.Group({
id,
x,
y,
width,
height,
scaleX,
scaleY,
rotation,
name,
listening: false,
});
const placeholder = createImagePlaceholderGroup(imageObject); const placeholder = createImagePlaceholderGroup(imageObject);
konvaImageGroup.add(placeholder.konvaPlaceholderGroup); konvaImageGroup.add(placeholder.konvaPlaceholderGroup);
layerObjectGroup.add(konvaImageGroup); layerObjectGroup.add(konvaImageGroup);

View File

@ -656,6 +656,11 @@ export const controlLayersSlice = createSlice({
layer.objects.push({ layer.objects.push({
id: getBrushLineId(layer.id, lineUuid), id: getBrushLineId(layer.id, lineUuid),
type: 'brush_line', type: 'brush_line',
x: 0,
y: 0,
scaleX: 1,
scaleY: 1,
rotation: 0,
// Points must be offset by the layer's x and y coordinates // Points must be offset by the layer's x and y coordinates
// TODO: Handle this in the event listener? // TODO: Handle this in the event listener?
points: [points[0] - layer.x, points[1] - layer.y, points[2] - layer.x, points[3] - layer.y], points: [points[0] - layer.x, points[1] - layer.y, points[2] - layer.x, points[3] - layer.y],
@ -685,6 +690,11 @@ export const controlLayersSlice = createSlice({
layer.objects.push({ layer.objects.push({
id: getEraserLineId(layer.id, lineUuid), id: getEraserLineId(layer.id, lineUuid),
type: 'eraser_line', type: 'eraser_line',
x: 0,
y: 0,
scaleX: 1,
scaleY: 1,
rotation: 0,
// Points must be offset by the layer's x and y coordinates // Points must be offset by the layer's x and y coordinates
// TODO: Handle this in the event listener? // TODO: Handle this in the event listener?
points: [points[0] - layer.x, points[1] - layer.y, points[2] - layer.x, points[3] - layer.y], points: [points[0] - layer.x, points[1] - layer.y, points[2] - layer.x, points[3] - layer.y],
@ -728,6 +738,9 @@ export const controlLayersSlice = createSlice({
id, id,
x: rect.x - layer.x, x: rect.x - layer.x,
y: rect.y - layer.y, y: rect.y - layer.y,
scaleX: 1,
scaleY: 1,
rotation: 0,
width: rect.width, width: rect.width,
height: rect.height, height: rect.height,
color, color,
@ -750,6 +763,9 @@ export const controlLayersSlice = createSlice({
id, id,
x: 0, x: 0,
y: 0, y: 0,
scaleX: 1,
scaleY: 1,
rotation: 0,
width, width,
height, height,
image: { width, height, name }, image: { width, height, name },

View File

@ -60,8 +60,16 @@ export const DEFAULT_RGBA_COLOR: RgbaColor = { r: 255, g: 255, b: 255, a: 1 };
const zOpacity = z.number().gte(0).lte(1); const zOpacity = z.number().gte(0).lte(1);
const zBrushLine = z.object({ const zObjectBase = z.object({
id: z.string(), id: z.string(),
x: z.number().catch(0),
y: z.number().catch(0),
scaleX: z.number().catch(1),
scaleY: z.number().catch(1),
rotation: z.number().catch(0),
});
const zBrushLine = zObjectBase.extend({
type: z.literal('brush_line'), type: z.literal('brush_line'),
strokeWidth: z.number().min(1), strokeWidth: z.number().min(1),
points: zPoints, points: zPoints,
@ -69,50 +77,39 @@ const zBrushLine = z.object({
}); });
export type BrushLine = z.infer<typeof zBrushLine>; export type BrushLine = z.infer<typeof zBrushLine>;
const zEraserline = z.object({ const zEraserline = zObjectBase.extend({
id: z.string(),
type: z.literal('eraser_line'), type: z.literal('eraser_line'),
strokeWidth: z.number().min(1), strokeWidth: z.number().min(1),
points: zPoints, points: zPoints,
}); });
export type EraserLine = z.infer<typeof zEraserline>; export type EraserLine = z.infer<typeof zEraserline>;
const zRectShape = z.object({ const zRectShape = zObjectBase.extend({
id: z.string(),
type: z.literal('rect_shape'), type: z.literal('rect_shape'),
x: z.number(),
y: z.number(),
width: z.number().min(1), width: z.number().min(1),
height: z.number().min(1), height: z.number().min(1),
color: zRgbaColor, color: zRgbaColor,
}); });
export type RectShape = z.infer<typeof zRectShape>; export type RectShape = z.infer<typeof zRectShape>;
const zEllipseShape = z.object({ const zEllipseShape = zObjectBase.extend({
id: z.string(),
type: z.literal('ellipse_shape'), type: z.literal('ellipse_shape'),
x: z.number(),
y: z.number(),
width: z.number().min(1), width: z.number().min(1),
height: z.number().min(1), height: z.number().min(1),
color: zRgbaColor, color: zRgbaColor,
}); });
export type EllipseShape = z.infer<typeof zEllipseShape>; export type EllipseShape = z.infer<typeof zEllipseShape>;
const zPolygonShape = z.object({ const zPolygonShape = zObjectBase.extend({
id: z.string(),
type: z.literal('polygon_shape'), type: z.literal('polygon_shape'),
points: zPoints, points: zPoints,
color: zRgbaColor, color: zRgbaColor,
}); });
export type PolygonShape = z.infer<typeof zPolygonShape>; export type PolygonShape = z.infer<typeof zPolygonShape>;
const zImageObject = z.object({ const zImageObject = zObjectBase.extend({
id: z.string(),
type: z.literal('image'), type: z.literal('image'),
image: zImageWithDims, image: zImageWithDims,
x: z.number(),
y: z.number(),
width: z.number().min(1), width: z.number().min(1),
height: z.number().min(1), height: z.number().min(1),
}); });
@ -179,12 +176,22 @@ const zMaskObject = z
...rest, ...rest,
type: 'brush_line', type: 'brush_line',
color: { r: 255, g: 255, b: 255, a: 1 }, color: { r: 255, g: 255, b: 255, a: 1 },
x: 0,
y: 0,
scaleX: 1,
scaleY: 1,
rotation: 0,
}; };
return asBrushline; return asBrushline;
} else if (tool === 'eraser') { } else if (tool === 'eraser') {
const asEraserLine: EraserLine = { const asEraserLine: EraserLine = {
...rest, ...rest,
type: 'eraser_line', type: 'eraser_line',
x: 0,
y: 0,
scaleX: 1,
scaleY: 1,
rotation: 0,
}; };
return asEraserLine; return asEraserLine;
} }
@ -193,6 +200,11 @@ const zMaskObject = z
...val, ...val,
type: 'rect_shape', type: 'rect_shape',
color: { r: 255, g: 255, b: 255, a: 1 }, color: { r: 255, g: 255, b: 255, a: 1 },
x: 0,
y: 0,
scaleX: 1,
scaleY: 1,
rotation: 0,
}; };
return asRectShape; return asRectShape;
} else { } else {