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) + }) +})