| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- import { describe, expect, it } from 'vitest';
- import { pickObjectIdAt, plateClickToMaskPoint } from '../../utils/skipObjects';
- function imageData(width: number, height: number, pixels: number[]): ImageData {
- return {
- width,
- height,
- data: new Uint8ClampedArray(pixels),
- colorSpace: 'srgb',
- } as ImageData;
- }
- describe('pickObjectIdAt', () => {
- it('decodes the slicer object ID from RGB channels', () => {
- const pick = imageData(2, 1, [
- 0, 0, 0, 0,
- 52, 18, 1, 255,
- ]);
- expect(pickObjectIdAt(pick, 1, 0)).toBe(1 * 65536 + 18 * 256 + 52);
- });
- it('treats transparent and black pixels as empty plate space', () => {
- const pick = imageData(2, 1, [
- 8, 0, 0, 0,
- 0, 0, 0, 255,
- ]);
- expect(pickObjectIdAt(pick, 0, 0)).toBeNull();
- expect(pickObjectIdAt(pick, 1, 0)).toBeNull();
- });
- it('clamps click coordinates to the image bounds', () => {
- const pick = imageData(1, 1, [63, 0, 0, 255]);
- expect(pickObjectIdAt(pick, 99, -4)).toBe(63);
- });
- });
- describe('plateClickToMaskPoint', () => {
- const square = { left: 100, top: 50, width: 400, height: 400 };
- it('maps a click through the display scale when the mask fills the box', () => {
- // 400px box, 200px mask: the centre of the box is the centre of the mask.
- expect(plateClickToMaskPoint(square, 200, 200, 300, 250)).toEqual({ x: 100, y: 100 });
- });
- it('offsets by the letterbox bars when the mask is not square', () => {
- // A 200x100 mask in a 400x400 box renders 400x200, leaving 100px bars top
- // and bottom. Without that offset this click would read 100px too low.
- expect(plateClickToMaskPoint(square, 200, 100, 300, 250)).toEqual({ x: 100, y: 50 });
- });
- it('rejects clicks on a letterbox bar rather than clamping onto an edge object', () => {
- expect(plateClickToMaskPoint(square, 200, 100, 300, 100)).toBeNull();
- expect(plateClickToMaskPoint(square, 200, 100, 300, 400)).toBeNull();
- });
- it('rejects clicks outside the plate box', () => {
- expect(plateClickToMaskPoint(square, 200, 200, 90, 250)).toBeNull();
- expect(plateClickToMaskPoint(square, 200, 200, 300, 460)).toBeNull();
- });
- it('returns null for a collapsed box instead of dividing by zero', () => {
- expect(plateClickToMaskPoint({ left: 0, top: 0, width: 0, height: 0 }, 200, 200, 0, 0)).toBeNull();
- });
- });
|