Pins and comments

Pins let you, or an AI agent, point at elements or regions of the live output and attach plain-text comments. A pin remembers what it points at, can follow it as the output changes, and can carry a cropped image. Pins are stored as files in the folder that you share with Agent πŸ“‚ Shareβ„’, so an agent reads them there, and an agent can add and change pins with code. Comments carry notes in both directions: from you to the agent, and from the agent to you.

Concepts

Element pin

A pin that comes from a live output element, by a click, or from code with add, addAll or setElement. Its kind is element.

Region pin

A pin that comes from a dragged rectangle, or from code with addRect or setRect. Its kind is rect and its label is Rect.

Linked and detached

An element pin is linked by default (linked: true): it finds its live element again and follows it, and its geometry is always tracked. A detached pin (linked: false) keeps the element's metadata but behaves like a region pin. Only element pins have linked.

Auto-track

autoTrack, true by default, controls geometry tracking for region and detached pins. A tracked pin stays attached to the same spot of the scrolled output document: it follows the output window's own scroll position, not scrolling inside nested scroll containers. An untracked pin stays fixed in the viewport. Linked element pins ignore it. The icons are πŸ›°οΈ for tracking and πŸͺ¨ for fixed.

Auto-capture

autoCapture, false by default, means refresh this pin's PNG automatically: πŸ“Έ, Automatic image refresh on. false (πŸ–ΌοΈ, Preserve existing image) keeps the current image. A forced capture, from capture() or a double-click, works either way.

Comment

Plain text. In code, values are converted with String(), and null and undefined become an empty string.

Id

pin_<time in base36>_<6 base36 characters>, for example pin_mutrqtc0_a1b2c3. It stays the same through reordering, renumbering, moves and retargeting.

All pin geometry is in output CSS pixels. A pin's rect is relative to the output viewport, and elements in nested same-origin frames are mapped into the output's coordinates. The viewport that a pin stores is a historical record: overlays and crops use the output frame's live layout size, so marks and images stay correct at any output zoom.

Pins do not add elements or attributes to the output document. The panel, the curtain, the marks and the hover boxes live in the playground document, and images with a scale or a background use temporary stylesheets that are removed afterwards. The output does receive helper scripts that add listeners and window globals. Pins are not the same as the cursor pins of Locate, which map editor cursors to output elements; they share only the word.

IconMeaning
πŸ“Έ / πŸ–ΌοΈautoCapture on, refresh the image automatically / off, keep the current image.
πŸ›°οΈ / πŸͺ¨autoTrack on, tracks the page / off, fixed in the viewport.
πŸ”— / ⛓️‍πŸ’₯linked on / off (detached).
🧬 / 🚫Mutation observation allowed / disabled.
🩻The picker's pierce depth.
βš™οΈThe image capture options.

Requirements

Starting and stopping Pins

CommandKeysAvailable whenWhat it does
✨ Agent: πŸ“ PinsCtrl+P / ⌘+PPins is closedOpens Pins and starts picking. Shares first when no folder is shared.
✨ Agent: πŸ“ Pins StopCtrl+P / ⌘+PPins is openStops and closes Pins.
✨ Agent: πŸ“ Pins + πŸ”΄ Output…Ctrl+Alt+P / ⌘+βŒ₯+PNo Output capture is activeShares with an Output capture, or adds one to a running share, and starts picking.
✨ Agent: πŸ“ Pins Pause/ResumeCtrl+Alt+Shift+P / ⌘+βŒ₯+⇧+PSharing, with Pins openPauses or resumes picking. It never opens Pins.
Stopping

Ctrl+P while Pins is open, the βœ• button, or Shift+click on the state button closes the panel. It turns picking off, removes the overlays, destroys the output bridge and cancels image work in progress. Pins stay in memory, in o.pins and on disk.

Unshare

Closes Pins, removes o.pins from the output frame element and clears the pins from memory. The πŸ“.<N>.json files stay in the work folder, unless you used Unshare with Shift (Empty) or Ctrl (Delete). Pin images, πŸ“.<N>.png, are deleted when Unshare stops a capture that the share started.

