|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>AI Phone Cover Designer</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"> |
|
<style> |
|
@keyframes gradientShift { |
|
0% { background-position: 0% 50%; } |
|
50% { background-position: 100% 50%; } |
|
100% { background-position: 0% 50%; } |
|
} |
|
body::before { |
|
content: ""; |
|
position: fixed; |
|
top: 0; |
|
left: 0; |
|
width: 100%; |
|
height: 100%; |
|
background: linear-gradient(-45deg, #ff9a9e, #fad0c4, #fbc2eb, #8fd3f4); |
|
background-size: 400% 400%; |
|
z-index: -1; |
|
animation: gradientShift 15s ease infinite; |
|
} |
|
.design-box { |
|
background: rgba(255, 255, 255, 0.9); |
|
backdrop-filter: blur(10px); |
|
border-radius: 15px; |
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); |
|
} |
|
.gallery-item { |
|
transition: transform 0.3s, box-shadow 0.3s; |
|
} |
|
.gallery-item:hover { |
|
transform: scale(1.05); |
|
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2); |
|
} |
|
.loading-dots span { |
|
animation: typing 1s infinite ease-in-out; |
|
} |
|
@keyframes typing { |
|
0% { transform: translateY(0); opacity: 0.4; } |
|
50% { transform: translateY(-5px); opacity: 1; } |
|
100% { transform: translateY(0); opacity: 0.4; } |
|
} |
|
</style> |
|
</head> |
|
<body class="min-h-screen font-sans"> |
|
<div class="container mx-auto px-4 py-8"> |
|
|
|
<header class="text-center mb-12"> |
|
<h1 class="text-5xl font-bold mb-4 bg-clip-text text-transparent bg-gradient-to-r from-pink-500 to-blue-500"> |
|
AI Phone Cover Designer |
|
</h1> |
|
<p class="text-xl text-gray-700">Create custom phone covers with AI</p> |
|
</header> |
|
|
|
|
|
<div class="design-box p-8 max-w-4xl mx-auto"> |
|
|
|
<div class="flex gap-4 mb-8"> |
|
<button data-tab="home" class="tab-btn px-6 py-2 rounded-full bg-blue-500 text-white font-semibold"> |
|
Home |
|
</button> |
|
<button data-tab="design" class="tab-btn px-6 py-2 rounded-full bg-gray-200 text-gray-700"> |
|
Design |
|
</button> |
|
<button data-tab="about" class="tab-btn px-6 py-2 rounded-full bg-gray-200 text-gray-700"> |
|
About |
|
</button> |
|
</div> |
|
|
|
|
|
<div id="home-tab" class="tab-content active"> |
|
<h2 class="text-3xl font-bold mb-6 text-gray-800">Welcome</h2> |
|
<div class="grid grid-cols-2 gap-4" id="gallery"> |
|
|
|
</div> |
|
</div> |
|
|
|
|
|
<div id="design-tab" class="tab-content hidden"> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-8"> |
|
<div> |
|
<div class="mb-6"> |
|
<label class="block text-gray-700 mb-2 font-semibold">Color</label> |
|
<input type="text" id="color-input" class="w-full p-3 border rounded-lg" |
|
placeholder="E.g., Red"> |
|
</div> |
|
<div class="mb-6"> |
|
<label class="block text-gray-700 mb-2 font-semibold">Mobile Type</label> |
|
<input type="text" id="type-input" class="w-full p-3 border rounded-lg" |
|
placeholder="E.g., iPhone 15"> |
|
</div> |
|
<div class="mb-6"> |
|
<label class="block text-gray-700 mb-2 font-semibold">Design Details</label> |
|
<textarea id="design-input" class="w-full p-3 border rounded-lg" rows="3" |
|
placeholder="E.g., Bold stripes with geometric patterns"></textarea> |
|
</div> |
|
<button id="generate-btn" class="w-full bg-blue-500 text-white py-3 rounded-lg font-semibold |
|
hover:bg-blue-600 transition-colors"> |
|
Generate Design |
|
</button> |
|
<button id="save-btn" class="w-full mt-4 bg-green-500 text-white py-3 rounded-lg font-semibold |
|
hover:bg-green-600 transition-colors"> |
|
Save Design |
|
</button> |
|
</div> |
|
<div> |
|
<div class="border-2 border-dashed border-gray-300 rounded-lg p-4 aspect-square flex items-center justify-center" |
|
id="output-image"> |
|
<span class="text-gray-400">Your design will appear here</span> |
|
</div> |
|
<div class="mt-4 p-4 bg-blue-50 rounded-lg" id="ai-message"> |
|
<div class="text-blue-600 font-semibold">AI Assistant:</div> |
|
<div id="message-text" class="mt-2"></div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="about-tab" class="tab-content hidden"> |
|
<h2 class="text-3xl font-bold mb-6 text-gray-800">About</h2> |
|
<div class="space-y-4 text-gray-700"> |
|
<p>The AI Phone Cover Maker is a cutting-edge tool designed to help users create personalized phone cover designs quickly and easily.</p> |
|
<div class="bg-white p-4 rounded-lg"> |
|
<h3 class="font-semibold text-lg mb-2">Features:</h3> |
|
<ul class="list-disc pl-6"> |
|
<li>Create custom designs using simple prompts</li> |
|
<li>Generate designs for various phone models</li> |
|
<li>Save your designs for future use</li> |
|
</ul> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="loading" class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center"> |
|
<div class="bg-white p-8 rounded-lg text-center"> |
|
<div class="loading-dots space-x-1 mb-4"> |
|
<span class="inline-block w-2 h-2 bg-blue-500 rounded-full"></span> |
|
<span class="inline-block w-2 h-2 bg-blue-500 rounded-full"></span> |
|
<span class="inline-block w-2 h-2 bg-blue-500 rounded-full"></span> |
|
</div> |
|
<p class="text-gray-700">Generating your design...</p> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<script> |
|
document.addEventListener('DOMContentLoaded', function() { |
|
const API_URL = "https://api-inference.huggingface.co/models/artificialguybr/TshirtDesignRedmond-V2"; |
|
const tabs = { |
|
home: document.getElementById('home-tab'), |
|
design: document.getElementById('design-tab'), |
|
about: document.getElementById('about-tab') |
|
}; |
|
|
|
|
|
document.querySelectorAll('.tab-btn').forEach(btn => { |
|
btn.addEventListener('click', function() { |
|
|
|
Object.values(tabs).forEach(tab => tab.classList.add('hidden')); |
|
document.querySelectorAll('.tab-btn').forEach(b => |
|
b.classList.replace('bg-blue-500', 'bg-gray-200')); |
|
|
|
|
|
const tabId = this.dataset.tab; |
|
tabs[tabId].classList.remove('hidden'); |
|
this.classList.replace('bg-gray-200', 'bg-blue-500'); |
|
}); |
|
}); |
|
|
|
|
|
document.getElementById('generate-btn').addEventListener('click', async function() { |
|
const color = document.getElementById('color-input').value; |
|
const type = document.getElementById('type-input').value; |
|
const design = document.getElementById('design-input').value; |
|
|
|
if (!color || !type || !design) { |
|
alert('Please fill in all fields'); |
|
return; |
|
} |
|
|
|
showLoading(true); |
|
try { |
|
const prompt = `A single vertical ${color} colored ${type} back cover featuring a bold ${design} design on the front, hanging on the plain wall. The soft light and shadows, creating a striking contrast against the minimal background, evoking modern sophistication.`; |
|
|
|
const response = await queryAPI(prompt); |
|
const imageUrl = URL.createObjectURL(response); |
|
|
|
|
|
const output = document.getElementById('output-image'); |
|
output.innerHTML = `<img src="${imageUrl}" class="w-full h-full object-contain rounded-lg">`; |
|
|
|
|
|
const message = `Your design is generated with the color '${color}', mobile type '${type}', and design '${design}'.`; |
|
document.getElementById('message-text').textContent = message; |
|
speakMessage(message); |
|
} catch (error) { |
|
alert('Error generating design: ' + error.message); |
|
} |
|
showLoading(false); |
|
}); |
|
|
|
|
|
document.getElementById('save-btn').addEventListener('click', function() { |
|
const img = document.querySelector('#output-image img'); |
|
if (!img) { |
|
alert('No design to save'); |
|
return; |
|
} |
|
|
|
const link = document.createElement('a'); |
|
link.download = 'phone-design.png'; |
|
link.href = img.src; |
|
link.click(); |
|
document.getElementById('message-text').textContent = 'Design saved successfully!'; |
|
}); |
|
|
|
async function queryAPI(prompt) { |
|
const payload = { |
|
inputs: prompt, |
|
parameters: { |
|
negative_prompt: "(worst quality, low quality, lowres, oversaturated, grayscale, bad photo:1.4)", |
|
num_inference_steps: 30, |
|
scheduler: "DPMSolverMultistepScheduler", |
|
} |
|
}; |
|
|
|
let retries = 0; |
|
while (retries < 5) { |
|
const response = await fetch(API_URL, { |
|
method: 'POST', |
|
headers: { 'Content-Type': 'application/json' }, |
|
body: JSON.stringify(payload) |
|
}); |
|
|
|
if (response.ok) return await response.blob(); |
|
if (response.status === 503) { |
|
await new Promise(resolve => setTimeout(resolve, 1000)); |
|
retries++; |
|
} else { |
|
throw new Error(`API Error: ${response.status}`); |
|
} |
|
} |
|
throw new Error('Server busy, please try again later'); |
|
} |
|
|
|
function showLoading(show) { |
|
document.getElementById('loading').style.display = show ? 'flex' : 'none'; |
|
} |
|
|
|
function speakMessage(text) { |
|
const synth = window.speechSynthesis; |
|
const utterance = new SpeechSynthesisUtterance(text); |
|
synth.speak(utterance); |
|
} |
|
|
|
|
|
const gallery = document.getElementById('gallery'); |
|
['https://via.placeholder.com/300x500/FFB6C1/ffffff?text=Sample+1', |
|
'https://via.placeholder.com/300x500/87CEEB/ffffff?text=Sample+2', |
|
'https://via.placeholder.com/300x500/98FB98/ffffff?text=Sample+3', |
|
'https://via.placeholder.com/300x500/DDA0DD/ffffff?text=Sample+4'] |
|
.forEach(url => { |
|
gallery.innerHTML += ` |
|
<div class="gallery-item bg-white rounded-lg overflow-hidden"> |
|
<img src="${url}" class="w-full h-48 object-cover"> |
|
<div class="p-3 text-gray-700">Sample Design</div> |
|
</div> |
|
`; |
|
}); |
|
}); |
|
</script> |
|
</body> |
|
</html> |