anycoder-95f2bff2 / index.html
Moonie805's picture
Upload folder using huggingface_hub
baa41ac verified
Raw
History Blame Contribute Delete
25.9 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Body Editor Pro</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
* {
font-family: 'Inter', sans-serif;
}
.gradient-bg {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.glass-effect {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
}
.tool-button {
transition: all 0.3s ease;
}
.tool-button:hover {
transform: translateY(-2px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
}
.chat-bubble {
animation: slideIn 0.3s ease;
}
@keyframes slideIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.editor-canvas {
background: repeating-linear-gradient(45deg,
#f0f0f0,
#f0f0f0 10px,
#e0e0e0 10px,
#e0e0e0 20px);
}
.filter-preview {
transition: all 0.3s ease;
}
.filter-preview:hover {
transform: scale(1.05);
}
.slider {
-webkit-appearance: none;
appearance: none;
height: 6px;
border-radius: 5px;
background: #d3d3d3;
outline: none;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 20px;
height: 20px;
border-radius: 50%;
background: #667eea;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 20px;
height: 20px;
border-radius: 50%;
background: #667eea;
cursor: pointer;
}
.body-marker {
position: absolute;
width: 12px;
height: 12px;
border-radius: 50%;
background: #667eea;
border: 2px solid white;
cursor: pointer;
transition: all 0.3s ease;
}
.body-marker:hover {
transform: scale(1.3);
}
.body-zone {
position: absolute;
border: 2px dashed rgba(102, 126, 234, 0.7);
border-radius: 8px;
background: rgba(102, 126, 234, 0.1);
pointer-events: none;
}
</style>
</head>
<body>
<div id="app">
<!-- Header -->
<header class="glass-effect text-white p-4">
<div class="container mx-auto flex justify-between items-center">
<h1 class="text-2xl font-bold">Body Editor Pro</h1>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" class="text-white hover:text-gray-200 transition-colors">
Built with anycoder
</a>
</div>
</header>
<div class="container mx-auto p-4 flex flex-col lg:flex-row gap-4">
<!-- Editor Section -->
<div class="flex-1 glass-effect rounded-xl p-6">
<h2 class="text-white text-xl font-semibold mb-4">Body Editor</h2>
<!-- Image Upload -->
<div class="mb-6">
<label class="block text-white mb-2">Upload Body Image</label>
<input
type="file"
accept="image/*"
id="imageUpload"
class="w-full p-2 rounded-lg bg-white/20 text-white file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-white/30 file:text-white hover:file:bg-white/40"
/>
</div>
<!-- Editor Canvas -->
<div class="editor-canvas rounded-lg p-4 mb-6 min-h-96 flex items-center justify-center relative">
<div id="imageContainer" class="relative">
<img
id="bodyImage"
src=""
alt="Body Image"
class="max-w-full max-h-96 rounded-lg shadow-lg"
/>
<!-- Body adjustment markers -->
<div id="bodyMarkers" class="absolute inset-0">
<!-- These markers will be positioned dynamically -->
</div>
<!-- Body zones for editing -->
<div id="bodyZones" class="absolute inset-0 pointer-events-none">
<!-- These zones will be positioned dynamically -->
</div>
</div>
<div id="noImageMessage" class="text-center text-white/60">
<i class="fas fa-user text-6xl mb-4"></i>
<p>Upload a body image to start editing</p>
</div>
</div>
<!-- Body Editing Tools -->
<div class="mb-6">
<h3 class="text-white mb-3">Body Adjustment Tools</h3>
<div class="grid grid-cols-3 sm:grid-cols-6 gap-2">
<button class="tool-button p-3 rounded-lg glass-effect text-white transition-all" data-tool="slim">
<i class="fas fa-arrows-alt-h text-lg"></i>
<span class="text-xs mt-1 block">Slim</span>
</button>
<button class="tool-button p-3 rounded-lg glass-effect text-white transition-all" data-tool="tall">
<i class="fas fa-arrows-alt-v text-lg"></i>
<span class="text-xs mt-1 block">Taller</span>
</button>
<button class="tool-button p-3 rounded-lg glass-effect text-white transition-all" data-tool="muscle">
<i class="fas fa-dumbbell text-lg"></i>
<span class="text-xs mt-1 block">Muscle</span>
</button>
<button class="tool-button p-3 rounded-lg glass-effect text-white transition-all" data-tool="waist">
<i class="fas fa-circle text-lg"></i>
<span class="text-xs mt-1 block">Waist</span>
</button>
<button class="tool-button p-3 rounded-lg glass-effect text-white transition-all" data-tool="chest">
<i class="fas fa-square text-lg"></i>
<span class="text-xs mt-1 block">Chest</span>
</button>
<button class="tool-button p-3 rounded-lg glass-effect text-white transition-all" data-tool="hips">
<i class="fas fa-circle text-lg"></i>
<span class="text-xs mt-1 block">Hips</span>
</button>
</div>
</div>
<!-- Body Adjustments -->
<div class="mb-6">
<h3 class="text-white mb-3">Body Adjustments</h3>
<div class="space-y-4">
<div>
<label class="text-white text-sm block mb-1">Overall Slim: <span id="slimValue">0</span>%</label>
<input
type="range"
min="-20"
max="20"
value="0"
id="slimSlider"
class="slider w-full"
/>
</div>
<div>
<label class="text-white text-sm block mb-1">Height: <span id="heightValue">0</span>%</label>
<input
type="range"
min="-10"
max="10"
value="0"
id="heightSlider"
class="slider w-full"
/>
</div>
<div>
<label class="text-white text-sm block mb-1">Muscle Definition: <span id="muscleValue">0</span>%</label>
<input
type="range"
min="0"
max="30"
value="0"
id="muscleSlider"
class="slider w-full"
/>
</div>
<div>
<label class="text-white text-sm block mb-1">Waist: <span id="waistValue">0</span>%</label>
<input
type="range"
min="-15"
max="15"
value="0"
id="waistSlider"
class="slider w-full"
/>
</div>
<div>
<label class="text-white text-sm block mb-1">Chest: <span id="chestValue">0</span>%</label>
<input
type="range"
min="-15"
max="15"
value="0"
id="chestSlider"
class="slider w-full"
/>
</div>
<div>
<label class="text-white text-sm block mb-1">Hips: <span id="hipsValue">0</span>%</label>
<input
type="range"
min="-15"
max="15"
value="0"
id="hipsSlider"
class="slider w-full"
/>
</div>
</div>
</div>
<!-- Action Buttons -->
<div class="flex gap-2">
<button
id="resetButton"
class="px-4 py-2 rounded-lg glass-effect text-white hover:bg-white/20 transition-colors"
>
Reset All
</button>
<button
id="downloadButton"
class="px-4 py-2 rounded-lg bg-white text-purple-600 font-semibold hover:bg-gray-100 transition-colors"
>
Download
</button>
</div>
</div>
<!-- Chat Section -->
<div class="lg:w-96 glass-effect rounded-xl p-6">
<h2 class="text-white text-xl font-semibold mb-4">Body Editor Assistant</h2>
<!-- Chat Messages -->
<div class="bg-white/10 rounded-lg p-4 h-96 overflow-y-auto mb-4">
<div class="chat-bubble mb-3">
<div class="flex items-start gap-2">
<div class="w-8 h-8 rounded-full bg-white/20 flex items-center justify-center text-white text-sm font-semibold">
A
</div>
<div class="flex-1">
<div class="flex items-center gap-2 mb-1">
<span class="text-white font-semibold text-sm">AI Assistant</span>
<span class="text-white/60 text-xs">10:30 AM</span>
</div>
<p class="text-white/90 text-sm">Welcome to Body Editor Pro! Upload a body image to start editing your physique.</p>
</div>
</div>
</div>
<div class="chat-bubble mb-3">
<div class="flex items-start gap-2">
<div class="w-8 h-8 rounded-full bg-white/20 flex items-center justify-center text-white text-sm font-semibold">
S
</div>
<div class="flex-1">
<div class="flex items-center gap-2 mb-1">
<span class="text-white font-semibold text-sm">System</span>
<span class="text-white/60 text-xs">10:31 AM</span>
</div>
<p class="text-white/90 text-sm">I can help you slim, tone, or build muscle in your photos.</p>
</div>
</div>
</div>
<div id="messagesEnd"></div>
</div>
<!-- Chat Input -->
<div class="flex gap-2">
<input
type="text"
id="messageInput"
placeholder="Ask about body editing..."
class="flex-1 p-3 rounded-lg bg-white/20 text-white placeholder-white/60 border border-white/30 focus:outline-none focus:border-white/50"
/>
<button
id="sendButton"
class="px-4 py-3 rounded-lg bg-white text-purple-600 font-semibold hover:bg-gray-100 transition-colors"
>
<i class="fas fa-paper-plane"></i>
</button>
</div>
<!-- Quick Actions -->
<div class="mt-4">
<h3 class="text-white mb-2">Quick Body Edits</h3>
<div class="grid grid-cols-2 gap-2">
<button class="p-2 rounded-lg glass-effect text-white text-sm hover:bg-white/20 transition-colors">
<i class="fas fa-running mr-1"></i> Athlete Mode
</button>
<button class="p-2 rounded-lg glass-effect text-white text-sm hover:bg-white/20 transition-colors">
<i class="fas fa-swimmer mr-1"></i> Swimmer Body
</button>
<button class="p-2 rounded-lg glass-effect text-white text-sm hover:bg-white/20 transition-colors">
<i class="fas fa-yin-yang mr-1"></i> Balanced
</button>
<button class="p-2 rounded-lg glass-effect text-white text-sm hover:bg-white/20 transition-colors">
<i class="fas fa-fire mr-1"></i> Fitness Model
</button>
</div>
</div>
</div>
<script>
// DOM Elements
const imageUpload = document.getElementById('imageUpload');
const bodyImage = document.getElementById('bodyImage');
const noImageMessage = document.getElementById('noImageMessage');
const imageContainer = document.getElementById('imageContainer');
const messageInput = document.getElementById('messageInput');
const sendButton = document.getElementById('sendButton');
const messagesEnd = document.getElementById('messagesEnd');
const resetButton = document.getElementById('resetButton');
const downloadButton = document.getElementById('downloadButton');
const chatMessages = document.querySelector('.bg-white/10');
// Slider elements
const slimSlider = document.getElementById('slimSlider');
const heightSlider = document.getElementById('heightSlider');
const muscleSlider = document.getElementById('muscleSlider');
const waistSlider = document.getElementById('waistSlider');
const chestSlider = document.getElementById('chestSlider');
const hipsSlider = document.getElementById('hipsSlider');
// Value displays
const slimValue = document.getElementById('slimValue');
const heightValue = document.getElementById('heightValue');
const muscleValue = document.getElementById('muscleValue');
const waistValue = document.getElementById('waistValue');
const chestValue = document.getElementById('chestValue');
const hipsValue = document.getElementById('hipsValue');
// Tool buttons
const toolButtons = document.querySelectorAll('[data-tool]');
// Current state
let currentImage = null;
let originalImage = null;
let adjustments = {
slim: 0,
height: 0,
muscle: 0,
waist: 0,
chest: 0,
hips: 0
};
// Initialize the app
function init() {
// Hide the image initially
bodyImage.style.display = 'none';
// Add event listeners
imageUpload.addEventListener('change', handleImageUpload);
sendButton.addEventListener('click', sendMessage);
messageInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') sendMessage();
});
// Slider event listeners
slimSlider.addEventListener('input', updateSlimAdjustment);
heightSlider.addEventListener('input', updateHeightAdjustment);
muscleSlider.addEventListener('input', updateMuscleAdjustment);
waistSlider.addEventListener('input', updateWaistAdjustment);
chestSlider.addEventListener('input', updateChestAdjustment);
hipsSlider.addEventListener('input', updateHipsAdjustment);
// Tool button event listeners
toolButtons.forEach(button => {
button.addEventListener('click', () => {
const tool = button.getAttribute('data-tool');
activateTool(tool);
});
});
// Action button event listeners
resetButton.addEventListener('click', resetAdjustments);
downloadButton.addEventListener('click', downloadImage);
}
// Handle image upload
function handleImageUpload(e) {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
currentImage = e.target.result;
originalImage = e.target.result;
bodyImage.src = currentImage;
bodyImage.style.display = 'block';
noImageMessage.style.display = 'none';
// Add message to chat
addChatMessage('System', 'Body image uploaded successfully! You can now adjust the physique.');
// Add body markers after image loads
bodyImage.onload = () => {
addBodyMarkers();
};
};
reader.readAsDataURL(file);
}
}
// Add body markers for editing
function addBodyMarkers() {
const markersContainer = document.getElementById('bodyMarkers');
const zonesContainer = document.getElementById('bodyZones');
// Clear existing markers
markersContainer.innerHTML = '';
zonesContainer.innerHTML = '';
// Define body points and zones
const bodyPoints = [
{ name: 'head', x: 50, y: 10 },
{ name: 'shoulders', x: 50, y: 25 },
{ name: 'chest', x: 50, y: 35 },
{ name: 'waist', x: 50, y: 50 },
{ name: 'hips', x: 50, y: 65 },
{ name: 'legs', x: 50, y: 85 }
];
// Create markers
bodyPoints.forEach(point => {
const marker = document.createElement('div');
marker.className = 'body-marker';
marker.style.left = `${point.x}%`;
marker.style.top = `${point.y}%`;
marker.setAttribute('data-point', point.name);
markersContainer.appendChild(marker);
// Add click event to markers
marker.addEventListener('click', () => {
highlightBodyZone(point.name);
addChatMessage('You', `Selected ${point.name} for adjustment`);
});
});
// Create body zones
const bodyZones = [
{ name: 'chest', top: 25, left: 35, width: 30, height: 15 },
{ name: 'waist', top: 45, left: 40, width: 20, height: 10 },
{ name: 'hips', top: 60, left: 38, width: 24, height: 10 },
{ name: 'legs', top: 70, left: 35, width: 30, height: 25 }
];
// Create zones
bodyZones.forEach(zone => {
const zoneDiv = document.createElement('div');
zoneDiv.className = 'body-zone';
zoneDiv.style.top = `${zone.top}%`;
zoneDiv.style.left = `${zone.left}%`;
zoneDiv.style.width = `${zone.width}%`;
zoneDiv.style.height = `${zone.height}%`;
zoneDiv.setAttribute('data-zone', zone.name);
zonesContainer.appendChild(zoneDiv);
});
}
// Highlight a body zone
function highlightBodyZone(zoneName) {
const zones = document.querySelectorAll('.body-zone');
zones.forEach(zone => {
if (zone.getAttribute('data-zone') === zoneName) {
zone.style.background = 'rgba(102, 126, 234, 0.3)';
zone.style.border = '2px solid rgba(102, 126, 234, 0.9)';
} else {
zone.style.background = 'rgba(102, 126, 234, 0.1)';
zone.style.border = '2px dashed rgba(102, 126, 234, 0.7)';
}
});
// Adjust sliders based on zone
switch(zoneName) {
case 'chest':
chestSlider.focus();
break;
case 'waist':
waistSlider.focus();
break;
case 'hips':
hipsSlider.focus();
break;
case 'legs':
slimSlider.focus();
break;
}
}
// Activate a tool
function activateTool(tool) {
// Remove active state from all tools
toolButtons.forEach(button => {
button.classList.remove('ring-2', 'ring-white');
});
// Add active state to clicked tool
event.currentTarget.classList.add('ring-2', 'ring-white');
// Show appropriate adjustments based on tool
switch(tool) {
case 'slim':
slimSlider.focus();
addChatMessage('You', 'Activated slimming tool');
break;
case 'tall':
heightSlider.focus();
addChatMessage('You', 'Activated height adjustment tool');
break;
case 'muscle':
muscleSlider.focus();
addChatMessage('You', 'Activated muscle definition tool');
break;
case 'waist':
waistSlider.focus();
addChatMessage('You', 'Activated waist adjustment tool');
break;
case 'chest':
chestSlider.focus();
addChatMessage('You', 'Activated chest adjustment tool');
break;
case 'hips':
hipsSlider.focus();
addChatMessage('You', 'Activated hips adjustment tool');
break;
}
}
// Update adjustments based on slider values
function updateSlimAdjustment() {
adjustments.slim = slimSlider.value;
slimValue.textContent = adjustments.slim;
applyBodyAdjustments();
}
function updateHeightAdjustment() {
adjustments.height = heightSlider.value;
heightValue.textContent = adjustments.height;
applyBodyAdjustments();
}
function updateMuscleAdjustment() {
adjustments.muscle = muscleSlider.value;
muscleValue.textContent = adjustments.muscle;
applyBodyAdjustments();
}
function updateWaistAdjustment() {
adjustments.waist = waistSlider.value;
waistValue.textContent = adjustments.waist;
applyBodyAdjustments();
}
function updateChestAdjustment() {
adjustments.chest = chestSlider.value;
chestValue.textContent = adjustments.chest;
applyBodyAdjustments();
}
function updateHipsAdjustment() {
adjustments.hips = hipsSlider.value;
hipsValue.textContent = adjustments.hips;
applyBodyAdjustments();
}
// Apply body adjustments to the image
function applyBodyAdjustments() {
if (!currentImage) return;
// In a real application, this would use a canvas and image processing
// For this demo, we'll just simulate the effect
// Show loading effect
bodyImage.style.opacity = '0.7';
// Simulate processing delay
setTimeout(() => {
bodyImage.style.opacity = '1';
// Add chat message about the adjustment
const totalAdjustment = Object.values(adjustments).reduce((sum, val) => sum + Math.abs(val), 0);
if (totalAdjustment > 0) {
addChatMessage('System', `Applied adjustments: Slim ${adjustments.slim}%, Height ${adjustments.height}%, Muscle ${adjustments.muscle}%`);
}
}, 300);
}
// Reset all adjustments
function resetAdjustments() {
adjustments = {
slim: 0,
height: 0,
muscle: 0,
waist: 0,
chest: 0,
hips: 0
};
// Reset sliders
slimSlider.value = 0;
heightSlider.value = 0;
muscleSlider.value = 0;
waistSlider.value = 0;
chestSlider.value = 0;
hipsSlider.value = 0;
// Update value displays
slimValue.textContent = '0';
heightValue.textContent = '0';
muscleValue.textContent = '0';
waistValue.textContent = '0';
chestValue.textContent = '0';
hipsValue.textContent = '0';
// Reset image
bodyImage.src = originalImage;
// Add message to chat
addChatMessage('You', 'Reset all body adjustments');
}
// Download the edited image
function downloadImage() {
if (!currentImage) {
addChatMessage('System', 'Please upload an image first');
return;
}
// Create a temporary link to download the image
const link = document.createElement('a');
link.download = 'edited-body-image.png';
link.href = currentImage;
link.click();
// Add message to chat
addChatMessage('System', 'Body image downloaded successfully!');
}
// Chat functionality
function sendMessage() {
const message = messageInput.value.trim();
if (message) {
addChatMessage('You', message);
messageInput.value = '';
// Simulate AI response
setTimeout(() => {
const responses = [
"I can help you adjust that area. Try using the sliders to fine-tune the effect.",
"For more natural results, make small adjustments to multiple areas.",
"Body editing works best when you maintain natural proportions.",
"Would you like me to suggest some quick presets for common body types?",
"You can use the body markers to quickly select specific areas for editing.",
"The muscle definition tool works well with the chest and arms areas.",
"Try the height adjustment for a more balanced overall look."
];
const randomResponse = responses[Math.floor(Math.random() * responses.length)];
addChatMessage('AI Assistant', randomResponse);
}, 1000);
}
}
// Add a message to the chat
function addChatMessage(user, message) {
const time = new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
const messageDiv = document.createElement('div');
messageDiv.className = 'chat-bubble mb-3';
messageDiv.innerHTML = `
<div class="flex items-start gap-2">
<div class="w-8 h-8 rounded-full bg-white/20 flex items-center justify-center text-white text-sm font-semibold">
${user[0]}
</div>
<div class="flex-1">
<div class="flex items-center gap-2 mb-1">
<span class="text-white font-semibold text-sm">${user}</span>
<span class="text-white/60 text-xs">${time}</span>
</div>
<p class="text-white/90 text-sm">${message}</p>
</div>
`;
chatMessages.appendChild(messageDiv);
messagesEnd.scrollIntoView({ behavior: 'smooth' });
}
// Initialize the app when DOM is loaded
document.addEventListener('DOMContentLoaded', init);
</script>
</body>
</html>