This commit is contained in:
@@ -306,7 +306,9 @@ $sectionLinks = [
|
|||||||
</div>
|
</div>
|
||||||
<p class="muted small">Wähle eine Komponente und passe dein neues Profilbild Schritt für Schritt an. Gespeichert wird erst nach Klick auf den Button unten.</p>
|
<p class="muted small">Wähle eine Komponente und passe dein neues Profilbild Schritt für Schritt an. Gespeichert wird erst nach Klick auf den Button unten.</p>
|
||||||
<div class="flex gap-12" style="flex-wrap:wrap; justify-content:center;">
|
<div class="flex gap-12" style="flex-wrap:wrap; justify-content:center;">
|
||||||
<button class="btn ghost" type="button" data-avatar-reroll>Neue Grundvariante laden</button>
|
<button class="btn ghost" type="button" data-avatar-random>Random Profilbild</button>
|
||||||
|
<button class="btn ghost" type="button" data-modal-close>Abbrechen</button>
|
||||||
|
<button class="btn" type="submit">Profilbild speichern</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="avatar-component-nav" role="tablist" aria-label="Avatar-Komponenten">
|
<div class="avatar-component-nav" role="tablist" aria-label="Avatar-Komponenten">
|
||||||
<?php foreach (\App\Avatar\Lorelei::componentDefinitions() as $field => $meta): ?>
|
<?php foreach (\App\Avatar\Lorelei::componentDefinitions() as $field => $meta): ?>
|
||||||
@@ -359,19 +361,7 @@ $sectionLinks = [
|
|||||||
</section>
|
</section>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="avatar-seed-picker" data-avatar-seed-picker hidden>
|
|
||||||
<div class="avatar-seed-picker__head">
|
|
||||||
<strong>Grundvarianten wählen</strong>
|
|
||||||
<button class="btn ghost" type="button" data-avatar-seed-picker-close>Schließen</button>
|
|
||||||
</div>
|
</div>
|
||||||
<p class="muted small">Hier siehst du verschiedene Grundvarianten mit deinen aktuell gewählten Augen, Haaren, Bart- und weiteren Einstellungen. Ein Klick übernimmt die Variante oben.</p>
|
|
||||||
<div class="avatar-seed-picker__grid" data-avatar-seed-picker-grid></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex gap-12">
|
|
||||||
<button class="btn ghost" type="button" data-modal-close>Abbrechen</button>
|
|
||||||
<button class="btn" type="submit">Profilbild speichern</button>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -267,17 +267,8 @@ body {
|
|||||||
.avatar-component-card__thumb img { width: 100%; height: 100%; object-fit: cover; object-position: center center; display: block; transform: none; }
|
.avatar-component-card__thumb img { width: 100%; height: 100%; object-fit: cover; object-position: center center; display: block; transform: none; }
|
||||||
.avatar-component-card__label { font-size: 12px; font-weight: 700; color: var(--color-text); text-align: center; }
|
.avatar-component-card__label { font-size: 12px; font-weight: 700; color: var(--color-text); text-align: center; }
|
||||||
.avatar-component-card:has(input:checked) { border-color: var(--color-primary); box-shadow: 0 0 0 3px rgba(52,72,90,0.14); }
|
.avatar-component-card:has(input:checked) { border-color: var(--color-primary); box-shadow: 0 0 0 3px rgba(52,72,90,0.14); }
|
||||||
.avatar-seed-picker { width: 100%; display: grid; gap: 12px; padding: 18px; background: rgba(255,255,255,0.82); border: 1px solid var(--color-border); border-radius: 18px; }
|
@media (max-width: 980px){ .avatar-component-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
|
||||||
.avatar-seed-picker[hidden] { display: none; }
|
@media (max-width: 860px){ .avatar-component-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
|
||||||
.avatar-seed-picker__head { display: flex; justify-content: space-between; gap: 12px; align-items: center; }
|
|
||||||
.avatar-seed-picker__grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
|
|
||||||
.avatar-seed-card { display: grid; gap: 8px; padding: 10px; border: 1px solid var(--color-border); border-radius: 16px; background: #fff; cursor: pointer; }
|
|
||||||
.avatar-seed-card:hover { border-color: var(--color-primary); box-shadow: 0 0 0 3px rgba(52,72,90,0.08); }
|
|
||||||
.avatar-seed-card__thumb { display: block; aspect-ratio: 1; border-radius: 14px; overflow: hidden; background: linear-gradient(180deg, #f7efe6, #f0e4d7); border: 1px solid rgba(74, 52, 38, 0.08); }
|
|
||||||
.avatar-seed-card__thumb img { width: 100%; height: 100%; display: block; object-fit: cover; }
|
|
||||||
.avatar-seed-card__label { text-align: center; font-size: 12px; font-weight: 700; }
|
|
||||||
@media (max-width: 980px){ .avatar-component-grid, .avatar-seed-picker__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
|
|
||||||
@media (max-width: 860px){ .avatar-component-grid, .avatar-seed-picker__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
|
|
||||||
.avatar-swatch-group { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; }
|
.avatar-swatch-group { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; }
|
||||||
.avatar-swatch { display: grid; grid-template-columns: 20px 18px minmax(0, 1fr); gap: 10px; align-items: center; padding: 10px 12px; border: 1px solid var(--color-border); border-radius: 14px; background: #fff; cursor: pointer; }
|
.avatar-swatch { display: grid; grid-template-columns: 20px 18px minmax(0, 1fr); gap: 10px; align-items: center; padding: 10px 12px; border: 1px solid var(--color-border); border-radius: 14px; background: #fff; cursor: pointer; }
|
||||||
.avatar-swatch__color { width: 18px; height: 18px; border-radius: 999px; background: var(--swatch-color); border: 1px solid rgba(0,0,0,0.12); }
|
.avatar-swatch__color { width: 18px; height: 18px; border-radius: 999px; background: var(--swatch-color); border: 1px solid rgba(0,0,0,0.12); }
|
||||||
|
|||||||
@@ -826,41 +826,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
updateAvatarOptionPreviews(form, getActiveAvatarField(form));
|
updateAvatarOptionPreviews(form, getActiveAvatarField(form));
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderAvatarSeedChoices = (form, seeds) => {
|
|
||||||
const picker = form.querySelector('[data-avatar-seed-picker]');
|
|
||||||
const grid = form.querySelector('[data-avatar-seed-picker-grid]');
|
|
||||||
if (!picker || !grid) return;
|
|
||||||
|
|
||||||
grid.innerHTML = '';
|
|
||||||
seeds.forEach((seed, index) => {
|
|
||||||
const params = buildAvatarParams(form, { avatar_preset: seed });
|
|
||||||
if (!params) return;
|
|
||||||
|
|
||||||
const card = document.createElement('button');
|
|
||||||
card.type = 'button';
|
|
||||||
card.className = 'avatar-seed-card';
|
|
||||||
card.setAttribute('data-avatar-seed-option', seed);
|
|
||||||
card.innerHTML = `
|
|
||||||
<span class="avatar-seed-card__thumb">
|
|
||||||
<img src="${avatarEndpoint}?${params.toString()}" alt="Grundvariante ${index + 1}">
|
|
||||||
</span>
|
|
||||||
<span class="avatar-seed-card__label">Variante ${index + 1}</span>
|
|
||||||
`;
|
|
||||||
card.addEventListener('click', () => {
|
|
||||||
const seedField = form.querySelector('[data-avatar-field="avatar_preset"]');
|
|
||||||
if (!(seedField instanceof HTMLInputElement)) return;
|
|
||||||
seedField.value = seed;
|
|
||||||
picker.hidden = true;
|
|
||||||
ensureAvatarBuilderLoaded(form);
|
|
||||||
updateAvatarPreview(form);
|
|
||||||
updateAvatarOptionPreviews(form, getActiveAvatarField(form));
|
|
||||||
});
|
|
||||||
grid.appendChild(card);
|
|
||||||
});
|
|
||||||
|
|
||||||
picker.hidden = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
document.querySelectorAll('[data-avatar-builder]').forEach((form) => {
|
document.querySelectorAll('[data-avatar-builder]').forEach((form) => {
|
||||||
form.querySelectorAll('[data-avatar-field]').forEach((field) => {
|
form.querySelectorAll('[data-avatar-field]').forEach((field) => {
|
||||||
field.addEventListener('change', () => {
|
field.addEventListener('change', () => {
|
||||||
@@ -925,23 +890,22 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
return slugifySeed(`${prefix}-${suffix}-${tail}`);
|
return slugifySeed(`${prefix}-${suffix}-${tail}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
form.querySelector('[data-avatar-reroll]')?.addEventListener('click', () => {
|
form.querySelector('[data-avatar-random]')?.addEventListener('click', () => {
|
||||||
const seedField = form.querySelector('[data-avatar-field="avatar_preset"]');
|
const seedField = form.querySelector('[data-avatar-field="avatar_preset"]');
|
||||||
if (!(seedField instanceof HTMLInputElement)) return;
|
if (!(seedField instanceof HTMLInputElement)) return;
|
||||||
const currentSeed = readAvatarValue(form, 'avatar_preset');
|
seedField.value = buildSeed();
|
||||||
const seeds = [];
|
|
||||||
while (seeds.length < 8) {
|
|
||||||
const candidate = buildSeed();
|
|
||||||
if (candidate === currentSeed || seeds.includes(candidate)) continue;
|
|
||||||
seeds.push(candidate);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderAvatarSeedChoices(form, seeds);
|
avatarComponentFields.forEach((field) => {
|
||||||
|
const options = Array.from(form.querySelectorAll(`[data-avatar-field="${field}"]`));
|
||||||
|
if (!options.length) return;
|
||||||
|
const randomOption = options[Math.floor(Math.random() * options.length)];
|
||||||
|
if (!(randomOption instanceof HTMLInputElement)) return;
|
||||||
|
randomOption.checked = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
form.querySelector('[data-avatar-seed-picker-close]')?.addEventListener('click', () => {
|
ensureAvatarBuilderLoaded(form);
|
||||||
const picker = form.querySelector('[data-avatar-seed-picker]');
|
updateAvatarPreview(form);
|
||||||
if (picker) picker.hidden = true;
|
updateAvatarOptionPreviews(form, getActiveAvatarField(form));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user