fix(B05): 종단 새 창 최대화 때 편집 · 다시 그리기 — 놓인 창 화면 틀 · 시계 공용 함수로 통일(230-2)
공용 common_util_view_window(viewOf · frameOf) 신설. design_profile rebuild · 접기 · render, Heights 높이 맞춤, 표 · 유토곡선 크기 끌기, 유토곡선 세로창 미끄러짐, 끌기 뒤 그리기, ▲▼ · 방향키 길게 누르기, 배수유역도, 구조물 말풍선 — 메인 창 전역 틀 · 시계 대신 요소가 놓인 창 것. 새 시험 test_230_2_popout_frames(메인 창 틀 멈춤 흉내 · 새 창 패널 코드 훑기). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F3mdb91125mPoC6tpsQx4P
This commit is contained in:
@@ -23,6 +23,7 @@ import { MASS_HAUL_BALANCE_KEY } from "./common_util_mass_haul";
|
||||
import { appendBalanceLayer, haulPlanChips } from "./common_util_mass_haul_balance_view";
|
||||
import { segmentOf } from "./common_util_mass_haul_curve";
|
||||
import { L, stationLabel, svgElement, svgText } from "./common_util_svg";
|
||||
import { viewOf } from "./common_util_view_window";
|
||||
|
||||
/**
|
||||
* 유토곡선 X축을 **호출한 쪽 종단 그래프와 맞추는** 값. 좌우 여백과 누가거리 최댓값이
|
||||
@@ -74,6 +75,8 @@ export interface MassHaulWindowState {
|
||||
settled: boolean;
|
||||
/** 예약해 둔 다음 프레임(중복 예약 방지). */
|
||||
frame: number;
|
||||
/** `frame` 을 받아 둔 창 — 걷을 때도 같은 창에서(230-2). */
|
||||
view?: Window;
|
||||
}
|
||||
|
||||
export function createMassHaulWindowState(): MassHaulWindowState {
|
||||
@@ -81,11 +84,17 @@ export function createMassHaulWindowState(): MassHaulWindowState {
|
||||
}
|
||||
|
||||
/** 아직 목표에 못 갔으면 다음 프레임에 한 번 더 그리게 예약한다. */
|
||||
export function scheduleMassHaulSettle(state: MassHaulWindowState, redraw: () => void): void {
|
||||
if (state.frame) cancelAnimationFrame(state.frame);
|
||||
/** `node` = 곡선이 놓인 요소 — 그 창의 틀에서 잰다(새 창 최대화 때 메인 창 틀은 멈춤 · 230-2). */
|
||||
export function scheduleMassHaulSettle(
|
||||
state: MassHaulWindowState,
|
||||
redraw: () => void,
|
||||
node?: Node,
|
||||
): void {
|
||||
if (state.frame) (state.view ?? window).cancelAnimationFrame(state.frame);
|
||||
state.frame = 0;
|
||||
if (state.settled) return;
|
||||
state.frame = requestAnimationFrame(() => {
|
||||
state.view = viewOf(node);
|
||||
state.frame = state.view.requestAnimationFrame(() => {
|
||||
state.frame = 0;
|
||||
redraw();
|
||||
});
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/* =============================================================================
|
||||
* common_util_view_window.ts
|
||||
* 요소가 지금 놓인 창 — 종단 패널을 새 창으로 빼면 그 창이다(230-1 · 230-2).
|
||||
*
|
||||
* 메인 창 전역 `requestAnimationFrame` · 시계를 쓰면, 새 창을 최대화해 메인 창이 가려질 때
|
||||
* 브라우저가 메인 창 화면 틀을 멈추고 시계를 늦춰 휠 · 편집 · 다시 그리기가 멈췄다.
|
||||
* 화면 틀 · 시계는 이 함수로 그 요소의 창에서 받는다.
|
||||
* ========================================================================== */
|
||||
|
||||
/** 요소가 놓인 창(문서에 안 붙었으면 메인 창). */
|
||||
export function viewOf(node: Node | null | undefined): Window {
|
||||
return node?.ownerDocument?.defaultView ?? window;
|
||||
}
|
||||
|
||||
/** 요소가 놓인 창의 다음 화면 틀에 부른다. */
|
||||
export function frameOf(node: Node | null | undefined, callback: FrameRequestCallback): number {
|
||||
return viewOf(node).requestAnimationFrame(callback);
|
||||
}
|
||||
Reference in New Issue
Block a user