From befe8fe19ad7e47831eebd3684c9e7687b9ee1da Mon Sep 17 00:00:00 2001 From: IliesAllali Date: Sun, 25 Oct 2026 16:57:08 +0100 Subject: [PATCH] =?UTF-8?q?=C2=AB=20=C3=80=20v=C3=A9rifier=20=C2=BB=20:=20?= =?UTF-8?q?drawPortrait,=20et=20un=20test=20qui=20=C3=A9choue=20si=20la=20?= =?UTF-8?q?marque=20repasse=20sous=20la=20d=C3=A9coupe=20du=20cadre?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- frontend/src/components/galaxy/renderers.js | 18 ++++++++------ .../src/components/galaxy/renderers.test.js | 24 ++++++++++++++++++- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/galaxy/renderers.js b/frontend/src/components/galaxy/renderers.js index 381f9a8..e9488b5 100644 --- a/frontend/src/components/galaxy/renderers.js +++ b/frontend/src/components/galaxy/renderers.js @@ -602,13 +602,7 @@ function drawPersonNode(ctx, node, pos, nodeProgress, { ctx.shadowOffsetY = shadowY } - // Le cadre découpe le canvas à sa forme : save/restore autour, sinon la marque ci-dessous est rognée - // (sur un cadre rond, elle tombe presque entière hors du cercle) - ctx.save() - drawFrame(ctx, frameType, person, img) - ctx.restore() - // « À vérifier » : petit rond terracotta avec un « ? » en haut à droite du cadre, absent au dézoom - if (person.toVerify && withDetail) drawToVerifyMark(ctx) + drawPortrait(ctx, frameType, person, img, person.toVerify && withDetail) ctx.restore() // --- Labels (estompés puis absents en dézoom) --- @@ -935,6 +929,16 @@ function resolveFrameType(person, img) { return resolveFrameKind(person.frameType || 'round', ratio, cropShape(person.avatarCrop)) } +// Cadre et portrait, puis la marque « À vérifier » (petit rond terracotta avec un « ? » en haut à droite du cadre, +// absente au dézoom). Le cadre découpe le canvas à sa forme : save/restore autour, sinon la marque est rognée +// (sur un cadre rond, elle tombe presque entière hors du cercle) +export function drawPortrait(ctx, frameType, person, img, withMark) { + ctx.save() + drawFrame(ctx, frameType, person, img) + ctx.restore() + if (withMark) drawToVerifyMark(ctx) +} + function drawToVerifyMark(ctx) { const r = 9 const x = PERSON_R * 0.74, y = -PERSON_R * 0.74 diff --git a/frontend/src/components/galaxy/renderers.test.js b/frontend/src/components/galaxy/renderers.test.js index a600ef0..91da576 100644 --- a/frontend/src/components/galaxy/renderers.test.js +++ b/frontend/src/components/galaxy/renderers.test.js @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest' -import { traceSibship } from './renderers' +import { drawPortrait, traceSibship } from './renderers' // Contexte canvas minimal qui enregistre les appels de tracé const recorder = () => { @@ -49,3 +49,25 @@ describe('traceSibship (accolade franche)', () => { expect(curve.slice(5)).toEqual([515, 480]) }) }) + +describe('drawPortrait, marque « À vérifier »', () => { + const person = { firstName: 'Marie', lastName: 'Martin', isAlive: true } + for (const frame of ['round', 'square', 'polaroid', 'rect']) { + it(`cadre ${frame} : la marque est dessinée hors de la découpe du cadre`, () => { + const { ctx, calls } = recorder() + drawPortrait(ctx, frame, person, null, true) + const clip = calls.findIndex(c => c[0] === 'clip') + const restore = calls.findIndex((c, i) => i > clip && c[0] === 'restore') + const markText = calls.findIndex(c => c[0] === 'fillText' && c[1] === '?') + expect(clip).toBeGreaterThan(-1) + expect(restore).toBeGreaterThan(clip) + expect(markText).toBeGreaterThan(restore) + }) + } + + it('sans « À vérifier », pas de marque', () => { + const { ctx, calls } = recorder() + drawPortrait(ctx, 'round', person, null, false) + expect(calls.some(c => c[0] === 'fillText' && c[1] === '?')).toBe(false) + }) +})