Restoring at Share

With Share ← Folder on, pins on disk win. If the folder has none, the pins in the page's memory are used. With Share ← Folder off, the pins in the page's memory are written over the folder. If there are none, which is so after a reload or an Unshare, the folder's πŸ“.<N>.json files are loaded.

Tab icon

The third character of the tab icon shows Pins: _ closed, P paused, or the pin count from 0 to 9 while picking.

Picking

While Pins is picking, a transparent curtain with a crosshair cursor covers exactly the visible output. It forwards pointer and wheel events to the bridge in the output, which hit-tests there.

Click

Pins the hovered element, the deepest one that is hit-tested through shadow roots and frames. A coral hover box, labelled with the element's selector, label or tag, follows the pointer. Only the primary button picks.

Drag

Creates a region pin when both the width and the height of the dragged box exceed 5 px. A dashed cyan box shows the region during the drag. A release with a side of 5 px or less pins the hovered element instead. Regions are clamped to the output viewport.

Shift+wheel

Walks the hover target through the element's ancestry: wheel up moves toward the ancestors, wheel down moves back toward the original element. The ancestry crosses shadow hosts and frame elements.

Wheel

A plain wheel still scrolls the output.

Esc

With focus in the output, pauses picking. The Pins panel itself does not intercept Esc.

Picker hit-testing enters open shadow roots and same-origin iframes, up to the 🩻 Picker pierce depth: -1, the default, is unlimited; 0 stays in the output document; n from 1 up crosses at most n boundaries. Closed shadow roots and cross-origin frames cannot be entered, but the iframe element itself can be pinned. The depth affects human picking only, never the selectors of agents, and it works without a capture.

A newly picked pin takes autoTrack from the header's πŸ›°οΈ/πŸͺ¨ default, autoCapture from the header's πŸ“Έ/πŸ–ΌοΈ default, and linked: true. The list scrolls to the new row and focuses its comment. With an Output capture active, an initial PNG is captured for the new pin and for any other pin that still has no image.

Pointer lock while capturing Experimental

Note: This behaviour may change.

After any screen capture starts, the playground primes the browser's pointer-lock permission once, by locking and at once unlocking the pointer. While you pick with the pointer over the output, the curtain then holds pointer lock and draws a crosshair at a virtual pointer: cyan by default, rotated by 45Β° with Shift, coral with Alt, ringed with Ctrl, and showing resize glyphs over the edges of region pins that you can edit. Esc releases the lock and pauses picking. Pushing 48 px or more past an edge of the output, or pushing hard several times, frees the cursor without pausing, and moving back over the output locks it again. With the lock held, the hint reads Click output elements or drag a rectangle. Shift+Wheel cycles ancestors. Esc pauses picking.

Marks over the output

Existing pins are drawn as marks over the output: coral for element pins, cyan for region pins. Tracked pins get a solid border. Fixed pins get a dashed border with an outline. A label at the top right holds the state buttons and the pin's index. Marks are clipped to the visible output, and they take pointer events only while you pick or while Shift or Alt is held. Otherwise clicks pass through to the output. Shift, Alt and Ctrl pressed while the output has focus are relayed to the playground, so marks react to them too.

GestureEffect
Alt+click a markDeletes that pin.
Alt+right-click a markDeletes all pins, without confirmation.
Hold ShiftEdits region marks. Drag inside a mark to move it. Drag in its edge band, 3 to 8 px depending on the size of the mark, to resize from that edge or corner. Regions stay at least 8 Γ— 8 px and inside the output viewport. On release the change is saved, and the PNG is refreshed only if the pin has autoCapture.
Alt+Shift+wheel on a markRegion pins grow (wheel up) or shrink (wheel down) by 8 px per edge, around their centre. Linked element pins move to the ancestor on wheel up (the same as β†–) and back down on wheel down (the same as β†˜).
Shift+double-click a markForces a new image for that pin.
Ctrl+Shift+double-click a markRefreshes the image of every pin.
Hold CtrlMakes the label buttons clickable: πŸ“Έ/πŸ–ΌοΈ toggles autoCapture (shown only with an Output capture), πŸ›°οΈ/πŸͺ¨ toggles autoTrack (region and detached pins only), and πŸ”—/⛓️‍πŸ’₯ toggles linked (element pins only). A right-click on a button applies its new value to all eligible pins.

