@adminide-stack/yantra-mobile 12.0.44-alpha.5 → 12.0.44-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvasCore.js","sources":["../../../src/features/canvas/canvasCore.ts"],"sourcesContent":["/**\n * Platform-agnostic canvas document model — the native twin of the web\n * surface's `state/boards.ts` (`@yantra/canvas-surface`).\n *\n * The shapes are copied, not imported: the surface package builds for the DOM\n * (react-dom peer, vite, `crypto.randomUUID`), so importing it would drag the\n * web toolchain into Metro. The contract that actually matters is the persisted\n * JSON — `PersistedCanvasState` version 1 — and tests below pin this file to\n * fixtures of that JSON, so drift between the copies fails a test rather than\n * corrupting a board.\n *\n * Everything here is pure data + math so it runs identically under Metro,\n * vite, and jest: no RN imports, no DOM globals.\n */\n\nexport interface CanvasItem {\n id: string;\n type: 'image' | 'video' | 'audio';\n src: string;\n x: number;\n y: number;\n width: number;\n height: number;\n zIndex: number;\n generatedAssetName?: string;\n}\n\nexport interface PersistedCanvasState {\n version: 1;\n savedAt: number;\n items: CanvasItem[];\n zoom: number;\n title?: string;\n}\n\n/** Parse a persisted board, tolerating the unknown: bad rows drop, not throw. */\nexport function parseBoardState(raw: unknown): PersistedCanvasState | null {\n if (!raw || typeof raw !== 'object') return null;\n const candidate = raw as Partial<PersistedCanvasState>;\n if (candidate.version !== 1 || !Array.isArray(candidate.items)) return null;\n const items = candidate.items.filter(isRenderableItem);\n return {\n version: 1,\n savedAt: typeof candidate.savedAt === 'number' ? candidate.savedAt : 0,\n items,\n zoom: clampZoom(typeof candidate.zoom === 'number' ? candidate.zoom : 1),\n ...(typeof candidate.title === 'string' && candidate.title ? { title: candidate.title } : {}),\n };\n}\n\n/** An item the viewer can draw. `blob:` URLs died with the web tab that made them. */\nexport function isRenderableItem(item: unknown): item is CanvasItem {\n if (!item || typeof item !== 'object') return false;\n const c = item as Partial<CanvasItem>;\n return (\n typeof c.id === 'string' &&\n (c.type === 'image' || c.type === 'video' || c.type === 'audio') &&\n typeof c.src === 'string' &&\n c.src.length > 0 &&\n !c.src.startsWith('blob:') &&\n [c.x, c.y, c.width, c.height].every((n) => typeof n === 'number' && Number.isFinite(n)) &&\n (c.width as number) > 0 &&\n (c.height as number) > 0\n );\n}\n\nexport const MIN_ZOOM = 0.25;\nexport const MAX_ZOOM = 4;\n\nexport function clampZoom(zoom: number): number {\n if (!Number.isFinite(zoom)) return 1;\n return Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, zoom));\n}\n\nexport interface BoardBounds {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}\n\n/** Union of item rects; null for an empty board (an empty union has no bounds). */\nexport function boardBounds(items: readonly CanvasItem[]): BoardBounds | null {\n if (items.length === 0) return null;\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const it of items) {\n minX = Math.min(minX, it.x);\n minY = Math.min(minY, it.y);\n maxX = Math.max(maxX, it.x + it.width);\n maxY = Math.max(maxY, it.y + it.height);\n }\n return { minX, minY, maxX, maxY };\n}\n\nexport interface FitTransform {\n /** Uniform scale applied to board coordinates. */\n scale: number;\n /** Screen-space translation, applied after scaling. */\n translateX: number;\n translateY: number;\n}\n\n/**\n * Fit the whole board inside a viewport with a margin — the viewer's initial\n * camera. Pure math so pinch/pan gestures can start from a reproducible state.\n */\nexport function fitToViewport(\n bounds: BoardBounds,\n viewportWidth: number,\n viewportHeight: number,\n margin = 24,\n): FitTransform {\n const boardW = Math.max(1, bounds.maxX - bounds.minX);\n const boardH = Math.max(1, bounds.maxY - bounds.minY);\n const availW = Math.max(1, viewportWidth - margin * 2);\n const availH = Math.max(1, viewportHeight - margin * 2);\n const scale = clampZoom(Math.min(availW / boardW, availH / boardH));\n // Center the scaled board in the viewport.\n const translateX = (viewportWidth - boardW * scale) / 2 - bounds.minX * scale;\n const translateY = (viewportHeight - boardH * scale) / 2 - bounds.minY * scale;\n return { scale, translateX, translateY };\n}\n\n/** Painter's order: stable sort by zIndex so overlapping media stack as authored. */\nexport function paintOrder(items: readonly CanvasItem[]): CanvasItem[] {\n return [...items].sort((a, b) => a.zIndex - b.zIndex || a.id.localeCompare(b.id));\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAmCO,SAAS,gBAAgB,GAA2C,EAAA;AACzE,EAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,UAAiB,OAAA,IAAA;AAC5C,EAAA,MAAM,SAAY,GAAA,GAAA;AAClB,EAAI,IAAA,SAAA,CAAU,YAAY,CAAK,IAAA,CAAC,MAAM,OAAQ,CAAA,SAAA,CAAU,KAAK,CAAA,EAAU,OAAA,IAAA;AACvE,EAAA,MAAM,KAAQ,GAAA,SAAA,CAAU,KAAM,CAAA,MAAA,CAAO,gBAAgB,CAAA;AACrD,EAAO,OAAA,cAAA,CAAA;AAAA,IACL,OAAS,EAAA,CAAA;AAAA,IACT,SAAS,OAAO,SAAA,CAAU,OAAY,KAAA,QAAA,GAAW,UAAU,OAAU,GAAA,CAAA;AAAA,IACrE,KAAA;AAAA,IACA,IAAA,EAAM,UAAU,OAAO,SAAA,CAAU,SAAS,QAAW,GAAA,SAAA,CAAU,OAAO,CAAC;AAAA,GAAA,EACnE,OAAO,SAAA,CAAU,KAAU,KAAA,QAAA,IAAY,UAAU,KAAQ,GAAA;AAAA,IAC3D,OAAO,SAAU,CAAA;AAAA,MACf,EAAC,CAAA;AAET;AAGO,SAAS,iBAAiB,IAAmC,EAAA;AAClE,EAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,UAAiB,OAAA,KAAA;AAC9C,EAAA,MAAM,CAAI,GAAA,IAAA;AACV,EAAO,OAAA,OAAO,EAAE,EAAO,KAAA,QAAA,KAAa,EAAE,IAAS,KAAA,OAAA,IAAW,CAAE,CAAA,IAAA,KAAS,OAAW,IAAA,CAAA,CAAE,SAAS,OAAY,CAAA,IAAA,OAAO,CAAE,CAAA,GAAA,KAAQ,QAAY,IAAA,CAAA,CAAE,IAAI,MAAS,GAAA,CAAA,IAAK,CAAC,CAAA,CAAE,GAAI,CAAA,UAAA,CAAW,OAAO,CAAK,IAAA,CAAC,CAAE,CAAA,CAAA,EAAG,CAAE,CAAA,CAAA,EAAG,EAAE,KAAO,EAAA,CAAA,CAAE,MAAM,CAAA,CAAE,KAAM,CAAA,CAAA,CAAA,KAAK,OAAO,CAAM,KAAA,QAAA,IAAY,MAAO,CAAA,QAAA,CAAS,CAAC,CAAC,KAAK,CAAE,CAAA,KAAA,GAAkB,CAAK,IAAA,CAAA,CAAE,MAAmB,GAAA,CAAA;AAC/T;
|
|
1
|
+
{"version":3,"file":"canvasCore.js","sources":["../../../src/features/canvas/canvasCore.ts"],"sourcesContent":["/**\n * Platform-agnostic canvas document model — the native twin of the web\n * surface's `state/boards.ts` (`@yantra/canvas-surface`).\n *\n * The shapes are copied, not imported: the surface package builds for the DOM\n * (react-dom peer, vite, `crypto.randomUUID`), so importing it would drag the\n * web toolchain into Metro. The contract that actually matters is the persisted\n * JSON — `PersistedCanvasState` version 1 — and tests below pin this file to\n * fixtures of that JSON, so drift between the copies fails a test rather than\n * corrupting a board.\n *\n * Everything here is pure data + math so it runs identically under Metro,\n * vite, and jest: no RN imports, no DOM globals.\n */\n\nexport interface CanvasItem {\n id: string;\n type: 'image' | 'video' | 'audio';\n src: string;\n x: number;\n y: number;\n width: number;\n height: number;\n zIndex: number;\n generatedAssetName?: string;\n}\n\nexport interface PersistedCanvasState {\n version: 1;\n savedAt: number;\n items: CanvasItem[];\n zoom: number;\n title?: string;\n}\n\n/** Parse a persisted board, tolerating the unknown: bad rows drop, not throw. */\nexport function parseBoardState(raw: unknown): PersistedCanvasState | null {\n if (!raw || typeof raw !== 'object') return null;\n const candidate = raw as Partial<PersistedCanvasState>;\n if (candidate.version !== 1 || !Array.isArray(candidate.items)) return null;\n const items = candidate.items.filter(isRenderableItem);\n return {\n version: 1,\n savedAt: typeof candidate.savedAt === 'number' ? candidate.savedAt : 0,\n items,\n zoom: clampZoom(typeof candidate.zoom === 'number' ? candidate.zoom : 1),\n ...(typeof candidate.title === 'string' && candidate.title ? { title: candidate.title } : {}),\n };\n}\n\n/** An item the viewer can draw. `blob:` URLs died with the web tab that made them. */\nexport function isRenderableItem(item: unknown): item is CanvasItem {\n if (!item || typeof item !== 'object') return false;\n const c = item as Partial<CanvasItem>;\n return (\n typeof c.id === 'string' &&\n (c.type === 'image' || c.type === 'video' || c.type === 'audio') &&\n typeof c.src === 'string' &&\n c.src.length > 0 &&\n !c.src.startsWith('blob:') &&\n [c.x, c.y, c.width, c.height].every((n) => typeof n === 'number' && Number.isFinite(n)) &&\n (c.width as number) > 0 &&\n (c.height as number) > 0\n );\n}\n\n/** Floor for item edits - a rect can never be resized away entirely. */\nexport const MIN_ITEM_SIZE = 24;\n\nexport interface ItemFrame {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport type ResizeCorner = 'tl' | 'tr' | 'bl' | 'br';\n\n/**\n * Resize `frame` by dragging `corner` by (dx, dy) board units, keeping the\n * OPPOSITE corner anchored - the gesture the selection handles drive. Both\n * axes move independently (free-form resize); each side clamps at\n * MIN_ITEM_SIZE so a rect can shrink to a nub but never invert or vanish.\n *\n * Marked as a worklet: the resize handles call this per-frame on the UI\n * thread. The directive is inert everywhere else (plain string in node/jest).\n */\nexport function resizeFrame(frame: ItemFrame, corner: ResizeCorner, dx: number, dy: number): ItemFrame {\n 'worklet';\n\n const left = corner === 'tl' || corner === 'bl';\n const top = corner === 'tl' || corner === 'tr';\n\n const width = Math.max(MIN_ITEM_SIZE, left ? frame.width - dx : frame.width + dx);\n const height = Math.max(MIN_ITEM_SIZE, top ? frame.height - dy : frame.height + dy);\n\n return {\n // Anchor the opposite corner: a left/top edge moves by however much the\n // clamped size actually changed, not by the raw drag delta.\n x: left ? frame.x + (frame.width - width) : frame.x,\n y: top ? frame.y + (frame.height - height) : frame.y,\n width,\n height,\n };\n}\n\n/** New items array with `id`'s frame replaced - the commit step after a drag\n * or resize gesture ends. Unknown ids return the array unchanged. */\nexport function applyItemFrame(items: readonly CanvasItem[], id: string, frame: ItemFrame): CanvasItem[] {\n return items.map((item) => (item.id === id ? { ...item, ...frame } : item));\n}\n\nexport const MIN_ZOOM = 0.25;\nexport const MAX_ZOOM = 4;\n\nexport function clampZoom(zoom: number): number {\n if (!Number.isFinite(zoom)) return 1;\n return Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, zoom));\n}\n\nexport interface BoardBounds {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}\n\n/** Union of item rects; null for an empty board (an empty union has no bounds). */\nexport function boardBounds(items: readonly CanvasItem[]): BoardBounds | null {\n if (items.length === 0) return null;\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const it of items) {\n minX = Math.min(minX, it.x);\n minY = Math.min(minY, it.y);\n maxX = Math.max(maxX, it.x + it.width);\n maxY = Math.max(maxY, it.y + it.height);\n }\n return { minX, minY, maxX, maxY };\n}\n\nexport interface FitTransform {\n /** Uniform scale applied to board coordinates. */\n scale: number;\n /** Screen-space translation, applied after scaling. */\n translateX: number;\n translateY: number;\n}\n\n/**\n * Fit the whole board inside a viewport with a margin — the viewer's initial\n * camera. Pure math so pinch/pan gestures can start from a reproducible state.\n */\nexport function fitToViewport(\n bounds: BoardBounds,\n viewportWidth: number,\n viewportHeight: number,\n margin = 24,\n): FitTransform {\n const boardW = Math.max(1, bounds.maxX - bounds.minX);\n const boardH = Math.max(1, bounds.maxY - bounds.minY);\n const availW = Math.max(1, viewportWidth - margin * 2);\n const availH = Math.max(1, viewportHeight - margin * 2);\n const scale = clampZoom(Math.min(availW / boardW, availH / boardH));\n // Center the scaled board in the viewport.\n const translateX = (viewportWidth - boardW * scale) / 2 - bounds.minX * scale;\n const translateY = (viewportHeight - boardH * scale) / 2 - bounds.minY * scale;\n return { scale, translateX, translateY };\n}\n\n/** Painter's order: stable sort by zIndex so overlapping media stack as authored. */\nexport function paintOrder(items: readonly CanvasItem[]): CanvasItem[] {\n return [...items].sort((a, b) => a.zIndex - b.zIndex || a.id.localeCompare(b.id));\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAmCO,SAAS,gBAAgB,GAA2C,EAAA;AACzE,EAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,UAAiB,OAAA,IAAA;AAC5C,EAAA,MAAM,SAAY,GAAA,GAAA;AAClB,EAAI,IAAA,SAAA,CAAU,YAAY,CAAK,IAAA,CAAC,MAAM,OAAQ,CAAA,SAAA,CAAU,KAAK,CAAA,EAAU,OAAA,IAAA;AACvE,EAAA,MAAM,KAAQ,GAAA,SAAA,CAAU,KAAM,CAAA,MAAA,CAAO,gBAAgB,CAAA;AACrD,EAAO,OAAA,cAAA,CAAA;AAAA,IACL,OAAS,EAAA,CAAA;AAAA,IACT,SAAS,OAAO,SAAA,CAAU,OAAY,KAAA,QAAA,GAAW,UAAU,OAAU,GAAA,CAAA;AAAA,IACrE,KAAA;AAAA,IACA,IAAA,EAAM,UAAU,OAAO,SAAA,CAAU,SAAS,QAAW,GAAA,SAAA,CAAU,OAAO,CAAC;AAAA,GAAA,EACnE,OAAO,SAAA,CAAU,KAAU,KAAA,QAAA,IAAY,UAAU,KAAQ,GAAA;AAAA,IAC3D,OAAO,SAAU,CAAA;AAAA,MACf,EAAC,CAAA;AAET;AAGO,SAAS,iBAAiB,IAAmC,EAAA;AAClE,EAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,UAAiB,OAAA,KAAA;AAC9C,EAAA,MAAM,CAAI,GAAA,IAAA;AACV,EAAO,OAAA,OAAO,EAAE,EAAO,KAAA,QAAA,KAAa,EAAE,IAAS,KAAA,OAAA,IAAW,CAAE,CAAA,IAAA,KAAS,OAAW,IAAA,CAAA,CAAE,SAAS,OAAY,CAAA,IAAA,OAAO,CAAE,CAAA,GAAA,KAAQ,QAAY,IAAA,CAAA,CAAE,IAAI,MAAS,GAAA,CAAA,IAAK,CAAC,CAAA,CAAE,GAAI,CAAA,UAAA,CAAW,OAAO,CAAK,IAAA,CAAC,CAAE,CAAA,CAAA,EAAG,CAAE,CAAA,CAAA,EAAG,EAAE,KAAO,EAAA,CAAA,CAAE,MAAM,CAAA,CAAE,KAAM,CAAA,CAAA,CAAA,KAAK,OAAO,CAAM,KAAA,QAAA,IAAY,MAAO,CAAA,QAAA,CAAS,CAAC,CAAC,KAAK,CAAE,CAAA,KAAA,GAAkB,CAAK,IAAA,CAAA,CAAE,MAAmB,GAAA,CAAA;AAC/T;AA8CO,MAAM,QAAW,GAAA;AACjB,MAAM,QAAW,GAAA;AACjB,SAAS,UAAU,IAAsB,EAAA;AAC9C,EAAA,IAAI,CAAC,MAAA,CAAO,QAAS,CAAA,IAAI,GAAU,OAAA,CAAA;AACnC,EAAA,OAAO,KAAK,GAAI,CAAA,QAAA,EAAU,KAAK,GAAI,CAAA,QAAA,EAAU,IAAI,CAAC,CAAA;AACpD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adminide-stack/yantra-mobile",
|
|
3
|
-
"version": "12.0.44-alpha.
|
|
3
|
+
"version": "12.0.44-alpha.6",
|
|
4
4
|
"description": "Sample core for higher packages to depend on",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"author": "CDMBase LLC",
|
|
@@ -56,5 +56,5 @@
|
|
|
56
56
|
"typescript": {
|
|
57
57
|
"definition": "lib/index.d.ts"
|
|
58
58
|
},
|
|
59
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "b13e97b0fd11278d23ce0a1b405175a0be00ef88"
|
|
60
60
|
}
|