feat(b06): [상세] 모달 첫 보기 = 중심점이 칸 가운데 · 그림 전체가 들어가게 축마다 큰 쪽 반폭 · [⤢] · 더블클릭 원복 같은 보기 (295-2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014utrjfoW831Vc5wJUd13kL
This commit is contained in:
@@ -63,6 +63,8 @@ export interface SvgZoomPanOptions {
|
||||
initial?: ZoomPanState;
|
||||
/** 처음 · 원복 배율(기본 1) — 플롯 중앙을 붙잡음 · 이보다 작게도 줄일 수 있음(266-1 B06 상세). */
|
||||
homeScale?: number;
|
||||
/** 처음 · 원복 상태를 통째로(295-2 B06 상세 — 중심점 가운데) · 주면 `homeScale` 대신 · 1 보다 작아도 됨. */
|
||||
home?: ZoomPanState;
|
||||
/** 상태가 바뀔 때마다 부른다 — 바깥이 담아 뒀다가 다음 그림에 되돌린다. */
|
||||
onChange?: (state: ZoomPanState) => void;
|
||||
/** 도형이 실제로 그려진 범위. 확대 상태에서 팬 한계가 여기까지 늘어난다. */
|
||||
@@ -88,11 +90,13 @@ export function attachSvgZoomPan(options: SvgZoomPanOptions): ZoomPanHandle {
|
||||
};
|
||||
const maxScale = options.maxScale ?? 8;
|
||||
const homeScale = Math.min(Math.max(options.homeScale ?? 1, 1), maxScale);
|
||||
const home: ZoomPanState = {
|
||||
const home: ZoomPanState = options.home ?? {
|
||||
scale: homeScale,
|
||||
tx: (plot.x + plot.width / 2) * (1 - homeScale),
|
||||
ty: (plot.y + plot.height / 2) * (1 - homeScale),
|
||||
};
|
||||
/** 축소 한계 — 1배 · 처음 보기가 더 작으면 그만큼. */
|
||||
const minScale = Math.min(1, home.scale);
|
||||
let scale = initial?.scale ?? home.scale;
|
||||
let tx = initial?.tx ?? home.tx;
|
||||
let ty = initial?.ty ?? home.ty;
|
||||
@@ -132,7 +136,7 @@ export function attachSvgZoomPan(options: SvgZoomPanOptions): ZoomPanHandle {
|
||||
|
||||
/** 그 자리를 붙잡고 확대·축소한다 — 버튼은 플롯 중앙을, 휠은 커서 자리를 준다. */
|
||||
const zoomAt = (factor: number, cx: number, cy: number): void => {
|
||||
const next = Math.min(maxScale, Math.max(1, scale * factor));
|
||||
const next = Math.min(maxScale, Math.max(minScale, scale * factor));
|
||||
tx = cx - ((cx - tx) / scale) * next;
|
||||
ty = cy - ((cy - ty) / scale) * next;
|
||||
scale = next;
|
||||
|
||||
Reference in New Issue
Block a user