The Pins panel

The panel is a non-modal dialog without a focus trap, and it follows light and dark mode. It sits at the bottom right by default, with 20 px insets, and is 340 px wide. It does not steal focus when it opens. Drag its header, outside the buttons and inputs, to move it. Eight resize handles (n, e, s, w, nw, ne, se, sw) resize it unless it is minimized. It stays 4 px inside the window, and the browser remembers its geometry. Minimized, it is 96 px wide and shows only the LED, the pin count and the restore button. The hint reads Click output elements or drag a rectangle., and an empty list reads No pins yet.

The header

The header controls, in order:

  1. The state button: an LED, the pin count (only when minimized) and PINS.
  2. Pause and resume: ⏸️ while picking (Pause picking.), 🎯 while paused (Resume picking.).
  3. 🩻, the pierce-depth number field.
  4. βš™οΈ, Pin image capture options.
  5. The default for tracking: πŸ›°οΈ/πŸͺ¨.
  6. The default for capturing: πŸ“Έ/πŸ–ΌοΈ.
  7. Mutation observation: 🧬/🚫.
  8. Minimize: β–Ύ/β–΄.
  9. βœ•, Stop and close.
The state button

A click pauses or resumes picking. Shift+click stops and closes Pins. A middle-click minimizes or restores the panel. A right-click clears all pins after the confirmation Clear all pins?, whose OK button is Clear Pins. Shift+right-click clears them without confirmation. The LED turns green when mutation observers are active and is coral otherwise, and it pulses while picking.

The default buttons

A click toggles the default for new pins that people pick. A right-click toggles it and applies it to every existing pin. The default-capture and 🧬 buttons appear only with an Output capture.

🧬 and 🚫

The tooltip says Allow mutation observation for live linked element pins. This is a switch for the whole session, and it takes effect at once. See How pin images are made.

The rows

Each pin has a row with:

  • an index chip, coral for element pins and cyan for region pins. Click it to scroll the pinned part of the output into view, smoothly;
  • the label;
  • the dimensions, the on-screen width and height at the current zoom. Double-click them to refresh the geometry;
  • the state buttons: πŸ“Έ/πŸ–ΌοΈ (only with an Output capture), πŸ›°οΈ/πŸͺ¨ (region and detached pins only) and πŸ”—/⛓️‍πŸ’₯ (element pins only). A click toggles the button for that pin, and a right-click applies the new value to all eligible pins. Untracked rows have a dashed border;
  • βœ•, which deletes the pin without confirmation. Ctrl+click or a right-click on βœ• deletes all pins, without confirmation;
  • a breadcrumb line, for element pins;
  • a thumbnail, only while an Output capture runs;
  • a comment field.
The comment field

Its placeholder is Comment. It grows with its content, and saves shortly after the last keystroke. Ctrl+Enter / ⌘+Enter adds a new pin for the same element or region, copies the comment and selects it. Ctrl+↑ and Ctrl+↓ (⌘ on macOS) jump between comment fields and wrap around.

The breadcrumb

It lists the labels from the deepest element of the pin's recorded path outward, separated by <, and highlights the pinned one. For an agent's pin, the path starts at the pinned element. For a human pick made after ancestor walking with Shift+wheel, it starts at the element that was hovered first, so that β†˜ can go below the picked ancestor. The path includes #shadow-root and #document markers, which cannot be pinned. β†– (Pin to ancestor) and β†˜ (Pin back down) step along it, and clicking a crumb moves the pin to that element. A small number shows how deep the pinned element sits below the outermost ancestor. Moving is disabled for detached pins, and when no live path is known. The mouse wheel scrolls the crumbs sideways.

The thumbnail

