diff --git a/src/collages.ts b/src/collages.ts index 64ad7cc..e1cec2d 100644 --- a/src/collages.ts +++ b/src/collages.ts @@ -1,17 +1,19 @@ import {CollageMode} from "@/types"; import {randint, shuffle} from "@/utils"; -const collageModeType = ["grid", "row", "irow", "col", "icol"] as const; +const collageModeType = ["grid", "row", "irow", "col", "icol", "center"] as const; export type CollageModeType = typeof collageModeType[number]; function cleanDraw(ctx: CanvasRenderingContext2D, image: ImageBitmap, x: number, y: number, w: number, h: number) { const scaleRatio = Math.max(w / image.width, h / image.height); - ctx.drawImage(image, + ctx.drawImage( + image, image.width / 2 - w / scaleRatio / 2, image.height / 2 - h / scaleRatio / 2, w / scaleRatio, h / scaleRatio, x - w / 2, y - h / 2, - w, h); + w, h + ); } const modes: { [key in CollageModeType]: CollageMode } = { @@ -124,6 +126,40 @@ const modes: { [key in CollageModeType]: CollageMode } = { }); }, }, + "center": { + name: "Concentric", + minImages: 2, + forceConfig: { + cleanCrops: true + }, + place: (ctx, images, config) => { + const selectedImages = shuffle(images).slice(0, config.numImages || randint(4) + 2); + const x = ctx.canvas.width / 2; + const y = ctx.canvas.height / 2; + + if (Math.random() < .66) { + selectedImages.forEach((image, idx) => { + cleanDraw( + ctx, image, x, y, + ctx.canvas.width - (ctx.canvas.width / selectedImages.length * idx), + ctx.canvas.height - (ctx.canvas.height / selectedImages.length * idx), + ); + }); + } else { + let factor: number; + if (Math.random() > .5) { + const factors = [1 / Math.sqrt(2), .5, .88]; + factor = factors[Math.floor(Math.random() * factors.length)]; + } else { + factor = 1 - (1 / selectedImages.length); + } + selectedImages.forEach((image, idx) => { + const ratio = Math.pow(factor, idx); + cleanDraw(ctx, image, x, y, ctx.canvas.width * ratio, ctx.canvas.height * ratio); + }); + } + } + } }; export default modes;