MOTION PALETTE
← すべてのデモ

Drift Canvas

InteractionJS / Canvas / AI Imagery

フルスクリーンで開く ↗

枠の中でスクロール・クリックして動きを試せます。端末指定は実寸表示です。幅が足りない場合は横にスクロールできます。

再現プロンプト

架空のトラベルジャーナル「DRIFTLINE」— 全方向にドラッグして探索する無限ループの生成地図をヒーローに据え、12枚の作品ピンには6枚のAI生成トラベル写真をフィールドノートに貼った質感で表示、経緯度と地図の語彙で全セクションを統一した1ページサイト。 配色・構成・動きの数値をまとめた指示書です。 お使いのAIに貼り、素材やお店の情報を伝えて実装してください。仕上がりは利用するAIと素材によって変わります。

Build a single self-contained HTML file (inline CSS/JS, CDN allowed only for GSAP + ScrollTrigger) for "DRIFTLINE" — a fictional travel/field-journal brand whose hero is an infinite, drag-pannable, procedurally generated map. Every later section keeps speaking the same vocabulary: coordinates, bearings, routes, waypoints. The terrain and minimap are generated in code (canvas 2D); the only bitmaps on the page are 12 locally-hosted, AI-generated travel photographs — 6 inside the hero's draggable pins and 6 as the Field Notes card thumbnails (see "## Imagery") — no stock photography, no runtime fetches, no CDN images.

## Art direction
Background ink: #0B0D10 (deeper canvas layer #06070A). Foreground/parchment text: #F1E8D6. Accent (gold): #FFC14D. Secondary sage used only inside generated terrain art: #6FB39A. Card surfaces: #13161A with a 1px rgba(241,232,214,0.10-0.14) border. Two-typeface system: a serif (Newsreader, weights 400/500/600, italic available) for every heading and for the pull-quotes, and a monospace (Space Mono, weights 400/700) for all UI chrome — nav, coordinate readouts, labels, buttons, badges. Radii: 10-14px on cards, 9999px pills on buttons/badges/nav chips. Letter-spacing on eyebrows/labels: 0.06em-0.18em. No numbered "01/02/03" list, counting-up statistic, marquee/ticker or magnetic-cursor button anywhere — the map/pin/route language does all the signalling instead.

## Imagery
AI-generate these 6 original 4:3 landscape photographs (or substitute similar original artwork) — photographic/painterly travel-photography style, natural light, NO text, logos, watermarks or signatures anywhere in the frame:
1. "Layered mountain ridges at sunrise from a rocky overlook, fog pooling in forested valleys, warm gold sky, wind-bent pines and lichened boulders in the foreground, painterly realistic landscape"
2. "Grassy sea cliff with a white lighthouse and cottage on the headland, waves breaking on dark rocks below, a hazy gold sun low over the ocean, painterly realistic landscape"
3. "Warm sand dune field at late afternoon, wind-rippled ridges casting long shadows, sparse desert scrub, hazy mountains on the horizon, clear pale-blue sky, painterly realistic landscape"
4. "Sunlit forest creek between moss-covered boulders, old-growth conifers and ferns lining the banks, dappled green light through the canopy, clear water over smooth stones, painterly realistic landscape"
5. "Snow-covered mountain valley at night under a glowing green aurora arc and starfield, a small warmly-lit tent glowing in the foreground, dark jagged peaks framing the scene, painterly realistic landscape"
6. "Terraced rice paddies down a hillside at sunset, still water mirroring an orange-pink sky, misty mountains beyond, a small thatched hut among the terraces, painterly realistic landscape"
Save locally as WebP, 4:3, ≤130KB each, reference with a plain `<img>` (never fetched at runtime). Number the files 1-6 in the order above.

