feat: Avatar Position-Offset (translate X/Y)

Backend:
- AgentRecord + SessionRecord: AvatarOffsetX, AvatarOffsetY Properties
- DB-Migration: avatar_offset_x/y REAL DEFAULT 0 auf agents + sessions
- Agent/Session Endpoints: Create + Update lesen/schreiben Offset-Felder
- GetSessionsWithStats: Offset-Felder ans Frontend

Frontend:
- Avatar-Editor: X/Y Offset-Slider (-50% bis +50%) im Modal
  - buildTransformStyle() Helper für transform: scale() translate()
  - getOffsetX()/getOffsetY() Public API
  - Reset bei Clear/AI-Generate/Upload
- ui.js: buildAgentCard + buildSessionCard rendern transform mit Offset
- Agent-Page + Session-Page: initialOffsetX/Y + Save
- CSS: .av-offset-row Styles (gruppiert mit .av-scale-row)
This commit is contained in:
Meleki committed 2026-03-06 21:14:51 +01:00
1 parent 95b3683910
commit 4775b8ded7
10 files changed
+143 -30

No files matched your search

+10 -4
View File
@@ -7,8 +7,11 @@ function buildSessionCard(session, agent) {
const card = document.createElement('div');
card.className = 'card';
const scaleStyle = session.avatarScale && session.avatarScale !== 1 ? ` style="scale: ${session.avatarScale}"` : '';
const imageHtml = session.image ? `<img src="${session.image}" alt=""${scaleStyle}>` : '';
const transformParts = [];
if (session.avatarScale && session.avatarScale !== 1) transformParts.push(`scale(${session.avatarScale})`);
if (session.avatarOffsetX || session.avatarOffsetY) transformParts.push(`translate(${session.avatarOffsetX || 0}%, ${session.avatarOffsetY || 0}%)`);
const transformStyle = transformParts.length ? ` style="transform: ${transformParts.join(' ')}"` : '';
const imageHtml = session.image ? `<img src="${session.image}" alt=""${transformStyle}>` : '';
// Badges
const badges = [];
@@ -47,8 +50,11 @@ function buildAgentCard(agent, skills) {
const card = document.createElement('div');
card.className = 'card';
const scaleStyle = agent.avatarScale && agent.avatarScale !== 1 ? ` style="transform: scale(${agent.avatarScale})"` : '';
const imageHtml = agent.avatar ? `<img src="${agent.avatar}" alt=""${scaleStyle}>` : '';
const agentTransformParts = [];
if (agent.avatarScale && agent.avatarScale !== 1) agentTransformParts.push(`scale(${agent.avatarScale})`);
if (agent.avatarOffsetX || agent.avatarOffsetY) agentTransformParts.push(`translate(${agent.avatarOffsetX || 0}%, ${agent.avatarOffsetY || 0}%)`);
const agentTransformStyle = agentTransformParts.length ? ` style="transform: ${agentTransformParts.join(' ')}"` : '';
const imageHtml = agent.avatar ? `<img src="${agent.avatar}" alt=""${agentTransformStyle}>` : '';
// Badges
const badges = [];