Add digital badge tab for round-display photo prep
Adds a new "Цифровой бейдж" tab for preparing 240×240 PNG circles for round digital displays. Photos come from device upload or the existing Flickr selection. Each photo can be drag-cropped and zoomed (mouse, wheel, or pinch on touch), have a yellow price tag (arc band or rectangular plate, with auto thousands separator and ₽), and a curved nickname signature — which auto-moves to the top of the circle when a price tag occupies the bottom. Saves are routed through the Web Share API on phones so the badge lands in the iOS/Android Photos app directly; history of saved badges is kept under data/badges/. Default nickname is stored in Settings. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -81,6 +81,7 @@ if (isset($_GET['logout'])) {
|
||||
<nav class="main-nav">
|
||||
<button class="nav-btn" data-tab="gallery">Галерея</button>
|
||||
<button class="nav-btn active" data-tab="posting">Публикация</button>
|
||||
<button class="nav-btn" data-tab="badge">Цифровой бейдж</button>
|
||||
<button class="nav-btn" data-tab="converter">Конвертер</button>
|
||||
<button class="nav-btn" data-tab="widget">Виджет</button>
|
||||
<button class="nav-btn" data-tab="settings">Настройки</button>
|
||||
@@ -561,6 +562,143 @@ https://live.staticflickr.com/65535/12345678901_abcdef1234_b.jpg"></textarea>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Tab: Digital Badge (round display) -->
|
||||
<section id="tab-badge" class="tab-content">
|
||||
<div class="panel">
|
||||
<h2>Цифровой бейдж</h2>
|
||||
<p class="help-text">Подготовьте фотографии под круглые дисплеи 240×240 пикселей. Кадрируйте, добавьте ценник или подпись никнеймом дугой снизу.</p>
|
||||
|
||||
<!-- Photo sources -->
|
||||
<div class="form-group">
|
||||
<label>Источник фотографий:</label>
|
||||
<div class="photo-source-buttons">
|
||||
<input type="file" id="badge-file-upload" multiple accept="image/*" style="display: none;">
|
||||
<button type="button" class="btn btn-secondary" id="btn-badge-upload">
|
||||
<span class="btn-icon-text">📤</span> Загрузить с устройства
|
||||
</button>
|
||||
<button type="button" class="btn btn-secondary" id="btn-badge-from-flickr">
|
||||
<span class="btn-icon-text">🖼</span> Выбранные в галерее Flickr
|
||||
</button>
|
||||
</div>
|
||||
<p class="hint">Размер итогового кружка — 240×240 PNG с прозрачным фоном.</p>
|
||||
</div>
|
||||
|
||||
<!-- Items grid (selected photos for badge processing) -->
|
||||
<div class="form-group">
|
||||
<label>Фотографии для бейджа: <span id="badge-items-count" class="photo-counter">0</span></label>
|
||||
<div id="badge-items-grid" class="badge-items-grid">
|
||||
<p class="placeholder">Выберите фото из галереи или загрузите с устройства</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Editor (visible when a photo is selected) -->
|
||||
<div id="badge-editor" class="badge-editor hidden">
|
||||
<div class="badge-editor-layout">
|
||||
<!-- Canvas preview -->
|
||||
<div class="badge-canvas-wrapper">
|
||||
<canvas id="badge-canvas" width="480" height="480"></canvas>
|
||||
<div class="badge-canvas-hint">Один палец — сдвиг, два пальца — масштаб. На компьютере — мышь и колесо.</div>
|
||||
</div>
|
||||
|
||||
<!-- Controls -->
|
||||
<div class="badge-controls">
|
||||
<div class="form-group">
|
||||
<label>Масштаб: <span id="badge-zoom-value">100%</span></label>
|
||||
<input type="range" id="badge-zoom" min="100" max="400" step="1" value="100">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<button type="button" id="btn-badge-reset" class="btn btn-secondary btn-small">Сбросить кадрирование</button>
|
||||
</div>
|
||||
|
||||
<hr style="border:none; border-top:1px solid var(--border-color, #ddd); margin:12px 0;">
|
||||
|
||||
<!-- Price tag -->
|
||||
<div class="form-group">
|
||||
<label class="checkbox-label">
|
||||
<input type="checkbox" id="badge-price-enabled">
|
||||
<span>Добавить ценник</span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="badge-price-options" class="badge-sub-options hidden">
|
||||
<div class="form-group">
|
||||
<label for="badge-price-value">Цена (₽):</label>
|
||||
<input type="number" inputmode="numeric" pattern="[0-9]*" id="badge-price-value" min="0" step="1" placeholder="2500">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Стиль плашки:</label>
|
||||
<div class="badge-radio-row">
|
||||
<label class="radio-label">
|
||||
<input type="radio" name="badge-price-style" value="arc" checked>
|
||||
<span>Дуга по низу</span>
|
||||
</label>
|
||||
<label class="radio-label">
|
||||
<input type="radio" name="badge-price-style" value="rect">
|
||||
<span>Прямоугольник</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr style="border:none; border-top:1px solid var(--border-color, #ddd); margin:12px 0;">
|
||||
|
||||
<!-- Nickname -->
|
||||
<div class="form-group">
|
||||
<label class="checkbox-label">
|
||||
<input type="checkbox" id="badge-nickname-enabled">
|
||||
<span>Добавить никнейм (дугой снизу)</span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="badge-nickname-options" class="badge-sub-options hidden">
|
||||
<div class="form-group">
|
||||
<label for="badge-nickname-value">Текст:</label>
|
||||
<input type="text" id="badge-nickname-value" maxlength="40" placeholder="Никнейм">
|
||||
<span class="hint">По умолчанию — из настроек.</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Цвет текста:</label>
|
||||
<div class="badge-radio-row">
|
||||
<label class="radio-label">
|
||||
<input type="radio" name="badge-nick-color" value="white" checked>
|
||||
<span>Белый (с тенью)</span>
|
||||
</label>
|
||||
<label class="radio-label">
|
||||
<input type="radio" name="badge-nick-color" value="black">
|
||||
<span>Чёрный</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr style="border:none; border-top:1px solid var(--border-color, #ddd); margin:12px 0;">
|
||||
|
||||
<div class="badge-actions">
|
||||
<button type="button" id="btn-badge-download" class="btn btn-primary">
|
||||
<span class="btn-icon-text">↓</span> <span id="badge-download-label">Сохранить PNG</span>
|
||||
</button>
|
||||
<button type="button" id="btn-badge-remove" class="btn btn-secondary btn-small">Убрать из списка</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Batch actions -->
|
||||
<div id="badge-batch-actions" class="form-group hidden" style="margin-top: 16px;">
|
||||
<button type="button" id="btn-badge-download-all" class="btn btn-secondary">
|
||||
<span class="btn-icon-text">⬇</span> Скачать все бейджи
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- History -->
|
||||
<div class="settings-section" style="margin-top: 24px;">
|
||||
<h3>История сохранённых бейджей</h3>
|
||||
<div id="badge-history-grid" class="badge-history-grid">
|
||||
<p class="placeholder">История пуста — сгенерированные бейджи будут появляться здесь.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Tab: Settings -->
|
||||
<section id="tab-settings" class="tab-content">
|
||||
<div class="panel">
|
||||
@@ -683,6 +821,18 @@ foreach ($channels as $ch) {
|
||||
<span id="cross-promo-save-status" class="save-status"></span>
|
||||
</div>
|
||||
|
||||
<!-- Digital Badge Settings -->
|
||||
<div class="settings-section">
|
||||
<h3>Цифровой бейдж</h3>
|
||||
<p class="help-text">Никнейм по умолчанию для подписи дугой снизу.</p>
|
||||
<div class="form-group">
|
||||
<label for="badge-nickname-default">Никнейм для бейджа:</label>
|
||||
<input type="text" id="badge-nickname-default" maxlength="40" placeholder="Ваш никнейм">
|
||||
<button id="btn-save-badge-nickname" class="btn btn-primary btn-small" style="margin-left: 10px;">Сохранить</button>
|
||||
<span id="badge-nickname-save-status" class="save-status"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Theme -->
|
||||
<div class="settings-section">
|
||||
<h3>Оформление</h3>
|
||||
|
||||
Reference in New Issue
Block a user