simpleverso's picture
I cant see the camera now
097981a verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Visionary Collage Creator</title>
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
<script src="https://unpkg.com/feather-icons"></script>
<script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@3.11.0/dist/tf.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/coco-ssd@2.1.0/dist/coco-ssd.min.js"></script>
<style>
.collage-item {
transition: all 0.3s ease;
position: relative;
}
.collage-item:hover {
transform: scale(1.05);
z-index: 10;
}
.camera-container {
border-radius: 12px;
overflow: hidden;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
}
.collage-container {
min-height: 400px;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border-radius: 16px;
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
border: 1px solid rgba(255, 255, 255, 0.3);
overflow: hidden;
}
.pulse {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.4); }
70% { box-shadow: 0 0 0 10px rgba(59, 130, 246, 0); }
100% { box-shadow: 0 0 0 0 rgba(59, 130, 246, 0); }
}
.floating {
animation: floating 3s ease-in-out infinite;
}
@keyframes floating {
0% { transform: translateY(0px); }
50% { transform: translateY(-10px); }
100% { transform: translateY(0px); }
}
.swaying {
animation: swaying 4s ease-in-out infinite;
}
@keyframes swaying {
0% { transform: rotate(0deg); }
50% { transform: rotate(3deg); }
100% { transform: rotate(0deg); }
}
.rotating {
animation: rotating 8s linear infinite;
}
@keyframes rotating {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.bounce {
animation: bounce 2s infinite;
}
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-15px); }
}
</style>
</head>
<body class="bg-gradient-to-br from-gray-900 to-blue-900 min-h-screen text-white">
<!-- Background Animation -->
<div id="vanta-bg" class="fixed top-0 left-0 w-full h-full -z-10"></div>
<!-- Header -->
<header class="container mx-auto px-4 py-8">
<div class="flex flex-col md:flex-row justify-between items-center">
<div class="flex items-center mb-6 md:mb-0">
<i data-feather="camera" class="mr-3 text-blue-400" size="32"></i>
<h1 class="text-3xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-blue-400 to-purple-500">
Visionary Collage Creator
</h1>
</div>
<div class="flex space-x-4">
<button id="start-camera" class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-full flex items-center transition-all">
<i data-feather="video" class="mr-2"></i> Start Camera
</button>
<button id="capture-btn" class="bg-purple-600 hover:bg-purple-700 text-white px-6 py-2 rounded-full flex items-center transition-all pulse">
<i data-feather="camera" class="mr-2"></i> Capture
</button>
</div>
</div>
</header>
<main class="container mx-auto px-4 py-8">
<!-- Camera Section as a button -->
<div class="flex justify-center mb-8">
<button id="camera-toggle" class="camera-container bg-black/30 p-6 rounded-2xl flex flex-col items-center cursor-pointer transition-all hover:bg-black/50">
<i data-feather="camera" class="mb-2 text-blue-400" size="32"></i>
<span class="text-lg font-semibold">Open Camera</span>
</button>
</div>
<!-- Camera View (Hidden by default) -->
<div id="camera-view" class="hidden flex justify-center mb-8">
<div class="camera-container relative">
<video id="video" autoplay playsinline class="w-full max-w-2xl rounded-lg"></video>
<div id="loading" class="absolute inset-0 bg-black/70 flex items-center justify-center hidden">
<div class="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-blue-500"></div>
</div>
</div>
</div>
<!-- Prediction Display -->
<div class="text-center mb-8">
<p id="prediction-text" class="text-lg">Point your camera at an object and capture to begin</p>
</div>
<!-- Collage Section in the center -->
<div class="collage-container p-6 rounded-2xl">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-semibold flex items-center">
<i data-feather="grid" class="mr-2 text-purple-400"></i> Dynamic Collage
</h2>
<button id="clear-collage" class="text-sm bg-red-600 hover:bg-red-700 px-3 py-1 rounded-full flex items-center">
<i data-feather="trash-2" class="mr-1" size="16"></i> Clear
</button>
</div>
<div id="collage" class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 gap-4">
<div class="col-span-full text-center py-12 text-gray-400">
<i data-feather="image" class="mb-2" size="48"></i>
<p>Capture an image to start building your collage</p>
</div>
</div>
</div>
<!-- How it works section -->
<section class="mt-16 bg-black/20 backdrop-blur-sm rounded-2xl p-8">
<h2 class="text-2xl font-bold text-center mb-8">How It Works</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
<div class="text-center p-6 bg-white/5 rounded-xl">
<div class="w-16 h-16 bg-blue-500 rounded-full flex items-center justify-center mx-auto mb-4">
<i data-feather="camera" size="24"></i>
</div>
<h3 class="text-xl font-semibold mb-2">Capture Image</h3>
<p class="text-gray-300">Point your camera at any object and capture an image with one click</p>
</div>
<div class="text-center p-6 bg-white/5 rounded-xl">
<div class="w-16 h-16 bg-purple-500 rounded-full flex items-center justify-center mx-auto mb-4">
<i data-feather="cpu" size="24"></i>
</div>
<h3 class="text-xl font-semibold mb-2">AI Detection</h3>
<p class="text-gray-300">Our ML model identifies the object and finds related images</p>
</div>
<div class="text-center p-6 bg-white/5 rounded-xl">
<div class="w-16 h-16 bg-green-500 rounded-full flex items-center justify-center mx-auto mb-4">
<i data-feather="layout" size="24"></i>
</div>
<h3 class="text-xl font-semibold mb-2">Dynamic Collage</h3>
<p class="text-gray-300">Related images are automatically added to your personalized collage</p>
</div>
</div>
</section>
</main>
<footer class="container mx-auto px-4 py-8 mt-12 text-center text-gray-400">
<p>Visionary Collage Creator &copy; 2023 | Powered by Machine Learning</p>
</footer>
<script>
// Initialize Feather Icons
feather.replace();
// Initialize Vanta.js background
VANTA.GLOBE({
el: "#vanta-bg",
mouseControls: true,
touchControls: true,
gyroControls: false,
minHeight: 200.00,
minWidth: 200.00,
scale: 1.00,
scaleMobile: 1.00,
color: 0x3b82f6,
color2: 0x8b5cf6,
backgroundColor: 0x0f172a
});
// DOM Elements
const video = document.getElementById('video');
const startCameraBtn = document.getElementById('start-camera');
const captureBtn = document.getElementById('capture-btn');
const predictionText = document.getElementById('prediction-text');
const collage = document.getElementById('collage');
const loading = document.getElementById('loading');
const clearCollageBtn = document.getElementById('clear-collage');
const cameraToggle = document.getElementById('camera-toggle');
// Camera setup
let stream = null;
// Toggle camera view
cameraToggle.addEventListener('click', async () => {
const cameraView = document.getElementById('camera-view');
if (cameraView.classList.contains('hidden')) {
// Open camera
try {
stream = await navigator.mediaDevices.getUserMedia({ video: true });
video.srcObject = stream;
cameraView.classList.remove('hidden');
cameraToggle.innerHTML = '<i data-feather="x" class="mb-2 text-blue-400" size="32"></i><span class="text-lg font-semibold">Close Camera</span>';
feather.replace();
} catch (err) {
console.error("Error accessing camera:", err);
predictionText.textContent = "Error accessing camera. Please check permissions.";
predictionText.classList.add('text-red-400');
}
} else {
// Close camera
if (stream) {
stream.getTracks().forEach(track => track.stop());
stream = null;
}
video.srcObject = null;
cameraView.classList.add('hidden');
cameraToggle.innerHTML = '<i data-feather="camera" class="mb-2 text-blue-400" size="32"></i><span class="text-lg font-semibold">Open Camera</span>';
feather.replace();
}
});
// Load COCO-SSD model
let model;
cocoSsd.load().then(loadedModel => {
model = loadedModel;
console.log("COCO-SSD model loaded");
}).catch(err => {
console.error("Error loading model:", err);
predictionText.textContent = "Failed to load detection model";
predictionText.classList.add('text-red-400');
});
// Capture image and process with ResNet (COCO-SSD)
captureBtn.addEventListener('click', async () => {
if (!stream) {
predictionText.textContent = "Please open the camera first";
predictionText.classList.add('text-yellow-400');
return;
}
if (!model) {
predictionText.textContent = "Model is still loading...";
predictionText.classList.add('text-yellow-400');
return;
}
loading.classList.remove('hidden');
captureBtn.classList.add('opacity-50', 'cursor-not-allowed');
try {
// Create canvas to capture frame
const canvas = document.createElement('canvas');
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
const ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
// Run detection
const predictions = await model.detect(canvas);
if (predictions.length > 0) {
// Get the highest confidence prediction
const topPrediction = predictions[0];
const detectedObject = topPrediction.class;
predictionText.textContent = `Detected: ${detectedObject} (${Math.round(topPrediction.score * 100)}% confidence)`;
predictionText.classList.remove('text-yellow-400', 'text-red-400');
predictionText.classList.add('text-green-400');
// Add to collage
addToCollage(detectedObject);
} else {
predictionText.textContent = "No objects detected. Try another image.";
predictionText.classList.remove('text-green-400', 'text-yellow-400');
predictionText.classList.add('text-red-400');
}
} catch (error) {
console.error("Detection error:", error);
predictionText.textContent = "Detection failed. Please try again.";
predictionText.classList.add('text-red-400');
} finally {
loading.classList.add('hidden');
captureBtn.classList.remove('opacity-50', 'cursor-not-allowed');
}
});
// Add multiple images to collage with dynamic movement
function addToCollage(object) {
// Remove placeholder if it exists
if (collage.children.length === 1 && collage.children[0].classList.contains('col-span-full')) {
collage.innerHTML = '';
}
// Add 12 similar images to the collage
for (let i = 0; i < 12; i++) {
// Create new collage item
const collageItem = document.createElement('div');
collageItem.className = 'collage-item rounded-lg overflow-hidden shadow-lg transform transition-transform hover:scale-105';
// Add random animation class
const animations = ['floating', 'swaying', 'rotating', 'bounce'];
const randomAnimation = animations[Math.floor(Math.random() * animations.length)];
collageItem.classList.add(randomAnimation);
// Generate random image based on object
const seed = Math.floor(Math.random() * 1000);
const imageUrl = `http://static.photos/${object}/320x240/${seed}`;
collageItem.innerHTML = `
<img src="${imageUrl}" alt="${object}" class="w-full h-32 object-cover">
<div class="p-2 bg-black/50 text-sm truncate">${object}</div>
`;
collage.appendChild(collageItem);
}
}
// Clear collage
clearCollageBtn.addEventListener('click', () => {
collage.innerHTML = `
<div class="col-span-full text-center py-12 text-gray-400">
<i data-feather="image" class="mb-2" size="48"></i>
<p>Capture an image to start building your collage</p>
</div>
`;
feather.replace();
});
</script>
</body>
</html>