It is up to 96 px tall. A striped placeholder shows while an image is pending, and a shimmer while it is captured. On a failure it reads Capture failed: <message> Double-click to retry. Double-click refreshes that image. Ctrl+double-click refreshes all images. Alt+click, or Alt+double-click, scrolls the pin into view.

Image capture options

βš™οΈ opens the popover βš™οΈ Image capture, anchored to the button. It opens only while an Output capture is active, and the button is hidden otherwise. Esc closes it. The options set how pin images are made when a person picks, double-clicks or uses the panel's buttons. Agents can pass the same options per call, and can inherit them; see Enforce as agent pin defaults.

Option in the panelName in codeValuesDefault
πŸ” ScalescaleA number greater than 0.1
🎯 Originoriginauto, or a CSS transform-origin value. The panel offers a preset grid: Auto, the center, and the 8 edges and corners. Hidden while the scale is 1.auto
🎨 Background colorbackgroundtransparent, or an absolute sRGB color. Hidden unless Custom background is on.transparent
🧩 Background methodbackgroundModeelement or backdrop. Hidden unless Custom background is on.backdrop
⏱️ Settle · mssettle0 to 2000.160
⬆️ LiftliftA checkbox: true or false.true
βœ‚οΈ UnclipunclipA checkbox: true or false.true
πŸ–ŒοΈ Custom background-A checkbox. See below.Automatic
πŸ€– Enforce as agent pin defaultsenforceAgentDefaultsA checkbox.On

The footnote of the popover reads Scale and backgrounds apply to linked elements. Rectangle and detached pins keep their original crop. The settings, the header defaults and the 🩻 depth belong to the page, and survive Pins Stop and Unshare. They reset when the page reloads, and changing a setting does not recapture existing images.

Scale

Temporarily applies transform: translate(…) scale(…) to the element, composed with any transform it has. Transitions are switched off, and inline elements become inline-block. The applied scale is the smallest of the requested scale, (visible output width βˆ’ 16 px) / element width and (visible output height βˆ’ 16 px) / element height, and enclosing iframes limit it as well. With origin: 'auto' the element is scaled about its centre and shifted to fit inside the visible output with 8 px margins. An explicit origin is used as the CSS transform-origin.

Lift

Temporarily sets position: relative, only if the element is static, and z-index: 2147483647. Like the transition and inline-block changes, it applies only to scaled captures. A background-only capture at scale 1 is not lifted. It is also skipped for Backdrop captures of inner SVG graphics.

Unclip

Applies only to scaled captures. Before scaling, ancestors with idle auto or overlay overflow get overflow: visible. After scaling, ancestors that would clip the enlarged box (overflow: hidden or clip, or contain: paint, strict or content) are unclipped. Real scrollers are left alone and recorded in clippedBy. If unclipping moves anything, the capture fails with Unclipping an idle overflow container changed the pin layout or scroll position.

Settle

An optional delay, in milliseconds, that starts after two animation frames. It applies only to the enhanced path: scaled or background captures. settle: 0 removes only the delay. The freshness and restoration checks still run.

Background

transparent, or an absolute sRGB color: #rgb, #rgba, #rrggbb, #rrggbbaa, rgb(), rgba() or color(srgb …). The value is trimmed and lowercased, and 3- or 4-digit hex is expanded, so '#fff' becomes '#ffffff'. Other forms are re-serialized by the browser, for example 'rgb(255, 255, 255)'. Named colors, hsl() and oklch() are rejected.

Custom background

It is checked automatically when the scale is not 1, and unchecked at 1, until you toggle it. Your choice then sticks regardless of the scale, until you reset it. Its color is white in a light output and black in a dark output, following the output's resolved color-scheme, including ocs, until you pick a color. A color you picked is remembered, even while the checkbox is unchecked, until you reset it.

Background method

Backdrop, the default, places the color behind the target. It hides the surrounding paint: sibling branches get opacity 0, the paint and pseudo-elements of ancestors are hidden, iframe chrome becomes transparent, unrelated open popovers and modals are hidden, and the top document root is painted with the color. This works for masked icons and inner SVG shapes. Element sets the target's own background-color and keeps its background images.

Wheel over a field or its label

Scale changes by Β±1 above 1 (wheel up at 1 goes to 2), and by Β±0.1 below 1 (wheel down at 1 goes to 0.9). Settle changes by Β±10 ms, and 🩻 depth by Β±1, with a minimum of βˆ’1. Origin cycles the presets; a custom value stays unchanged unless Alt is held, and Alt+wheel enters the presets at auto. Selects cycle, checkboxes toggle and the color stays. Ctrl/⌘+wheel is ignored, because the browser uses it to zoom.

Reset

Every field has a reset button β†Ί, which is disabled while the field is at its default. A right-click on a field's row resets that field, and a right-click on any β†Ί resets every pin setting. Resetting Enforce turns it on again, resetting 🩻 restores βˆ’1, resetting Custom background restores the automatic behaviour that follows the scale, and resetting the color forgets the chosen color.

Enforce as agent pin defaults

It starts checked. When it is checked, agent calls inherit any capture option that they omit from the βš™οΈ settings, including the automatic Custom background that follows the call's effective scale. When it is unchecked, omitted options use the built-in defaults, so the background stays transparent even for scaled captures. Options that a call passes explicitly always win and never change the settings.

How pin images are made

Two paths

The direct crop path handles region pins, detached pins, and linked element pins at scale 1 with a transparent background. It crops one fresh frame of the Output capture stream, with no temporary styles and no settle delay. The enhanced path handles linked element pins with a scale other than 1 or a non-transparent background. It temporarily restyles the element, waits for a frame that was captured after that paint, crops it, restores the element, and waits again until the restored paint has reached the stream. A batch with both kinds uses both paths.

The crop

Crops use the output frame's live viewport, so they match at any output zoom, and they cover every bitmap pixel that the pin touches, snapped to whole pixels. When part of the pin lies outside the visible output, the crop is first filled with a hatched placeholder, with the text outside viewport in the middle when the crop is larger than 96 Γ— 36 px, and the visible part is drawn over it. Crops of more than 2,000,000 pixels are scaled down proportionally. Otherwise the PNG's pixels are the capture stream's pixels, whose density relative to CSS pixels depends on the browser and the device pixel ratio.

Freshness

A direct-path crop waits for a newly delivered video frame, and fails after 2 seconds with Timed out waiting for a fresh capture frame. An enhanced capture waits, also up to 2 seconds, for a frame that is newer than the temporary paint, and fails with Capture frame timestamps are unavailable. when the browser gives no timestamps.

One lane

Image work runs one request at a time in a single lane per page. Full-output screenshots, πŸ“Έ.png and Image…, queue in the same lane, so they never show a temporarily enlarged element. They refuse to run while a restoration is unconfirmed (Pin image restoration has not been confirmed.).

Failures

A failed capture keeps the pin's previous PNG. If the pin has no PNG yet, the error text is stored and written as captureError in its JSON file, and a later success clears it. The panel's thumbnail shows the error. Explicit calls from code reject with the first error, after they have processed every requested pin.

Cancelling

A capture in progress is cancelled by source edits and by changes of the output viewport or zoom; by clearing or closing Pins, output reloads and target changes; by your input in the output (pointer, click, key, wheel, a real scroll, resize, page hide and unload) and by picking input; and by pointer, click or wheel input for Locate. A presentation that never settles is cancelled by a watchdog after the longer of 10 seconds and the settle delay plus 10 seconds.

Automatic refresh

The images of autoCapture pins refresh after the πŸ“Έ.png refresh that follows a source edit (linked element pins only when mutation observation is on); after DOM mutations; after changes of the output's zoom, viewport or color scheme (ocs), after 80 ms and two frames; after region edits, for the edited pin only; when an Output capture is retargeted after a layout swap or an orientation change; and after a save of the pins that is not about specific pins, which can re-crop all autoCapture pins. Such saves can follow tracked geometry, scroll, layout or zoom changes, comment edits, button toggles, a right-click that applies a default to all pins, and deletions. Starting an Output capture refreshes every pin's image.

