mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 11:29:46 +00:00
Mask the puzzle piece
This commit is contained in:
parent
707674db7c
commit
03c9340eb2
2 changed files with 27 additions and 3 deletions
BIN
captcha/puzzle.png
Normal file
BIN
captcha/puzzle.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.7 KiB |
|
|
@ -8,12 +8,13 @@ import { aesEncrypt } from '@/utils/aes.ts';
|
|||
export const captchaController: AppController = async (c) => {
|
||||
const { puzzle, piece, solution } = await generateCaptcha(
|
||||
await Deno.readFile(new URL('../../../captcha/tj-holowaychuk.jpg', import.meta.url)),
|
||||
await Deno.readFile(new URL('../../../captcha/puzzle.png', import.meta.url)),
|
||||
{
|
||||
cw: 300,
|
||||
ch: 300,
|
||||
pw: 50,
|
||||
ph: 50,
|
||||
alpha: 0.6,
|
||||
alpha: 0.8,
|
||||
},
|
||||
);
|
||||
|
||||
|
|
@ -41,6 +42,7 @@ interface Point {
|
|||
|
||||
async function generateCaptcha(
|
||||
from: Uint8Array,
|
||||
mask: Uint8Array,
|
||||
opts: {
|
||||
pw: number;
|
||||
ph: number;
|
||||
|
|
@ -54,12 +56,34 @@ async function generateCaptcha(
|
|||
const ctx = puzzle.getContext('2d');
|
||||
const image = await loadImage(from);
|
||||
ctx.drawImage(image, 0, 0, image.width(), image.height(), 0, 0, cw, ch);
|
||||
|
||||
const piece = createCanvas(pw, ph);
|
||||
const pctx = piece.getContext('2d');
|
||||
|
||||
const solution = getPieceCoords(puzzle.width, puzzle.height, pw, ph);
|
||||
|
||||
// Draw the piece onto the puzzle piece canvas but only where the mask allows
|
||||
const maskImage = await loadImage(mask);
|
||||
pctx.globalCompositeOperation = 'source-over';
|
||||
pctx.drawImage(maskImage, 0, 0, pw, ph);
|
||||
pctx.globalCompositeOperation = 'source-in';
|
||||
pctx.drawImage(puzzle, solution.x, solution.y, pw, ph, 0, 0, pw, ph);
|
||||
ctx.fillStyle = `rgba(0, 0, 0, ${alpha})`;
|
||||
ctx.fillRect(solution.x, solution.y, pw, ph);
|
||||
|
||||
// Reset composite operation
|
||||
pctx.globalCompositeOperation = 'source-over';
|
||||
|
||||
// Create a temporary canvas to draw the darkened shape
|
||||
const tempCanvas = createCanvas(pw, ph);
|
||||
const tempCtx = tempCanvas.getContext('2d');
|
||||
|
||||
// Draw the darkened shape onto the temporary canvas but only where the mask allows
|
||||
tempCtx.fillStyle = `rgba(0, 0, 0, ${alpha})`;
|
||||
tempCtx.fillRect(0, 0, pw, ph);
|
||||
tempCtx.globalCompositeOperation = 'destination-in';
|
||||
tempCtx.drawImage(maskImage, 0, 0, pw, ph);
|
||||
|
||||
// Draw the temporary canvas onto the puzzle at the piece's location
|
||||
ctx.drawImage(tempCanvas, solution.x, solution.y, pw, ph);
|
||||
|
||||
return {
|
||||
puzzle,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue