Refactoring code
This commit is contained in:
@ -1,36 +1,49 @@
|
|||||||
"use server";
|
"use server";
|
||||||
|
|
||||||
import { prisma } from "@/lib/prisma";
|
import { prisma } from "@/lib/prisma";
|
||||||
import { VibrantSwatch } from "@/types/VibrantSwatch";
|
import type { VibrantSwatch } from "@/types/VibrantSwatch";
|
||||||
import { getImageBufferFromS3Key } from "@/utils/getImageBufferFromS3";
|
import { getImageBufferFromS3Key } from "@/utils/getImageBufferFromS3";
|
||||||
import { generateColorName, rgbToHex } from "@/utils/uploadHelper";
|
import { generateColorName, rgbToHex } from "@/utils/uploadHelper";
|
||||||
import { converter, parse } from "culori";
|
import { converter, parse } from "culori";
|
||||||
import { Vibrant } from "node-vibrant/node";
|
import { Vibrant } from "node-vibrant/node";
|
||||||
|
|
||||||
const toOklab = converter("oklab");
|
const toOklab = converter("oklab");
|
||||||
const A_MIN = -0.5, A_MAX = 0.5;
|
const A_MIN = -0.5,
|
||||||
const B_MIN = -0.5, B_MAX = 0.5;
|
A_MAX = 0.5;
|
||||||
|
const B_MIN = -0.5,
|
||||||
|
B_MAX = 0.5;
|
||||||
|
|
||||||
function clamp01(x: number) { return Math.max(0, Math.min(1, x)); }
|
function clamp01(x: number) {
|
||||||
function norm(x: number, lo: number, hi: number) { return clamp01((x - lo) / (hi - lo)); }
|
return Math.max(0, Math.min(1, x));
|
||||||
|
}
|
||||||
|
function norm(x: number, lo: number, hi: number) {
|
||||||
|
return clamp01((x - lo) / (hi - lo));
|
||||||
|
}
|
||||||
|
|
||||||
function hilbertIndex15(x01: number, y01: number): number {
|
function hilbertIndex15(x01: number, y01: number): number {
|
||||||
let x = Math.floor(clamp01(x01) * 32767);
|
let x = Math.floor(clamp01(x01) * 32767);
|
||||||
let y = Math.floor(clamp01(y01) * 32767);
|
let y = Math.floor(clamp01(y01) * 32767);
|
||||||
let index = 0;
|
let index = 0;
|
||||||
for (let s = 1 << 14; s > 0; s >>= 1) {
|
for (let s = 1 << 14; s > 0; s >>= 1) {
|
||||||
const rx = (x & s) ? 1 : 0;
|
const rx = x & s ? 1 : 0;
|
||||||
const ry = (y & s) ? 1 : 0;
|
const ry = y & s ? 1 : 0;
|
||||||
index += s * s * ((3 * rx) ^ ry);
|
index += s * s * ((3 * rx) ^ ry);
|
||||||
if (ry === 0) {
|
if (ry === 0) {
|
||||||
if (rx === 1) { x = 32767 - x; y = 32767 - y; }
|
if (rx === 1) {
|
||||||
const t = x; x = y; y = t;
|
x = 32767 - x;
|
||||||
|
y = 32767 - y;
|
||||||
|
}
|
||||||
|
const t = x;
|
||||||
|
x = y;
|
||||||
|
y = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return index >>> 0;
|
return index >>> 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function centroidFromPaletteHexes(hexByType: Record<string, string | undefined>) {
|
function centroidFromPaletteHexes(
|
||||||
|
hexByType: Record<string, string | undefined>,
|
||||||
|
) {
|
||||||
const weights: Record<string, number> = {
|
const weights: Record<string, number> = {
|
||||||
Vibrant: 0.7,
|
Vibrant: 0.7,
|
||||||
Muted: 0.15,
|
Muted: 0.15,
|
||||||
@ -48,14 +61,20 @@ function centroidFromPaletteHexes(hexByType: Record<string, string | undefined>)
|
|||||||
hexByType["LightVibrant"] ||
|
hexByType["LightVibrant"] ||
|
||||||
hexByType["LightMuted"];
|
hexByType["LightMuted"];
|
||||||
|
|
||||||
let L = 0, A = 0, B = 0, W = 0;
|
let L = 0,
|
||||||
|
A = 0,
|
||||||
|
B = 0,
|
||||||
|
W = 0;
|
||||||
|
|
||||||
for (const [type, w] of Object.entries(weights)) {
|
for (const [type, w] of Object.entries(weights)) {
|
||||||
const hex = hexByType[type] ?? fallbackHex;
|
const hex = hexByType[type] ?? fallbackHex;
|
||||||
if (!hex || w <= 0) continue;
|
if (!hex || w <= 0) continue;
|
||||||
const c = toOklab(parse(hex));
|
const c = toOklab(parse(hex));
|
||||||
if (!c) continue;
|
if (!c) continue;
|
||||||
L += c.l * w; A += c.a * w; B += c.b * w; W += w;
|
L += c.l * w;
|
||||||
|
A += c.a * w;
|
||||||
|
B += c.b * w;
|
||||||
|
W += w;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (W === 0) return { l: 0.5, a: 0, b: 0 };
|
if (W === 0) return { l: 0.5, a: 0, b: 0 };
|
||||||
@ -78,7 +97,11 @@ export async function generateArtworkColorsForArtwork(artworkId: string) {
|
|||||||
where: { id: artworkId },
|
where: { id: artworkId },
|
||||||
select: {
|
select: {
|
||||||
file: { select: { fileKey: true } },
|
file: { select: { fileKey: true } },
|
||||||
variants: { where: { type: "original" }, select: { s3Key: true }, take: 1 },
|
variants: {
|
||||||
|
where: { type: "original" },
|
||||||
|
select: { s3Key: true },
|
||||||
|
take: 1,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (!artwork) throw new Error("Artwork not found");
|
if (!artwork) throw new Error("Artwork not found");
|
||||||
@ -117,11 +140,14 @@ export async function generateArtworkColorsForArtwork(artworkId: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const hexByType: Record<string, string | undefined> = Object.fromEntries(
|
const hexByType: Record<string, string | undefined> = Object.fromEntries(
|
||||||
vibrantHexes.map(({ type, hex }) => [type, hex])
|
vibrantHexes.map(({ type, hex }) => [type, hex]),
|
||||||
);
|
);
|
||||||
|
|
||||||
const { l, a, b } = centroidFromPaletteHexes(hexByType);
|
const { l, a, b } = centroidFromPaletteHexes(hexByType);
|
||||||
const sortKey = hilbertIndex15(norm(a, A_MIN, A_MAX), norm(b, B_MIN, B_MAX));
|
const sortKey = hilbertIndex15(
|
||||||
|
norm(a, A_MIN, A_MAX),
|
||||||
|
norm(b, B_MIN, B_MAX),
|
||||||
|
);
|
||||||
|
|
||||||
await prisma.artwork.update({
|
await prisma.artwork.update({
|
||||||
where: { id: artworkId },
|
where: { id: artworkId },
|
||||||
@ -144,6 +170,9 @@ export async function generateArtworkColorsForArtwork(artworkId: string) {
|
|||||||
colorError: e instanceof Error ? e.message : "Color generation failed",
|
colorError: e instanceof Error ? e.message : "Color generation failed",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return { ok: false as const, error: e instanceof Error ? e.message : "Color generation failed" };
|
return {
|
||||||
|
ok: false as const,
|
||||||
|
error: e instanceof Error ? e.message : "Color generation failed",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
"use server";
|
"use server";
|
||||||
|
|
||||||
import { Prisma } from "@/generated/prisma/client";
|
import type { Prisma } from "@/generated/prisma/client";
|
||||||
import { prisma } from "@/lib/prisma";
|
import { prisma } from "@/lib/prisma";
|
||||||
import { generateArtworkColorsForArtwork } from "../artworks/generateArtworkColors";
|
import { generateArtworkColorsForArtwork } from "../artworks/generateArtworkColors";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user