Mutation observation

It needs all of these: an Output capture, 🧬 on (the default), and linked element pins with autoCapture: true. The output then observes the document, and the shadow roots on the path of each eligible element, for child, attribute and text changes. Any mutation in those roots queues a refresh for all eligible pins, not only the changed one.

Capture start and stop

When an Output capture starts, all pin images are captured again. When it ends while a folder is shared, all πŸ“.<N>.png files are deleted and the JSON files are rewritten without image references.

Pin files

Each pin is written as πŸ“.<N>.json, and as πŸ“.<N>.png when it has an image. The numbers start at 0 and follow the live pin order. Every save rewrites all the files, so deleting pin 0 renumbers the rest. The writes are quiet, with no toasts, and the playground ignores edits to the files while it runs: it reads them only when a share starts. To change pins, use o.pins. Agent files describes the envelope, every field of the pin, and the metadata of images.

Pin files copy what the output shows into the work folder: the element's text and its full source, its computed styles, the CSS rules that match it, and the output's URL and title. Agents that read the files can read all of it.

Pins from code

An agent drives pins through o.pins from io.eval.js. It is installed on the output frame element in the editor window, at startup and again on every share, and Unshare removes it. Write one request, wait for and read io.eval.json, and only then write the next; top-level await and an implicit final-expression return work as described in File evals. The methods and options are documented in PinList. The shared skill, .agents/skills/pin-use/SKILL.md and .claude/skills/pin-use/SKILL.md, teaches the same to the agent.

A page to pin

This output document has an element pin target, a list for addAll and an open shadow root for piercing:

html
<style>
  :root    { color-scheme: light dark; }
  main     { display: grid; gap: 1rem; padding: 1rem; }
  #badge   { justify-self: start; padding: .25rem .6rem; border-radius: 1rem; background: oklch(.75 .15 150); }
  x-card   { display: block; }
</style>
<main>
  <h1>Pins demo</h1>
  <span id=badge>new</span>
  <ul id=list><li>One<li>Two<li>Three</ul>
  <x-card></x-card>
</main>
<script>
  customElements.define('x-card', class extends HTMLElement {
    connectedCallback() { this.shadowRoot ?? this.attachShadow({ mode: 'open' }).append(Object.assign(document.createElement('button'), { id: 'inner', textContent: 'Buy' })) }
  })
</script>

The root color-scheme matters: the automatic Custom background reads the output root's resolved color-scheme, so a page that never declares it gets a white background, even in dark mode.

To pin by hand, press Ctrl+Alt+P / ⌘+βŒ₯+P (Pins + Output). If no folder is shared yet, pick the root folder first. Choose this tab in the browser's capture dialog, click the badge, then type a comment in the Pins panel.

Examples for io.eval.js

Send each snippet as its own request, in order. They use the page above.

Add an element pin, and return only what you need. The comment is converted to a string, and the call resolves to the aggregate payload:

js
const { pins } = await o.pins.add('#badge', { comment: 'Make this pill smaller' })
pins.map(({ id, label, rect, comment }) => ({ id, label, rect, comment }))

Pin every list item, and a region. o.pins is an array of handles, and index is a non-enumerable getter of each handle:

js
await o.pins.addAll('#list li', { comment: 'row' })
await o.pins.addRect({ x: 0, y: 0, width: 320, height: 80, comment: 'header area', autoTrack: false })
o.pins.map(p => `${p.index} ${p.kind} ${p.label}: ${p.comment}`)

Pierce into the open shadow root. Without pierceDepth, '#inner' is searched with document.querySelector only, and fails with Pin target not found: #inner:

js
await o.pins.add('#inner', { pierceDepth: -1, comment: 'inside x-card' })

Walk the ancestors. On the button in the shadow root, the first up() reaches the x-card host:

js
await o.pins.at(-1).up()      // button#inner β†’ x-card
await o.pins.at(-1).down(-1)  // back to the original button

