fix(rsocials): campaign planner loads with fit-to-view on initial visit
Previously the planner restored a stale zoomed-out viewport from localStorage, and fitView() could fail silently if the SVG had zero dimensions during shadow DOM layout. Now: skip viewport restore on initial load, retry fitView up to 3 rAFs, and clamp min zoom to 50%. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
9a7548e5ca
commit
932151aa88
|
|
@ -193,6 +193,7 @@ class FolkCampaignPlanner extends HTMLElement {
|
|||
private _boundPointerMove: ((e: PointerEvent) => void) | null = null;
|
||||
private _boundPointerUp: ((e: PointerEvent) => void) | null = null;
|
||||
private _boundKeyDown: ((e: KeyboardEvent) => void) | null = null;
|
||||
private _initialLoad = true;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
|
@ -302,7 +303,7 @@ class FolkCampaignPlanner extends HTMLElement {
|
|||
}
|
||||
|
||||
private restoreViewport() {
|
||||
if (!this.currentFlowId) return;
|
||||
if (!this.currentFlowId || this._initialLoad) return;
|
||||
try {
|
||||
const raw = localStorage.getItem(`rsocials:vp:${this.currentFlowId}`);
|
||||
if (raw) {
|
||||
|
|
@ -328,11 +329,14 @@ class FolkCampaignPlanner extends HTMLElement {
|
|||
if (el) el.textContent = `${Math.round(this.canvasZoom * 100)}%`;
|
||||
}
|
||||
|
||||
private fitView() {
|
||||
private fitView(retries = 3) {
|
||||
const svg = this.shadow.getElementById('cp-svg') as SVGSVGElement | null;
|
||||
if (!svg || this.nodes.length === 0) return;
|
||||
const rect = svg.getBoundingClientRect();
|
||||
if (rect.width === 0 || rect.height === 0) return;
|
||||
if (rect.width === 0 || rect.height === 0) {
|
||||
if (retries > 0) requestAnimationFrame(() => this.fitView(retries - 1));
|
||||
return;
|
||||
}
|
||||
|
||||
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
||||
for (const n of this.nodes) {
|
||||
|
|
@ -343,15 +347,16 @@ class FolkCampaignPlanner extends HTMLElement {
|
|||
maxY = Math.max(maxY, n.position.y + s.h);
|
||||
}
|
||||
|
||||
const pad = 60;
|
||||
const pad = 40;
|
||||
const contentW = maxX - minX + pad * 2;
|
||||
const contentH = maxY - minY + pad * 2;
|
||||
const scaleX = rect.width / contentW;
|
||||
const scaleY = rect.height / contentH;
|
||||
this.canvasZoom = Math.min(scaleX, scaleY, 1.5);
|
||||
this.canvasZoom = Math.max(0.5, Math.min(scaleX, scaleY, 1.5));
|
||||
this.canvasPanX = (rect.width - contentW * this.canvasZoom) / 2 - (minX - pad) * this.canvasZoom;
|
||||
this.canvasPanY = (rect.height - contentH * this.canvasZoom) / 2 - (minY - pad) * this.canvasZoom;
|
||||
this.updateCanvasTransform();
|
||||
this._initialLoad = false;
|
||||
}
|
||||
|
||||
private zoomAt(screenX: number, screenY: number, factor: number) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue