diff --git a/docs/specs/447-exterior-furniture-snap-keyboard-nudge.md b/docs/specs/447-exterior-furniture-snap-keyboard-nudge.md index 5003f599..5c003647 100644 --- a/docs/specs/447-exterior-furniture-snap-keyboard-nudge.md +++ b/docs/specs/447-exterior-furniture-snap-keyboard-nudge.md @@ -54,7 +54,8 @@ drag или ручного ввода координат. - одинаковая наружная геометрия для hover preview, clean placement и drag существующей мебели; - ArrowLeft/Right/Up/Down для любого выбранного элемента `space.decor[]`; -- шаг ровно в один `gridPitch` по соответствующей оси холста; +- видимый шаг ровно в один `gridPitch` в render-координатах по соответствующей + оси холста, с явным переводом в нормализованные persisted-поля; - общий Undo/Redo, сохранение и canvas clamp для клавиатурного сдвига; - unit, browser smoke, отрицательные witnesses и пользовательская документация. @@ -133,15 +134,24 @@ resolver. `Shift` по-прежнему полностью отключает wa | Клавиша | Дельта render-координат | |---|---:| -| `ArrowLeft` | `x -= gridPitch` | -| `ArrowRight` | `x += gridPitch` | -| `ArrowUp` | `y -= gridPitch` | -| `ArrowDown` | `y += gridPitch` | +| `ArrowLeft` | `renderX -= gridPitch` | +| `ArrowRight` | `renderX += gridPitch` | +| `ArrowUp` | `renderY -= gridPitch` | +| `ArrowDown` | `renderY += gridPitch` | -Для box-kind меняются `x/y`; у линии одной и той же дельтой меняются обе -конечные точки. Угол, размеры, отражение, стиль, identity и порядок слоя не -меняются. Сдвиг сохраняет текущую off-grid фазу: к координате прибавляется -ровно одна клетка, сама координата не округляется к ближайшему узлу. +Persisted-координаты декора нормализованы, поэтому render-дельта переводится +перед записью тем же преобразованием, что и pointer move: + +- `dxN = renderDx / NORM_W` для `x`, `x1`, `x2`; +- `dyN = renderDy / decorH` для `y`, `y1`, `y2`. + +При квадратном холсте текущего контракта оба значения по модулю равны +`GRID_STEP_N = 1 / GRID_N`. Деления на `cell_cm` нет: `cell_cm` определяет +физический размер видимой клетки, но не меняет её нормализованный шаг. Для +box-kind меняются `x/y`; у линии одной и той же нормализованной дельтой меняются +обе конечные точки. Угол, размеры, отражение, стиль, identity и порядок слоя не +меняются. Сдвиг сохраняет текущую off-grid фазу: к координате прибавляется одна +нормализованная клетка, сама координата не округляется к ближайшему узлу. Команда не вызывает `_decorSnap`, `snapFurnitureToWall` либо placement resolver. Поэтому мебель можно отвести от поверхности на одну клетку и магнит не отменит @@ -244,9 +254,12 @@ intent на snapped point либо удаляющая наружную пове ### AC4. Каждый вид выбранного декора двигается на одну клетку `unit`: для `line`, `rect`, `ellipse`, `text`, `furniture` и `image` четыре -направления меняют только позиционные поля на `gridPitch`, сохраняют off-grid -остаток и все непозиционные поля. Mutation с шагом `1 cm`, округлением anchor к -grid либо движением только одной точки линии краснит соответствующую проверку. +направления дают видимую render-дельту ровно `gridPitch`, а нормализованные поля +меняют на `gridPitch / NORM_W` по X и `gridPitch / decorH` по Y (в текущем +квадратном холсте — `GRID_STEP_N`). Тест сохраняет off-grid остаток и все +непозиционные поля. Mutation, прибавляющая `gridPitch` прямо к persisted-полю, +использующая шаг `1 cm`, округляющая anchor к grid либо двигающая только одну +точку линии, краснит соответствующую проверку. ### AC5. Клавиатурная доводка не включает магниты