{ "id": "gsap-988440b33c85", "sourceId": "gsap", "title": "Simple Grid FLIP Modal", "sourceUrl": "https://demos.gsap.com/demo/simple-grid-flip-modal", "demoUrl": "https://codepen.io/GreenSock/pen/XWOeLEb", "sourceStatus": "unresolved", "sourceReason": "Public page unavailable through web browsing", "sourceRevision": null, "sourceLicense": null, "originalDemoAcquired": false, "disposition": "ready_for_independent_study", "evidenceBasis": "catalog_linked_api", "studyId": "gsap-988440b33c85", "sharedStudyCanonicalId": null, "label": "Independently authored documentation study; original Pen unavailable", "catalogEvidence": { "localPath": "artifacts/full-import/gsap/remaining-docs/catalog-evidence.json", "sha256": "4f2a4f9aa64456b85b905b562b60d7733629b41026787b3057cba29e8b10de69", "bytes": 30117, "recordId": "gsap-988440b33c85" }, "sourceInputs": [ { "kind": "authored-study-specification", "localPath": "artifacts/full-import/gsap/remaining-docs/study-specs.json", "sha256": "cbb89331eda8783b5cf2f173b326b9195eeabfb223374fb60019161d9f46d4a6", "bytes": 52279, "recordId": "gsap-988440b33c85" }, { "kind": "official-catalog-metadata", "localPath": "artifacts/full-import/gsap/remaining-docs/catalog-evidence.json", "sha256": "4f2a4f9aa64456b85b905b562b60d7733629b41026787b3057cba29e8b10de69", "bytes": 30117, "recordId": "gsap-988440b33c85" }, { "kind": "official-documentation-evidence", "localPath": "artifacts/full-import/gsap/remaining-docs/official-documentation-evidence.json", "sha256": "bfa25f561e61c597569cf1bc0b3538e6dce4b9985a932775ceab41e665ca24a2", "bytes": 11430, "recordIds": [ "flip-state", "flip" ] }, { "kind": "original-library-source", "localPath": "artifacts/full-import/gsap/library/src/Flip.js", "sha256": "02d87b469498badf49957f4e8ad0d1b5eb9689742cb4bdb06e2c7dc53554d918", "gitBlob": "7e7a3d988fde077ed173e01a54e6c74ed8e38156", "revision": "13e2b790546426a1a2e0e9b409f3f8dc6d6611f2", "sourcePath": "src/Flip.js", "ranges": [ { "id": "flip-state-from", "startLine": 952, "endLine": 966, "rangeSha256": "47528e5c46b86a139a4deccf9b1df4698fe2e47b206c94536bc8099f68a5aa5e" } ] } ], "studiedPrinciple": "Capture a tile's geometry before changing its layout or parent, then animate from that capture into an authored dialog presentation and back.", "namedApis": [ { "name": "Flip.getState(tile)", "purpose": "Capture the selected tile before each open/close layout change.", "libraryEvidence": [ "flip-state-from" ], "documentationEvidence": [ "flip-state" ] }, { "name": "Flip.from(state, vars)", "purpose": "Interpolate from the captured prior geometry to the new DOM layout.", "libraryEvidence": [ "flip-state-from" ], "documentationEvidence": [ "flip" ] } ], "implementationBrief": { "scene": "A grid of six native tile buttons using newly authored colors, shapes, and labels. Selecting a tile presents its visual content larger inside a labeled dialog with a Close button; a placeholder keeps its grid position stable.", "controls": [ { "label": "Open tile", "type": "six native buttons", "action": "Capture the selected visual element and move it to the authored dialog layout." }, { "label": "Close", "type": "button and Escape", "action": "Capture the enlarged visual element, restore its original layout position, and return focus to its opener." }, { "label": "Static view", "type": "toggle", "action": "Keep the same open/close semantics while setting destination layout immediately." } ], "mechanismSteps": [ "Keep a stable DOM element for each tile's visual content and a saved original parent/next sibling. Track the native opener separately for focus restoration.", "Before opening, call Flip.getState on the selected visual element. Then show the dialog, insert a same-sized placeholder in the grid, and move the visual element into the dialog's enlarged layout.", "After the DOM change, call Flip.from with the captured state. The dialog's focus placement, backdrop, size, and content are authored choices.", "For the declared native-dialog strategy, intercept Escape's cancel event and route it through the same close function as the Close button. Capture the enlarged visual element while the dialog is still open.", "In that same close task, call dialog.close(), restore the visual element to its saved parent/sibling position and destination class, remove the placeholder, then call Flip.from with the captured enlarged geometry. Closing the top layer before this animation makes the returning element render in the document instead of behind an open modal backdrop.", "Restore focus to the original opener after the close transition; account for the browser also restoring focus when dialog.close() runs. The backdrop closes immediately in this authored design. Browser verification must confirm no blank frame between dialog closing, reparenting, and Flip initialization.", "Use an explicit transition flag: ignore another tile-open action during a transition, and queue one close request made during opening. This is the declared study policy for rapid input.", "Map both gsap-988440b33c85 and gsap-160507325ef2 to this one independent implementation, retaining their separate catalog identity metadata." ] }, "authoredDefaults": { "tileCount": 6, "durationSeconds": 0.6, "ease": "power2.inOut", "dialogMaximumInlineSize": "min(80vw, 560px)", "dialogStrategy": "native dialog; capture before closing, then close/reparent/start Flip in one task; backdrop closes immediately", "assets": "new inline SVG or CSS shapes; no photography", "rapidInput": "ignore competing opens during transition; queue close during opening" }, "verificationRequired": [ "getState is called before each DOM/layout mutation; opening and closing animate between the actual source and destination geometry.", "Closing restores the original parent/sibling order and removes the placeholder without leaving a duplicate tile.", "Focus enters the dialog, Escape closes it, and focus returns to the correct opener; background content is not accidentally interactive while modal.", "Queued close during opening and repeated keyboard activation settle without orphan nodes or locked transition flags.", "At 320px the dialog remains usable and at 1440px the geometry remains aligned. Static mode follows the same semantic open/close path.", "Both retained original IDs resolve to this study and disclose the exact-Pen alias." ], "unsupportedClaims": [ "Original composition, assets, timing, breakpoint behavior, and live interaction are not observable in captured frames. This brief does not establish visual fidelity or recover original code.", "Only the catalog's Flip.getState link and shared Pen identity are established. Original reparenting strategy, focus handling, backdrop, assets, and transition choreography were not recovered.", "The chosen dialog/top-layer strategy must be checked in a real browser; source inspection alone cannot prove the reparenting animation is correct." ], "dependencies": { "package": "gsap", "version": "3.15.0", "revision": "13e2b790546426a1a2e0e9b409f3f8dc6d6611f2", "repository": "https://github.com/greensock/GSAP", "plugins": [ "Flip" ], "registration": "gsap.registerPlugin(Flip) after loading core and those plugin scripts", "runtimeCandidates": [ { "path": "dist/gsap.js", "localPath": "artifacts/full-import/gsap/library/dist/gsap.js", "gitBlob": "ec5ffee3f099bc454f2f1c79cee6a55ba97e7400", "sha256": "01effe0e121c22ba0f885a3f091f3dc6d1f0d445c4fba37dcb298e314eca5cfb", "bytes": 179557 }, { "path": "dist/Flip.js", "localPath": "artifacts/full-import/gsap/library/dist/Flip.js", "gitBlob": "6a3aa6c954b0020706dcd9764e88e9ef739bd2c7", "sha256": "3c732c2ab4b5bcaf1b9835b1722376019b743f7641280acc342040623b248d75", "bytes": 54494 } ], "license": { "name": "GSAP Standard 'No Charge' License (custom, not MIT)", "localPath": "artifacts/full-import/gsap/licenses/gsap-standard-license.html", "sha256": "bf8536e67b77db780f7db0c14a645f184f554bb19e938d1e52d58986e2f10528", "bytes": 6988, "url": "https://gsap.com/community/standard-license/" }, "originalDependencyVersionKnown": false }, "runtimeVerified": false, "implementationWritten": false }