fix(ui): correct horizontal drag direction in 360 panorama viewer

The panorama viewer inverted horizontal drag relative to vertical: the
yaw sign was opposite, so dragging right turned the view right instead
of moving the scene right. Flip yaw to match the pitch convention
(drag the world) and lock the behavior with a ui-workspace scenario.
This commit is contained in:
iu
2026-10-11 21:02:01 +03:00
parent a72d8876d6
commit 6528abad82
5 changed files with 89 additions and 1 deletions
@@ -303,7 +303,7 @@ void main() {
const dy = e.clientY - lastY;
lastX = e.clientX;
lastY = e.clientY;
yaw -= dx * k;
yaw += dx * k;
pitch = Math.max(-PITCH_LIMIT, Math.min(PITCH_LIMIT, pitch + dy * k));
dirty = true;
requestRender();
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-10-11
@@ -0,0 +1,32 @@
# Proposal
## Why
In the 360 panorama viewer the horizontal drag moves the view the wrong way: it is
inverted relative to the vertical drag. The two axes use opposite sign conventions
(`PanoViewer.svelte`, `onPointerMove`), so horizontal feels "swapped" while vertical
feels correct.
## What Changes
- Align the horizontal drag with the vertical one: dragging right moves the scene
right (the view turns left), matching the "drag the world" feel already provided
by the vertical drag.
- Clarify the `ui-workspace` panorama requirement with a scenario fixing the
direction convention, so the behavior is testable and does not regress.
## Capabilities
### New Capabilities
<!-- none -->
### Modified Capabilities
- `ui-workspace`: the «Просмотр 360-панорамы» requirement gains a direction
scenario — dragging moves the scene with the pointer on both axes.
## Impact
- Frontend: `frontend/src/lib/components/PanoViewer.svelte` (`onPointerMove`).
- Spec: `openspec/specs/ui-workspace/spec.md` («Просмотр 360-панорамы»).
@@ -0,0 +1,39 @@
# Spec Delta
## MODIFIED Requirements
### Requirement: Просмотр 360-панорамы
Фото с тегом `pano360` SHALL открываться в режиме сферического обзора (equirect) вместо плоского
изображения. Перетаскивание SHALL менять направление взгляда и SHALL перемещать сцену вслед за
указателем по обеим осям согласованно, колесо — угол обзора, `Space` — сбрасывать вид. Остальные
фото SHALL просматриваться как прежде. При недоступности WebGL или сбое загрузки/декодирования
SHALL показываться плоское изображение. На публичных share-страницах панорамный режим SHALL не
активироваться.
#### Scenario: Обзор панорамы
- **WHEN** пользователь открывает фото с тегом `pano360`
- **THEN** показывается сферический обзор, и перетаскивание меняет направление взгляда
#### Scenario: Направление перетаскивания
- **WHEN** в режиме панорамы пользователь перетаскивает вправо
- **THEN** сцена перемещается вправо (направление взгляда поворачивается влево), согласованно с вертикальным перетаскиванием
#### Scenario: Обычное фото
- **WHEN** пользователь открывает фото без тега `pano360`
- **THEN** показывается обычное плоское изображение
#### Scenario: Управление обзором
- **WHEN** в режиме панорамы пользователь вращает колесо или нажимает `Space`
- **THEN** колесо меняет угол обзора, а `Space` сбрасывает направление взгляда и угол обзора
#### Scenario: Навигация между фото
- **WHEN** в режиме панорамы пользователь нажимает стрелки влево/вправо или выбирает миниатюру
- **THEN** открывается соседнее фото, панорамный режим включается или выключается по его тегу
#### Scenario: Нет WebGL
- **WHEN** WebGL недоступен или изображение не загружается
- **THEN** показывается плоское изображение
#### Scenario: Публичная share-страница
- **WHEN** фото открыто по публичной share-ссылке
- **THEN** панорамный режим не активируется, показывается плоское изображение
@@ -0,0 +1,15 @@
# Tasks
## 1. Fix horizontal drag direction
- [x] 1.1 In `frontend/src/lib/components/PanoViewer.svelte` `onPointerMove`, change `yaw -= dx * k` to `yaw += dx * k` so dragging right moves the scene right, consistent with the vertical drag; verify by opening a `pano360` photo and dragging right — the scene moves right while vertical behavior is unchanged.
- [x] 1.2 Confirm the change does not alter `pitch` handling or the wheel/reset behavior; verify with `npm run check`.
## 2. Integration verification
- [x] 2.1 Run `npm run check` and `npm run build` (frontend); verify both pass with no regressions.
## Workflow follow-up
- Run `/opsx-apply` to implement this change.
- Archive the change after review and verification (sync the delta spec into `ui-workspace`).