Spaces:
Running
Running
<html> | |
<head> | |
<base href="https://websim.ai/clock-with-ai/"> | |
</base> | |
<title>AI-Powered Clock with Dynamic Backgrounds</title> | |
<style> | |
body { | |
background-color: #1a1a1a; | |
display: flex; | |
flex-direction: column; | |
justify-content: center; | |
align-items: center; | |
height: 100vh; | |
margin: 0; | |
font-family: Arial, sans-serif; | |
color: #00ff00; | |
transition: background-image 1s ease-in-out; | |
} | |
#clock { | |
font-weight: bold; | |
text-shadow: 0 0 10px currentColor; | |
z-index: 10; | |
} | |
#settings-btn { | |
position: fixed; | |
top: 10px; | |
right: 10px; | |
background: none; | |
border: none; | |
color: #00ff00; | |
font-size: 24px; | |
cursor: pointer; | |
z-index: 20; | |
} | |
#settings-panel { | |
position: fixed; | |
top: 50px; | |
right: 10px; | |
background: rgba(255, 255, 255, 0.9); | |
color: #000; | |
padding: 20px; | |
border-radius: 10px; | |
display: none; | |
z-index: 20; | |
max-width: 300px; | |
max-height: 80vh; | |
overflow-y: auto; | |
} | |
#token-input, | |
#prompt-input, | |
#clock-color-input, | |
#clock-size-input { | |
width: 100%; | |
margin-bottom: 10px; | |
} | |
.btn { | |
border: none; | |
color: white; | |
padding: 10px 20px; | |
text-align: center; | |
text-decoration: none; | |
display: inline-block; | |
font-size: 16px; | |
margin: 4px 2px; | |
cursor: pointer; | |
border-radius: 5px; | |
transition: background-color 0.3s; | |
} | |
#fullscreen-btn { | |
background-color: #4CAF50; | |
} | |
#fullscreen-btn:hover { | |
background-color: #45a049; | |
} | |
#save-settings { | |
background-color: #008CBA; | |
} | |
#save-settings:hover { | |
background-color: #007B9A; | |
} | |
#test-image { | |
background-color: #f44336; | |
} | |
#test-image:hover { | |
background-color: #da190b; | |
} | |
#reset-prompt { | |
background-color: #ff9800; | |
} | |
#reset-prompt:hover { | |
background-color: #e68a00; | |
} | |
#background-image { | |
position: fixed; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
object-fit: cover; | |
z-index: 1; | |
} | |
label { | |
display: block; | |
margin-top: 10px; | |
margin-bottom: 5px; | |
} | |
</style> | |
</head> | |
<body> | |
<img id="background-image" alt="AI generated abstract landscape based on current time" src=""> | |
<div id="clock"></div> | |
<button id="settings-btn">settings</button> | |
<div id="settings-panel"> | |
<label for="token-input">Hugging Face Token:</label> | |
<input type="password" id="token-input" placeholder="Enter Hugging Face token"> | |
<label for="prompt-input">Custom Prompt:</label> | |
<textarea id="prompt-input" rows="4" placeholder="Enter custom prompt (use {time} for current time)"></textarea> | |
<label for="clock-color-input">Clock Color:</label> | |
<input type="color" id="clock-color-input"> | |
<label for="clock-size-input">Clock Size (vw):</label> | |
<input type="range" id="clock-size-input" min="1" max="20" step="0.1"> | |
<span id="clock-size-value"></span> | |
<button id="fullscreen-btn" class="btn">Toggle Fullscreen</button> | |
<button id="save-settings" class="btn">Save</button> | |
<button id="test-image" class="btn">Test Image Generation</button> | |
<button id="reset-prompt" class="btn">Reset Prompt</button> | |
</div> | |
<script> | |
let hfToken = localStorage.getItem('hfToken') || ''; | |
let customPrompt = localStorage.getItem('customPrompt') || 'beautiful abstract landscape that suits the time {time}'; | |
const generationFrequency = 150; // 150 seconds | |
let clockColor = localStorage.getItem('clockColor') || '#00ff00'; | |
let clockSize = parseFloat(localStorage.getItem('clockSize')) || 8; | |
let imageGenerationInterval; | |
const DEFAULT_PROMPT = 'beautiful abstract landscape that suits the time {time}'; | |
function updateClock() { | |
const now = new Date(); | |
let hours = now.getHours(); | |
const minutes = now.getMinutes() | |
.toString() | |
.padStart(2, '0'); | |
const seconds = now.getSeconds() | |
.toString() | |
.padStart(2, '0'); | |
const ampm = hours >= 12 ? 'PM' : 'AM'; | |
hours = hours % 12; | |
hours = hours ? hours : 12; | |
hours = hours.toString() | |
.padStart(2, '0'); | |
const timeString = `${hours}:${minutes}:${seconds} ${ampm}`; | |
const clockElement = document.getElementById('clock'); | |
clockElement.textContent = timeString; | |
clockElement.style.color = clockColor; | |
clockElement.style.fontSize = `${clockSize}vw`; | |
return `${hours}:${minutes} ${ampm}`; | |
} | |
async function generateImage(prompt) { | |
if (!hfToken) return; | |
try { | |
const response = await fetch('https://api-inference.huggingface.co/models/black-forest-labs/FLUX.1-schnell', { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
'Authorization': `Bearer ${hfToken}` | |
}, | |
body: JSON.stringify({ | |
inputs: prompt | |
}) | |
}); | |
if (!response.ok) { | |
throw new Error('Failed to generate image'); | |
} | |
const blob = await response.blob(); | |
const imageUrl = URL.createObjectURL(blob); | |
const backgroundImage = document.getElementById('background-image'); | |
const newImage = new Image(); | |
newImage.onload = function() { | |
URL.revokeObjectURL(backgroundImage.src); | |
backgroundImage.src = this.src; | |
}; | |
newImage.src = imageUrl; | |
} catch (error) { | |
console.error('Error generating image:', error); | |
} | |
} | |
function updateBackgroundImage() { | |
const currentTime = updateClock() | |
.slice(0, -3); | |
const prompt = customPrompt.replace('{time}', currentTime); | |
generateImage(prompt); | |
} | |
function initializeSettings() { | |
document.getElementById('token-input') | |
.value = hfToken; | |
document.getElementById('prompt-input') | |
.value = customPrompt; | |
document.getElementById('clock-color-input') | |
.value = clockColor; | |
document.getElementById('clock-size-input') | |
.value = clockSize; | |
document.getElementById('clock-size-value') | |
.textContent = clockSize + ' vw'; | |
} | |
function toggleFullscreen() { | |
if (!document.fullscreenElement) { | |
document.documentElement.requestFullscreen() | |
.catch(err => console.error(err)); | |
} else { | |
if (document.exitFullscreen) { | |
document.exitFullscreen(); | |
} | |
} | |
} | |
function setupImageGenerationInterval() { | |
clearInterval(imageGenerationInterval); | |
imageGenerationInterval = setInterval(updateBackgroundImage, generationFrequency * 1000); | |
} | |
setInterval(updateClock, 1000); | |
setupImageGenerationInterval(); | |
updateClock(); | |
updateBackgroundImage(); | |
initializeSettings(); | |
document.getElementById('settings-btn') | |
.addEventListener('click', () => { | |
const panel = document.getElementById('settings-panel'); | |
panel.style.display = panel.style.display === 'none' ? 'block' : 'none'; | |
}); | |
document.getElementById('fullscreen-btn') | |
.addEventListener('click', toggleFullscreen); | |
document.getElementById('save-settings') | |
.addEventListener('click', () => { | |
hfToken = document.getElementById('token-input') | |
.value; | |
customPrompt = document.getElementById('prompt-input') | |
.value; | |
clockColor = document.getElementById('clock-color-input') | |
.value; | |
clockSize = parseFloat(document.getElementById('clock-size-input') | |
.value); | |
localStorage.setItem('hfToken', hfToken); | |
localStorage.setItem('customPrompt', customPrompt); | |
localStorage.setItem('clockColor', clockColor); | |
localStorage.setItem('clockSize', clockSize); | |
document.getElementById('settings-panel') | |
.style.display = 'none'; | |
updateBackgroundImage(); | |
setupImageGenerationInterval(); | |
updateClock(); | |
}); | |
document.getElementById('test-image') | |
.addEventListener('click', () => { | |
updateBackgroundImage(); | |
}); | |
document.getElementById('reset-prompt') | |
.addEventListener('click', () => { | |
customPrompt = DEFAULT_PROMPT; | |
document.getElementById('prompt-input') | |
.value = customPrompt; | |
}); | |
document.getElementById('clock-size-input') | |
.addEventListener('input', (e) => { | |
const value = e.target.value; | |
document.getElementById('clock-size-value') | |
.textContent = value + ' vw'; | |
clockSize = parseFloat(value); | |
updateClock(); | |
}); | |
document.getElementById('clock-color-input') | |
.addEventListener('input', (e) => { | |
clockColor = e.target.value; | |
updateClock(); | |
}); | |
document.addEventListener('DOMContentLoaded', () => { | |
const settingsBtn = document.getElementById('settings-btn'); | |
const newSettingsBtn = settingsBtn.cloneNode(true); | |
settingsBtn.parentNode.replaceChild(newSettingsBtn, settingsBtn); | |
newSettingsBtn.addEventListener('click', () => { | |
const panel = document.getElementById('settings-panel'); | |
panel.style.display = panel.style.display === 'none' ? 'block' : 'none'; | |
}); | |
}); | |
</script> | |
</body> | |
</html> |