AI-screensaver / index.html
Ivan000's picture
Update index.html
172c351 verified
raw
history blame
9.42 kB
<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>