Then AI-generate 6 more 16:10 landscape photographs for the Field Notes thumbnails — same painterly-realistic travel-photography style, natural light, muted earthy palette on a dark-leaning exposure so they sit into the ink background, same "one photographer, one journal" tone as the 6 above, NO text/logos/watermarks/people-as-subject:
n1. "Black volcanic tide pools filled with glacial meltwater at the edge of ice, low golden light reflecting off the still water, painterly realistic landscape" (matches photo 4's water tone)
n2. "Valley between wind-rippled sand dunes with long late shadows, distant dunes fading into haze, painterly realistic landscape" (reads as another frame of photo 3)
n3. "A chain of bridges over a river in dense fog, the farthest spans dissolving into blue-grey blue-hour mist, painterly realistic landscape"
n4. "Pre-dawn harbor with a cluster of moored fishing boats on calm water, a distant breakwater light, painterly realistic landscape" (matches photo 2's sea tone)
n5. "Steep terraced ridgeline and mountain path rising like contour lines made solid, a sea of clouds below, painterly realistic landscape" (matches photo 1's mountain tone)
n6. "Aerial view of a river delta branching into many channels at dusk, mirror-still waterways between low dark islands, painterly realistic landscape" (matches photo 6's sky tone)
Save as WebP, 16:10, served at 480x300 (2x the 240x150 slot), ≤35KB each, named note-1..note-6 in the order above.

## Section 1: Hero — "The Atlas"
Full-bleed, full-viewport-height hero. A single <canvas> renders a seamless, infinitely tileable map: build one 960x960px offscreen "world tile" once at load using a hand-rolled periodic noise field — four sine terms summed with integer wave-counts over the 960px period (frequency pairs (2,1), (3,4), (5,2), (1,5) with amplitudes 0.46/0.26/0.16/0.12) so the field is exactly periodic on both axes and therefore tiles with zero seam. Sample it on a 6px grid (160x160 samples): values below -0.32 get a translucent blue "submerged lowland" fill (rgba(24,44,60, 0.22 to 0.52)); values above 0.08 get a hypsometric tint that shifts from sage (rgb 111,179,154) to gold (rgb 255,193,77) as elevation rises past 72% of the band. A second, phase-shifted sample of the same noise marks sparse "route waypoint" dots (rendered wherever the value exceeds 0.86) in accent gold at 55% opacity. On top, draw a latitude/longitude graticule every 80px, with every 4th line (320px) drawn brighter (10% vs 4.5% white alpha) and the minor lines dashed [2,7].

Camera state is a single {x, y} float pair (world-space, unbounded) plus a velocity {vx, vy}. Pointer-drag pans the camera 1:1 (camera -= pointer delta) using setPointerCapture so the drag continues even if the cursor leaves the hero bounds; releasing the pointer lets velocity continue and decay by a friction factor of 0.90 per 60fps-normalised frame (velocity *= 0.90^(dt*60)), snapping to zero under 0.4px/s. While at rest (not dragging), a slow constant "current" of vx=3.2px/s, vy=-1.4px/s is added every frame so the map is never fully still. Every frame the camera position is wrapped modulo 960 and the background is redrawn by tiling the single world-tile canvas across the viewport from one tile before the wrapped origin (6-12 drawImage calls) — there is no boundary, only the same tile recurring.

Twelve pin-cards (title + lat/long tag) sit on a deterministic 4x3 jittered grid across the same 960px tile (jitter 55% of cell size, seeded RNG for a stable layout). Every frame each pin's screen position is its world coordinate minus the wrapped camera offset, folded into the nearest -480..+480px range (pins reappear at the opposite edge exactly like the terrain, the same infinite-loop rule applied to DOM elements). Each pin also gets a live "drag tilt": rotation = clamp(-cameraVelocityX*0.02, -12deg, 12deg), smoothed 15%/frame toward target, scaled by a per-pin weight (0.7-1.3) so the flock leans into a fast drag at slightly different intensities, easing flat when the drag stops. Off-screen culling uses a 140px horizontal / 150px vertical margin around the viewport so the taller photo pins never pop visibly at the edge.

Each pin (148px wide) is dressed as a photo taped into a field journal: a 44x15px "washi tape" strip (hsla(pinHue,70%,62%,0.55) fill, 1px hsla(pinHue,75%,78%,0.45) border, rotated -3deg) overlaps the top edge; below it a 4:3 photo panel (3px #F1E8D6 mount border, 4px radius, shadow 0 10px 18px -10px rgba(0,0,0,0.65) plus a 1px hue-tinted ring) shows one Imagery photo at object-fit: cover, then the serif title and gold monospace lat/long tag. The 12 pins cycle 6 accent hues twice (each hue = one core location revisited); assign one photo per hue so a revisit repeats its print: 40->photo4, 152->photo3, 198->photo5, 16->photo2, 92->photo1, 340->photo6.

A 104x104px minimap sits bottom-right: the scaled-down world tile plus a dot per pin, with a live gold viewport rectangle (position = wrapped-camera-fraction*104, size = viewport-size/960*104) drawn at all 3x3 wrapped offsets so it never "pops" at the seam. Top-left, a monospace "YOU ARE HERE" HUD prints a fabricated coordinate each frame from the wrapped camera fraction (lat = -58+fraction*116, lon = -179+fraction*358, 4 decimals, N/S/E/W) — mirrored in the sticky top nav so it keeps updating through the whole scroll, not just the hero. A small centred crosshair reticle and a bottom "DRAG TO DRIFT" hint (which dims to 35% opacity after the first pointerdown) complete the hero chrome. Hero copy: eyebrow "FIELD JOURNAL — VOL. II", H1 "The map runs on drift, not destinations.", italic serif subhead, and a "Begin Drifting ↓" pill button that smooth-scrolls to Field Notes. On load, a one-off (non-scroll-triggered) GSAP timeline reveals the eyebrow and H1 with a left-to-right clip-path wipe (inset 0% 100% 0% 0% -> 0%, 0.7s/0.9s, power3.out, 0.45s overlap), the subhead and CTA with a bottom-to-top clip-path wipe (inset 100% 0% 0% 0% -> 0%, 0.7s/0.6s), then fades the 12 pins in via opacity only (0.5s, 4% stagger) — position/rotation of the pins is never touched by this timeline, since that is owned exclusively by the per-frame camera loop.

## Section 2: Field Notes
Eyebrow "COORDINATES LOGGED", H2 "Field Notes". A responsive grid (auto-fit, min 260px) of 6 cards, one per journal entry (Reykjavík tide pools, Liwa dunes, Kyoto fog, Barcelona harbour, Andes contour lines, Mekong delta). Each card's artwork is a 240x150 (16:10) photo panel showing the matching Imagery thumbnail (card 1 -> note-1 tide pools, card 2 -> note-2 dunes, card 3 -> note-3 fog bridges, card 4 -> note-4 harbor, card 5 -> note-5 altitude, card 6 -> note-6 delta) as a plain `<img loading="lazy" decoding="async">` at object-fit: cover, 8px radius, with a subtle saturate(0.95) contrast(1.02) filter so the prints sit in the same journal as the hero pins. Below the art: a gold monospace coordinate tag, a 1px underline that draws in, a serif title and a short excerpt line.

## Section 3: Field Method
Eyebrow "FIELD METHOD", H2 "How a Coordinate Becomes a Note". Three columns labelled with compass bearings instead of numbers — "N · DEPART", "— · DRIFT", "S · ARRIVE" — each with one sentence of process copy. A thin dashed horizontal "route" track connects them with a solid gold fill and three waypoint dots that land in sequence as the section is scrubbed.

## Section 4: Dispatches
Eyebrow "DISPATCHES", H2 "Notes From the Field". Three postcard-style quote cards, each with a "POSTMARKED {coordinate}" stamp pill, an italic serif quote and a citation. Cards enter with a "postmark stamp" rotate-in (from ±10deg to their small final seeded rotation, scale 0.92->1, opacity 0->1) and independently parallax ±22px horizontally while the section scrolls past, as if sliding along a route.

## Section 5: Footer — "Chart Your Course"
The same 960px world tile is drawn twice side-by-side into a 1920x960 canvas filling the footer at 40% opacity behind a vignette, panned via a CSS keyframe (translateX 0 -> -50%, 70s linear infinite — exactly one tile width, reusing the hero's texture). Eyebrow "CHART YOUR COURSE", H2 "The Map Has No Last Page", a subhead, a pin-drop marker (SVG map-pin icon dropping in from y:-46 opacity:0 scale:0.6 to rest with a back.out(1.7) ease, 0.9s), a "Plot Your Journal →" CTA pill, and a "bearings" list (ARCHIVE / DISPATCHES / FIELD KIT / CONTACT), each row printing a fabricated coordinate instead of a plain link, revealed with the same left-to-right clip-path wipe used everywhere else, staggered 0.08s.

## Scroll animations
The whole page runs on native window scroll; a fixed sticky top nav (wordmark, section links, live coordinate readout) tracks a slim dashed "route" progress line filling left-to-right, scrub 0.3, across the full document height. Every entrance across every section (Field Notes cards, section eyebrows/headings, footer bearings) uses the same signature "plot-line" reveal: a left-to-right clip-path wipe, 0.7-0.9s, power3.out, never a plain translateY+opacity fade. Field Notes cards additionally wipe bottom-to-top (inset 0% 0% 100% 0% -> 0%, 0.9s power3.out, 12% stagger) with their underline drawing in 0.15s later (scaleX 0->1, 0.6s power2.out). The Field Method route uses a single ScrollTrigger with scrub 0.6 between "top 82%" and "top 30%" driving both the fill's scaleX and each dot's scale (activation window: 0.12 of scroll progress per dot). Use gsap.context()/ctx.revert() for cleanup and prefers-reduced-motion to disable the camera's inertia, auto-drift and tilt (drag itself still works, snapping 1:1) and to replace every scroll reveal with an instant, fully-visible state.

## Performance & accessibility
Clamp devicePixelRatio to 2. The world tile paints once (25,600 fills); the loop only redraws the hero canvas, the 104px minimap and 12 DOM transforms per frame, plus O(1) HUD text updates — comfortably inside a 60fps budget on integrated GPUs. All 12 photographs (6 hero prints + 6 note thumbnails) load with `loading="lazy" decoding="async"`; since exactly 2 pins share each hue, the browser fetches each hero file once no matter how the 12 pins tile. Respect prefers-reduced-motion as described above. All interactive elements (nav buttons, CTAs, the drag surface) are real <button>/<div role usage> with visible focus and sufficient colour contrast against the ink background. No external fetches, fonts self-hosted via the standard Google Fonts <link> tags, no autoplaying audio.

## Action flow and content

Implement the following local planning experience for the primary CTA, in the visual language of the page. Use a real button opening a labelled modal dialog. Choosing a pricing card must preselect that exact plan. A navigation link may move to another section; a planning CTA must lead to its review flow.

Use this content for the dialog, including the option details and notes:

{
  "slug": "drift-canvas",
  "brand": "DRIFTLINE FIELD JOURNAL",
  "accent": "#72623a",
  "title": "Plot your next field journal",
  "intro": "Begin with a question, choose how you will observe it, and keep a working note.",
  "facts": [
    [
      "Method",
      "Repeat observations and keep the conditions beside them."
    ],
    [
      "Output",
      "An illustrated field journal with source and date notes."
    ],
    [
      "Archive",
      "The map and its places form a fictional editorial collection."
    ]
  ],
  "groups": [
    {
      "label": "Observation",
      "options": [
        {
          "title": "A place over time",
          "detail": "Return to one place and record how it changes."
        },
        {
          "title": "A route through a place",
          "detail": "Build a sequence of observations from a route."
        }
      ]
    }
  ],
  "brief": "Describe a place or route, and what you would like to notice about it.",
  "notes": [
    "This is a writing plan, not a navigation route or travel booking."
  ]
}

- Explain before input that this is a fictional brand sample: choices can be reviewed and saved, with no external submission, booking, payment or registration. Use each brand's language. Do not launch a mail client or present an installer for a fictional product.
- Give every option group a legend, inputs explicit labels and errors linked descriptions. Validate options against the allowed values, requested dates as actual dates from today onward, and free text as 10–2,000 trimmed characters. Blank spaces alone must fail. Tracking accepts the sample reference TG-2048 only.
- Focus the first invalid field and preserve every entered value. On success, show the selected option WITH its full detail, requested date or brief, relevant facts and notes. An edit action returns to the preserved form. Do not claim a real reservation, purchase or account has succeeded.
- Save the complete review as UTF-8 text. A browser download request is not proof of a file being written. On download failure, retain the full text in a labelled, selectable textarea and offer retry. Do not show a false success state.
- Constrain modal content to the viewport with internal scrolling. Support keyboard and touch, trap focus while open, close on Escape and restore focus to the exact initiating control. Keep these operations available with motion disabled.
- If a separate project-contact CTA is present, let it collect a project brief and review it locally; a product selection CTA must retain the product choice. Verify both flows independently.