Capture an enlarged image. It needs an Output capture that a person started. Pin 0 must be a linked element pin: region and detached pins keep their plain crop. Afterwards, read image.capture.appliedScale in πŸ“.0.json, which is fitted to the visible output, and open πŸ“.0.png. With Enforce as agent pin defaults checked and Custom background left automatic, the call's effective scale of 8 also turns on an automatic background: the remembered color, or else white or black from the output's theme. Pass background: 'transparent' to keep the page's own painting.

js
await o.pins.at(0).capture({ scale: 8, settle: 0 })

Set session defaults for agents. These setters are synchronous:

js
o.pins.default.scale = 3                    // UI setting; omitted agent options inherit it while Enforce is on
o.pins.default.enforceAgentDefaults = false // agents fall back to built-ins (scale 1, transparent)

Read the human's feedback without the heavy fields.

js
o.pins.toJSON().pins.map(({ id, kind, selector, label, comment, autoCapture }) => ({ id, kind, selector, label, comment, autoCapture }))

Messages

Pins and o.pins

MessageWhen
Pin API requires an active Agent Folder Share.A mutating o.pins call, pause() or resume() without a share.
Pin requires the inline output iframe.Pins starts without the inline output frame.
Pin target not found: <selector>add, addAll or setElement finds no match. Nothing is added.
Pin target not found: <target>A list method gets an unknown index or id.
Pin rectangle requires positive width and height.addRect gets a rectangle without area.
Pin target is not element-sourced: <target>setOptions sets linked and an explicit target is a region pin.
Pinned element was not found; keeping it detached.linked: true on a detached pin whose element cannot be found. The whole call rejects and nothing changes.
Pin geometry not found: <id>capture or track has an explicit target whose linked element can no longer be found.
Pin target disconnected: <id>up or down on an element that has vanished.
Output screen capture is required to update this pin image.setElement, setRect, up or down on a pin that already has a PNG, without an Output capture.
Pin update is already pending.A second update of the same pin while one is pending.

Options

  • Scale must be a positive number.
  • Settle delay must be between 0 and 2000 ms.
  • Origin must be auto or a CSS transform-origin value.
  • lift must be true or false. and unclip must be true or false. Only real booleans are accepted.
  • Background must be transparent or an absolute sRGB color.
  • Background method must be element or backdrop.
  • Element background requires an unmasked CSS background box. Choose Backdrop or a parent element. (a masked target, background-clip: text, or a target that is not a CSS box)
  • Backdrop requires an element below the document root. Choose Element background.
  • Backdrop cannot hide a focused ancestor. Move focus outside the pinned element first.
  • Pin background cannot override <property>. and Pin background changed the target geometry.

Image capture

These come from the enhanced capture path. They appear in an error thrown by a call, in the thumbnail, and as captureError in the pin's file.

Scaling and fitting

Scaled pin capture requires a current connected linked element. Pin capture requires visible positive geometry. Pinned element has no visible capture viewport. Scaled pin cannot fit the capture viewport. Pinned element cannot be scaled without changing its layout. Pinned element transform cannot be positioned for capture. Pinned element layout changed while preparing its image. Scaled pin moved outside the capture viewport.

Changes during capture

Pinned element moved during image capture. Pinned element content or styles changed during image capture. Pinned element disconnected during image capture. Pinned element structure changed during image capture. Pinned element frame navigated during image capture.

Styles

Pin image capture cannot override <property>. Required pin image styles were overridden. Pin image stylesheet was removed during capture.

Interruption and timeouts

Pin image capture interrupted by <event>. Pin image presentation timed out. Timed out waiting for pin image restoration to paint. Another pin image capture is still active.

RTCode.ai pins Coming soon

RTCode.ai is announced to ship its own Pins plugin, with the same capture options. It is not available yet. See Coming soon.

Availability

FeaturePlaygroundRTEdge.netNotes
Pins, panel and marksYesNoNeeds Agent Folder Share: Chrome or Edge on a desktop, and an inline output.
Pin imagesYesNoNeed an Output capture that a person starts. See Screen capture.
o.pinsYesNoOnly in the editor window, through io.eval.js. It does not exist in o.eval.js.

See also