feat(avatar): add human silhouette overlay to avatar cropper
Added visual guide with human body contour overlay to help users properly position their face for FaceID.
Features:
- SVG overlay with human silhouette (head, neck, shoulders)
- Green dashed outline (70-80% face coverage guidance)
- Guide lines (vertical center, horizontal eye level)
- Text labels ('Верх головы', 'Плечи')
- Toggle checkbox to show/hide overlay
- Real-time overlay positioning synchronized with crop box
Technical implementation:
- SVG viewBox 400x400 with preserveAspectRatio
- Dynamic positioning using getCropBoxData()
- Event handlers: ready, crop, zoom
- Overlay updates on cropper interactions
- Pointer-events: none for non-intrusive UI
UI/UX improvements:
- Clear visual guidance for face positioning
- Non-intrusive overlay (can be toggled off)
- Color: #00ff00 (green) for high visibility
- Opacity: 0.8 for overlay, 0.4 for guide lines
- Auto-shown by default, user can disable
Benefits:
✓ Reduces user errors in face positioning
✓ Ensures consistent photo quality for FaceID
✓ Visual feedback for proper head/shoulders alignment
✓ Improves user experience and reduces support requests
This commit is contained in:
parent
53f1eb8096
commit
c3a82378ff
@ -49,6 +49,7 @@ const DEFAULT_CONFIG = {
|
||||
<div class="alert alert-info mb-3">
|
||||
<h6 class="mb-2"><i class="bi-info-circle me-2"></i>Требования для системы распознавания лиц:</h6>
|
||||
<ul class="mb-0 small">
|
||||
<li><strong>Совместите голову и плечи с контуром</strong></li>
|
||||
<li>Лицо должно занимать 70-80% кадра</li>
|
||||
<li>Расположите лицо в центре рамки</li>
|
||||
<li>Избегайте теней и бликов</li>
|
||||
@ -107,14 +108,53 @@ export class AvatarCropper {
|
||||
${this.config.texts.instructions}
|
||||
|
||||
<!-- Контейнер для Cropper.js -->
|
||||
<div class="cropper-container-wrapper" style="max-height: 500px; overflow: hidden;">
|
||||
<div class="cropper-container-wrapper position-relative" style="max-height: 500px; overflow: hidden;">
|
||||
<img id="cropperImage" style="max-width: 100%; display: block;">
|
||||
|
||||
<!-- SVG оверлей с контуром человека -->
|
||||
<svg id="humanOverlay" class="position-absolute top-0 start-0 w-100 h-100"
|
||||
style="pointer-events: none; z-index: 1000; display: none;"
|
||||
viewBox="0 0 400 400" preserveAspectRatio="xMidYMid meet">
|
||||
<!-- Контур головы и плеч -->
|
||||
<g fill="none" stroke="#00ff00" stroke-width="3" stroke-opacity="0.8" stroke-dasharray="8,4">
|
||||
<!-- Голова (эллипс) -->
|
||||
<ellipse cx="200" cy="140" rx="85" ry="105"/>
|
||||
|
||||
<!-- Шея -->
|
||||
<path d="M 160 230 L 160 260 M 240 230 L 240 260"/>
|
||||
|
||||
<!-- Плечи -->
|
||||
<path d="M 90 340 Q 160 260, 200 260 Q 240 260, 310 340"/>
|
||||
</g>
|
||||
|
||||
<!-- Направляющие линии -->
|
||||
<g stroke="#00ff00" stroke-width="1" stroke-opacity="0.4" stroke-dasharray="4,4">
|
||||
<!-- Вертикальная центральная линия -->
|
||||
<line x1="200" y1="0" x2="200" y2="400"/>
|
||||
<!-- Горизонтальная линия глаз -->
|
||||
<line x1="0" y1="140" x2="400" y2="140"/>
|
||||
</g>
|
||||
|
||||
<!-- Подсказки -->
|
||||
<text x="200" y="30" text-anchor="middle" fill="#00ff00" font-size="14" font-weight="bold">
|
||||
↓ Верх головы
|
||||
</text>
|
||||
<text x="200" y="390" text-anchor="middle" fill="#00ff00" font-size="14" font-weight="bold">
|
||||
↑ Плечи
|
||||
</text>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<!-- Индикатор размера -->
|
||||
<div class="mt-3 text-center">
|
||||
<!-- Индикатор размера и контроль оверлея -->
|
||||
<div class="mt-3 d-flex justify-content-between align-items-center">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="toggleHumanOverlay" checked>
|
||||
<label class="form-check-label" for="toggleHumanOverlay">
|
||||
<small><i class="bi-person-bounding-box me-1"></i>Показать контур человека</small>
|
||||
</label>
|
||||
</div>
|
||||
<small class="text-muted" id="cropperSizeIndicator">
|
||||
Размер обрезанного фото: <span class="fw-bold">-</span>
|
||||
Размер: <span class="fw-bold">-</span>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
@ -161,6 +201,12 @@ export class AvatarCropper {
|
||||
if (cropperImage) {
|
||||
cropperImage.addEventListener('crop', (e) => this.updateSizeIndicator(e.detail));
|
||||
}
|
||||
|
||||
// Обработчик переключения контура человека
|
||||
const toggleOverlay = document.getElementById('toggleHumanOverlay');
|
||||
if (toggleOverlay) {
|
||||
toggleOverlay.addEventListener('change', (e) => this.toggleHumanOverlay(e.target.checked));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -268,13 +314,60 @@ export class AvatarCropper {
|
||||
ready: () => {
|
||||
console.log('[AvatarCropper] Cropper ready');
|
||||
this.updateSizeIndicator();
|
||||
this.updateOverlayPosition();
|
||||
this.showHumanOverlay();
|
||||
},
|
||||
crop: (event) => {
|
||||
this.updateSizeIndicator(event.detail);
|
||||
this.updateOverlayPosition();
|
||||
},
|
||||
zoom: () => {
|
||||
this.updateOverlayPosition();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Показывает контур человека
|
||||
*/
|
||||
showHumanOverlay() {
|
||||
const overlay = document.getElementById('humanOverlay');
|
||||
const toggle = document.getElementById('toggleHumanOverlay');
|
||||
|
||||
if (overlay && toggle && toggle.checked) {
|
||||
overlay.style.display = 'block';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Переключает видимость контура человека
|
||||
*/
|
||||
toggleHumanOverlay(show) {
|
||||
const overlay = document.getElementById('humanOverlay');
|
||||
if (overlay) {
|
||||
overlay.style.display = show ? 'block' : 'none';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновляет позицию оверлея в соответствии с crop box
|
||||
*/
|
||||
updateOverlayPosition() {
|
||||
if (!this.cropper) return;
|
||||
|
||||
const overlay = document.getElementById('humanOverlay');
|
||||
if (!overlay) return;
|
||||
|
||||
const cropBoxData = this.cropper.getCropBoxData();
|
||||
const containerData = this.cropper.getContainerData();
|
||||
|
||||
// Позиционируем SVG оверлей точно над crop box
|
||||
overlay.style.left = cropBoxData.left + 'px';
|
||||
overlay.style.top = cropBoxData.top + 'px';
|
||||
overlay.style.width = cropBoxData.width + 'px';
|
||||
overlay.style.height = cropBoxData.height + 'px';
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновляет индикатор размера обрезанного изображения
|
||||
*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user