Monarth's picture
Create script.js
ec18068 verified
// --- CONFIGURATION & STATE ---
const config = {
localApiUrl: localStorage.getItem('motif_api_url') || null,
};
// --- DOM ELEMENTS ---
const modal = document.getElementById('guide-modal');
const showGuideBtn = document.getElementById('show-guide');
const closeModalBtn = document.querySelector('.close-modal');
const saveConnectionBtn = document.getElementById('save-connection');
const apiUrlInput = document.getElementById('api-url');
const navItems = document.querySelectorAll('.nav-item');
const sections = document.querySelectorAll('main section');
// --- STARTUP BEHAVIOR ---
document.addEventListener('DOMContentLoaded', () => {
// 1. Mandatory Setup Guide - Show popup if no API is saved
if (!config.localApiUrl) {
openModal();
} else {
apiUrlInput.value = config.localApiUrl;
}
// 2. Initialize Cool Cursor Trail Effect
initializeCursorTrail();
});
// --- UI / NAVIGATION HANDLERS ---
navItems.forEach(item => {
item.addEventListener('click', (e) => {
// Handle Sidebar active state
navItems.forEach(nav => nav.classList.remove('active'));
item.classList.add('active');
// Handle Main Section visibility (Scrolling effect control)
const targetSectionId = item.getAttribute('data-target');
sections.forEach(sec => sec.classList.remove('active-section'));
document.getElementById(targetSectionId).classList.add('active-section');
});
});
// --- MODAL / CONNECTION GUIDE LOGIC ---
function openModal() { modal.classList.add('active-modal'); }
function closeModal() { modal.classList.remove('active-modal'); }
showGuideBtn.addEventListener('click', openModal);
closeModalBtn.addEventListener('click', closeModal);
modal.addEventListener('click', (e) => {
// Close if clicking overlay area outside the content box
if (e.target === modal) closeModal();
});
saveConnectionBtn.addEventListener('click', () => {
const enteredUrl = apiUrlInput.value.trim();
if (enteredUrl) {
localStorage.setItem('motif_api_url', enteredUrl);
config.localApiUrl = enteredUrl;
closeModal();
alert(`Setup Complete! 🦄 Portal connected to backend at: ${enteredUrl}`);
} else {
alert('Please enter your local API address (e.g., http://localhost:7860)');
}
});
// --- COOL MOUSE EFFECTS (PASTEL CURSOR TRAIL) ---
function initializeCursorTrail() {
const trailContainer = document.getElementById('cursor-trail');
const dots = [];
const numDots = 12;
// Create dots with alternating pastel colors
for (let i = 0; i < numDots; i++) {
const dot = document.createElement('div');
dot.className = 'trail-dot';
dot.style.backgroundColor = getPastelColor(i);
trailContainer.appendChild(dot);
dots.push({ element: dot, x: 0, y: 0 });
}
let mouseX = 0, mouseY = 0;
window.addEventListener('mousemove', (e) => {
mouseX = e.clientX;
mouseY = e.clientY;
});
// Animation loop for dots lagging smoothly behind cursor
function animateTrail() {
let x = mouseX;
let y = mouseY;
dots.forEach((dot, index) => {
const nextDot = dots[index + 1] || dots[0];
dot.x = x;
dot.y = y;
dot.element.style.left = x + 'px';
dot.element.style.top = y + 'px';
dot.element.style.opacity = 1 - (index / numDots); // Trail fades out
// Apply smooth lag effect
x += (nextDot.x - x) * 0.3;
y += (nextDot.y - y) * 0.3;
});
requestAnimationFrame(animateTrail);
}
animateTrail();
}
function getPastelColor(index) {
const colors = ['#ffe6d9', '#d6eaff', '#fbe0e6', '#e1f7f1']; // Peach, Blue, Pink, Mint
return colors[index % colors.length];
}
// --- GENERATION LOGIC (CONNECTION PLACEHOLDER) ---
const generateButtons = document.querySelectorAll('.generate-btn');
generateButtons.forEach(btn => {
btn.addEventListener('click', handleGeneration);
});
async function handleGeneration(e) {
if (!config.localApiUrl) {
alert("Wait! 🛑 To keep this portal unlimited and free, you must connect to your own powerful local computer first. Click 'Connection Guide'.");
openModal();
return;
}
const outputArea = document.getElementById('video-output');
// Add loading animation and swell effect
outputArea.innerHTML = '<span class="status-text">Connecting to local GPU...</span><div class="loading-spinner"></div>';
outputArea.closest('.animated-frame').classList.add('generating-active');
// PLACEHOLDER GENERATION SIMULATION
// In a real application, you would send a POST request to ${config.localApiUrl} here.
console.log(`Sending generation request to local backend: ${config.localApiUrl}`);
// Simulate backend processing time (4 seconds)
setTimeout(() => {
outputArea.innerHTML = ''; // Clear status spinner
// Use placeholder output from model card
const video = document.createElement('video');
video.src = 'https://huggingface.co/Motif-Technologies/Motif-Video-2B/resolve/main/assets/banner.mp4';
video.autoplay = true;
video.loop = true;
video.controls = true;
video.style.width = '100%';
outputArea.appendChild(video);
outputArea.closest('.animated-frame').classList.remove('generating-active');
}, 4000);
}