mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 11:29:46 +00:00
captcha: refactor canvas calls
This commit is contained in:
parent
cdf727e5c7
commit
71873997e5
1 changed files with 23 additions and 32 deletions
|
|
@ -24,12 +24,8 @@ export const captchaController: AppController = async (c) => {
|
||||||
await Deno.readFile(new URL('../../../captcha/tj-holowaychuk.jpg', import.meta.url)),
|
await Deno.readFile(new URL('../../../captcha/tj-holowaychuk.jpg', import.meta.url)),
|
||||||
await Deno.readFile(new URL('../../../captcha/puzzle-mask.png', import.meta.url)),
|
await Deno.readFile(new URL('../../../captcha/puzzle-mask.png', import.meta.url)),
|
||||||
await Deno.readFile(new URL('../../../captcha/puzzle-hole.png', import.meta.url)),
|
await Deno.readFile(new URL('../../../captcha/puzzle-hole.png', import.meta.url)),
|
||||||
{
|
{ w: 370, h: 400 },
|
||||||
cw: 370,
|
{ w: 65, h: 65 },
|
||||||
ch: 400,
|
|
||||||
pw: 65,
|
|
||||||
ph: 65,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const id = crypto.randomUUID();
|
const id = crypto.randomUUID();
|
||||||
|
|
@ -53,33 +49,30 @@ async function generateCaptcha(
|
||||||
from: Uint8Array,
|
from: Uint8Array,
|
||||||
mask: Uint8Array,
|
mask: Uint8Array,
|
||||||
hole: Uint8Array,
|
hole: Uint8Array,
|
||||||
opts: {
|
bgSize: Dimensions,
|
||||||
pw: number;
|
puzzleSize: Dimensions,
|
||||||
ph: number;
|
|
||||||
cw: number;
|
|
||||||
ch: number;
|
|
||||||
},
|
|
||||||
) {
|
) {
|
||||||
const { pw, ph, cw, ch } = opts;
|
const bg = createCanvas(bgSize.w, bgSize.h);
|
||||||
const bg = createCanvas(cw, ch);
|
const puzzle = createCanvas(puzzleSize.w, puzzleSize.h);
|
||||||
const ctx = bg.getContext('2d');
|
|
||||||
const image = await loadImage(from);
|
|
||||||
ctx.drawImage(image, 0, 0, image.width(), image.height(), 0, 0, cw, ch);
|
|
||||||
|
|
||||||
const puzzle = createCanvas(pw, ph);
|
const ctx = bg.getContext('2d');
|
||||||
const pctx = puzzle.getContext('2d');
|
const pctx = puzzle.getContext('2d');
|
||||||
|
|
||||||
const solution = getPieceCoords(bg.width, bg.height, pw, ph);
|
const bgImage = await loadImage(from);
|
||||||
|
|
||||||
const maskImage = await loadImage(mask);
|
const maskImage = await loadImage(mask);
|
||||||
const holeImage = await loadImage(hole);
|
const holeImage = await loadImage(hole);
|
||||||
|
|
||||||
pctx.drawImage(maskImage, 0, 0, pw, ph);
|
const solution = generateSolution(bgSize, puzzleSize);
|
||||||
pctx.globalCompositeOperation = 'source-in';
|
|
||||||
pctx.drawImage(bg, solution.x, solution.y, pw, ph, 0, 0, pw, ph);
|
|
||||||
|
|
||||||
|
// Draw the background image.
|
||||||
|
ctx.drawImage(bgImage, 0, 0, bg.width, bg.height);
|
||||||
ctx.globalCompositeOperation = 'source-atop';
|
ctx.globalCompositeOperation = 'source-atop';
|
||||||
ctx.drawImage(holeImage, solution.x, solution.y, pw, ph);
|
ctx.drawImage(holeImage, solution.x, solution.y, puzzle.width, puzzle.height);
|
||||||
|
|
||||||
|
// Draw the puzzle piece.
|
||||||
|
pctx.drawImage(maskImage, 0, 0, puzzle.width, puzzle.height);
|
||||||
|
pctx.globalCompositeOperation = 'source-in';
|
||||||
|
pctx.drawImage(bgImage, solution.x, solution.y, puzzle.width, puzzle.height, 0, 0, puzzle.width, puzzle.height);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
bg,
|
bg,
|
||||||
|
|
@ -88,14 +81,12 @@ async function generateCaptcha(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPieceCoords(cw: number, ch: number, pw: number, ph: number): Point {
|
/** Random coordinates such that the piece fits within the canvas. */
|
||||||
// Random x coordinate such that the piece fits within the canvas horizontally
|
function generateSolution(bgSize: Dimensions, puzzleSize: Dimensions): Point {
|
||||||
const x = Math.floor(Math.random() * (cw - pw));
|
return {
|
||||||
|
x: Math.floor(Math.random() * (bgSize.w - puzzleSize.w)),
|
||||||
// Random y coordinate such that the piece fits within the canvas vertically
|
y: Math.floor(Math.random() * (bgSize.h - puzzleSize.h)),
|
||||||
const y = Math.floor(Math.random() * (ch - ph));
|
};
|
||||||
|
|
||||||
return { x, y };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const pointSchema = z.object({
|
const pointSchema = z.object({
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue