slothmonarchy's picture
The reference measurement will be bust, underbust, waist, hips, height or weight in imperial or metric
3db8e08 verified
Raw History Blame Contribute Delete
11.5 kB
// Global variables
let currentImage = null;
let analysisInProgress = false;
// DOM Elements
const dropZone = document.getElementById('dropZone');
const imageUpload = document.getElementById('imageUpload');
const previewImage = document.getElementById('previewImage');
const resultsSection = document.getElementById('resultsSection');
const loadingSection = document.getElementById('loadingSection');
// Measurement elements
const measurementElements = {
bust: { value: document.getElementById('bustValue'), note: document.getElementById('bustNote') },
underbust: { value: document.getElementById('underbustValue'), note: document.getElementById('underbustNote') },
waist: { value: document.getElementById('waistValue'), note: document.getElementById('waistNote') },
hips: { value: document.getElementById('hipsValue'), note: document.getElementById('hipsNote') },
height: { value: document.getElementById('heightValue'), note: document.getElementById('heightNote') },
weight: { value: document.getElementById('weightValue'), note: document.getElementById('weightNote') }
};
// Confidence elements
const confidenceValue = document.getElementById('confidenceValue');
const analysisNotes = document.getElementById('analysisNotes');
// Initialize the application
document.addEventListener('DOMContentLoaded', function() {
initializeEventListeners();
});
function initializeEventListeners() {
// File input change
imageUpload.addEventListener('change', handleFileSelect);
// Drag and drop events
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
dropZone.addEventListener(eventName, preventDefaults, false);
});
['dragenter', 'dragover'].forEach(eventName => {
dropZone.addEventListener(eventName, highlight, false);
});
['dragleave', 'drop'].forEach(eventName => {
dropZone.addEventListener(eventName, unhighlight, false);
});
dropZone.addEventListener('drop', handleDrop, false);
}
function preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
function highlight() {
dropZone.classList.add('drag-over');
}
function unhighlight() {
dropZone.classList.remove('drag-over');
}
function handleDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
handleFiles(files);
}
function handleFileSelect(e) {
const files = e.target.files;
handleFiles(files);
}
function handleFiles(files) {
if (analysisInProgress) return;
const file = files[0];
if (!file) return;
// Check if file is an image
if (!file.type.match('image.*')) {
alert('Please upload an image file (JPG, PNG, WEBP)');
return;
}
// Check file size (10MB max)
if (file.size > 10 * 1024 * 1024) {
alert('File size must be less than 10MB');
return;
}
// Create preview
const reader = new FileReader();
reader.onload = function(e) {
previewImage.src = e.target.result;
currentImage = e.target.result;
startAnalysis();
};
reader.readAsDataURL(file);
}
function startAnalysis() {
if (!currentImage) return;
analysisInProgress = true;
// Show loading state
resultsSection.classList.add('hidden');
loadingSection.classList.remove('hidden');
// Get reference values
const referenceType = document.getElementById('referenceType').value;
const referenceValue = parseFloat(document.getElementById('referenceValue').value) || null;
const unitSystem = document.getElementById('unitSystem').value;
const actualHeight = parseFloat(document.getElementById('actualHeight').value) || null;
const heightUnit = document.getElementById('heightUnit').value;
// Simulate AI analysis (in a real app, this would call an API)
setTimeout(() => {
performAnalysis(referenceType, referenceValue, unitSystem, actualHeight, heightUnit);
}, 3000);
}
function performAnalysis(referenceType, referenceValue, unitSystem, actualHeight, heightUnit) {
// This is a mock analysis - in a real application, this would use computer vision APIs
const measurements = generateMockMeasurements(referenceType, referenceValue, unitSystem, actualHeight, heightUnit);
// Update UI with results
updateResultsUI(measurements, unitSystem);
// Hide loading, show results
loadingSection.classList.add('hidden');
resultsSection.classList.remove('hidden');
analysisInProgress = false;
}
function generateMockMeasurements(referenceType, referenceValue, unitSystem, actualHeight, heightUnit) {
// Convert actual height to cm for internal calculations
let baseHeightCm;
if (actualHeight) {
baseHeightCm = heightUnit === 'in' ? actualHeight * 2.54 : actualHeight;
} else {
baseHeightCm = 160 + Math.random() * 30; // 160-190cm if not provided
}
// Base measurements in cm for metric system
let baseMeasurements = {
bust: (85 + Math.random() * 20) * (baseHeightCm / 170),
underbust: (70 + Math.random() * 15) * (baseHeightCm / 170),
waist: (65 + Math.random() * 15) * (baseHeightCm / 170),
hips: (90 + Math.random() * 20) * (baseHeightCm / 170),
height: baseHeightCm,
weight: (55 + Math.random() * 25) * (baseHeightCm / 170) / 1.7
};
// Adjust measurements if reference is provided
if (referenceValue && referenceType) {
// Convert reference value to cm if needed
let referenceValueCm = referenceValue;
if (unitSystem === 'imperial' && referenceType !== 'weight') {
referenceValueCm = referenceValue * 2.54;
} else if (unitSystem === 'imperial' && referenceType === 'weight') {
referenceValueCm = referenceValue * 0.453592;
}
// Calculate scaling factor based on reference
const scalingFactor = referenceValueCm / baseMeasurements[referenceType];
// Apply scaling to all measurements
Object.keys(baseMeasurements).forEach(key => {
if (key !== 'weight') {
baseMeasurements[key] *= scalingFactor;
} else {
baseMeasurements[key] *= scalingFactor;
}
});
}
// Convert to desired unit system for display
const measurements = {};
Object.keys(baseMeasurements).forEach(key => {
let displayValue;
let estimated = true;
let confidence = 'medium';
// Determine if this measurement is accurate based on reference
if (referenceType === key) {
estimated = false;
confidence = 'high';
} else if (referenceValue && referenceType) {
confidence = 'high';
}
if (unitSystem === 'metric') {
if (key === 'weight') {
displayValue = Math.round(baseMeasurements[key]);
} else {
displayValue = Math.round(baseMeasurements[key]);
}
} else {
if (key === 'weight') {
displayValue = Math.round(baseMeasurements[key] * 2.20462);
} else {
displayValue = Math.round(baseMeasurements[key] / 2.54 * 10) / 10; // Round to 1 decimal for inches
} else {
displayValue = Math.round(baseMeasurements[key]);
}
}
measurements[key] = {
value: displayValue,
estimated: estimated,
confidence: confidence
};
});
return measurements;
}
function updateResultsUI(measurements, unitSystem) {
// Update each measurement
Object.keys(measurements).forEach(key => {
const measurement = measurements[key];
const element = measurementElements[key];
if (element) {
// Update value with appropriate units
let unit = '';
if (key === 'weight') {
unit = unitSystem === 'metric' ? 'kg' : 'lbs';
} else {
unit = unitSystem === 'metric' ? 'cm' : 'in';
}
element.value.textContent = `${measurement.value} ${unit}`;
// Update note
if (measurement.estimated) {
element.note.textContent = 'Estimated value';
element.note.className = 'text-sm text-amber-600';
} else {
element.note.textContent = 'Measured from reference';
element.note.className = 'text-sm text-green-600';
}
}
});
// Update confidence level
const confidenceLevels = Object.values(measurements).map(m => m.confidence);
const avgConfidence = confidenceLevels.reduce((a, b) => {
const values = { low: 1, medium: 2, high: 3 };
return a + values[b];
}, 0) / confidenceLevels.length;
let confidenceText = '';
let confidenceColor = '';
if (avgConfidence >= 2.5) {
confidenceText = 'High';
confidenceColor = 'text-green-600';
} else if (avgConfidence >= 1.5) {
confidenceText = 'Medium';
confidenceColor = 'text-amber-600';
} else {
confidenceText = 'Low';
confidenceColor = 'text-red-600';
}
confidenceValue.textContent = confidenceText;
confidenceValue.className = `font-semibold ${confidenceColor}`;
// Update analysis notes
let notes = [];
const referenceType = document.getElementById('referenceType').value;
const referenceValue = parseFloat(document.getElementById('referenceValue').value) || null;
const actualHeight = parseFloat(document.getElementById('actualHeight').value) || null;
if (!referenceValue && !actualHeight) {
notes.push('No reference measurement provided. Measurements are estimated based on average proportions.');
} else if (referenceValue && !actualHeight) {
notes.push(`Using ${referenceType} measurement as reference. Height is estimated.`);
} else if (actualHeight) {
notes.push('Using provided height for proportion calculations.');
}
if (measurements.weight.estimated) {
notes.push('Weight is estimated based on body proportions and typical BMI ranges.');
}
analysisNotes.querySelector('span').textContent = notes.join(' ');
}
function resetAnalysis() {
// Reset file input
imageUpload.value = '';
// Reset preview
previewImage.src = '';
currentImage = null;
// Reset measurement values
Object.values(measurementElements).forEach(element => {
element.value.textContent = '-- cm';
element.note.textContent = '';
element.note.className = 'text-sm text-gray-600';
});
// Reset reference inputs
document.getElementById('referenceType').value = 'bust';
document.getElementById('unitSystem').value = 'metric';
document.getElementById('referenceValue').value = '';
document.getElementById('actualHeight').value = '';
document.getElementById('heightUnit').value = 'cm';
// Hide results
resultsSection.classList.add('hidden');
}
// Utility function to convert pixels to real measurements
function pixelsToCm(pixels, referencePixels, referenceCm) {
if (!referencePixels || !referenceCm) return null;
return (pixels / referencePixels) * referenceCm;
}