Character portrait
Crop-and-zoom picture editor on the Concept page, stored (re-encoded to a 256 px WebP data URL) inside the character; shown on the sheet header, in the lobby player bar and as token icon on the map. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJhXuLD2Z6hv3Wqeq9UL9K
This commit is contained in:
@@ -6,7 +6,7 @@ const clamp = (v, a, b) => Math.min(b, Math.max(a, v))
|
||||
|
||||
// Map with pan (drag the background), zoom (wheel / pinch) and draggable tokens. Coordinates are image pixels.
|
||||
// Everybody pans and zooms for themselves; token moves go out through onMove(id, x, y) which returns a promise.
|
||||
export function MapView({ map, image, tokens, onMove, selected, onSelect, grid: showGrid, tool, onClick, onHover, overlay, children }) {
|
||||
export function MapView({ map, image, portraitUrl, tokens, onMove, selected, onSelect, grid: showGrid, tool, onClick, onHover, overlay, children }) {
|
||||
const box = useRef(null)
|
||||
const [view, setView] = useState({ tx: 0, ty: 0, s: 1 })
|
||||
const [drag, setDrag] = useState(null)
|
||||
@@ -125,7 +125,7 @@ export function MapView({ map, image, tokens, onMove, selected, onSelect, grid:
|
||||
<div key={t.id} className={`maptoken ${t.kind} ${t.hidden ? 'hid' : ''} ${selected === t.id ? 'sel' : ''} ${t.can_move ? 'mov' : ''}`}
|
||||
style={{ left: x - d(t) / 2, top: y - d(t) / 2, width: d(t), height: d(t), '--tc': t.color, fontSize: Math.max(8, d(t) * 0.45) }}
|
||||
onPointerDown={(e) => startToken(e, t)} title={t.name + (t.hidden ? ' (hidden from players)' : '')}>
|
||||
<span>{(t.name || '?').trim().slice(0, 2)}</span>
|
||||
{portraitUrl?.(t) ? <img className="tokpic" src={portraitUrl(t)} alt="" draggable={false} /> : <span>{(t.name || '?').trim().slice(0, 2)}</span>}
|
||||
<em style={{ fontSize: Math.max(9, map.grid * 0.28) }}>{t.name}</em>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user