Create a simple homepage that displays rotating and translating cubes that warp into eachother based on mouse movement
Browse files- cube-warp.js +148 -0
- index.html +15 -85
- style.css +12 -1
cube-warp.js
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class CubeWarp {
|
| 2 |
+
constructor() {
|
| 3 |
+
this.scene = new THREE.Scene();
|
| 4 |
+
this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
|
| 5 |
+
this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
|
| 6 |
+
|
| 7 |
+
this.cubes = [];
|
| 8 |
+
this.mouseX = 0;
|
| 9 |
+
this.mouseY = 0;
|
| 10 |
+
this.targetX = 0;
|
| 11 |
+
this.targetY = 0;
|
| 12 |
+
|
| 13 |
+
this.init();
|
| 14 |
+
this.animate();
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
init() {
|
| 18 |
+
// Setup renderer
|
| 19 |
+
this.renderer.setSize(window.innerWidth, window.innerHeight);
|
| 20 |
+
this.renderer.setClearColor(0x000000, 0);
|
| 21 |
+
document.getElementById('container').appendChild(this.renderer.domElement);
|
| 22 |
+
|
| 23 |
+
// Create multiple cubes with different colors and positions
|
| 24 |
+
const colors = [
|
| 25 |
+
0xff6b6b, 0x4ecdc4, 0x45b7d1, 0x96ceb4, 0xffeaa7,
|
| 26 |
+
0xdda0dd, 0x98d8c8, 0xf7dc6f, 0xbb8fce
|
| 27 |
+
];
|
| 28 |
+
|
| 29 |
+
for (let i = 0; i < 15; i++) {
|
| 30 |
+
const geometry = new THREE.BoxGeometry(2, 2, 2);
|
| 31 |
+
const material = new THREE.MeshPhongMaterial({
|
| 32 |
+
color: colors[i % colors.length],
|
| 33 |
+
transparent: true,
|
| 34 |
+
opacity: 0.8,
|
| 35 |
+
shininess: 100
|
| 36 |
+
});
|
| 37 |
+
|
| 38 |
+
const cube = new THREE.Mesh(geometry, material);
|
| 39 |
+
|
| 40 |
+
// Position cubes in a spherical arrangement
|
| 41 |
+
const radius = 8 + Math.random() * 4;
|
| 42 |
+
const theta = Math.random() * Math.PI * 2;
|
| 43 |
+
const phi = Math.acos((Math.random() * 2) - 1);
|
| 44 |
+
|
| 45 |
+
cube.position.x = radius * Math.sin(phi) * Math.cos(theta);
|
| 46 |
+
cube.position.y = radius * Math.sin(phi) * Math.sin(theta);
|
| 47 |
+
cube.position.z = radius * Math.cos(phi);
|
| 48 |
+
|
| 49 |
+
cube.userData = {
|
| 50 |
+
originalPosition: cube.position.clone(),
|
| 51 |
+
speed: 0.5 + Math.random() * 1.5,
|
| 52 |
+
rotationSpeed: {
|
| 53 |
+
x: (Math.random() - 0.5) * 0.02,
|
| 54 |
+
y: (Math.random() - 0.5) * 0.02,
|
| 55 |
+
z: (Math.random() - 0.5) * 0.02
|
| 56 |
+
},
|
| 57 |
+
warpFactor: 0
|
| 58 |
+
};
|
| 59 |
+
|
| 60 |
+
this.scene.add(cube);
|
| 61 |
+
this.cubes.push(cube);
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
// Add lights
|
| 65 |
+
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
|
| 66 |
+
this.scene.add(ambientLight);
|
| 67 |
+
|
| 68 |
+
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
|
| 69 |
+
directionalLight.position.set(5, 5, 5);
|
| 70 |
+
this.scene.add(directionalLight);
|
| 71 |
+
|
| 72 |
+
const pointLight = new THREE.PointLight(0x4ecdc4, 1, 100);
|
| 73 |
+
pointLight.position.set(-5, -5, -5);
|
| 74 |
+
this.scene.add(pointLight);
|
| 75 |
+
|
| 76 |
+
// Position camera
|
| 77 |
+
this.camera.position.z = 15;
|
| 78 |
+
|
| 79 |
+
// Mouse move event
|
| 80 |
+
document.addEventListener('mousemove', (event) => {
|
| 81 |
+
this.mouseX = (event.clientX / window.innerWidth) * 2 - 1;
|
| 82 |
+
this.mouseY = -(event.clientY / window.innerHeight) * 2 + 1;
|
| 83 |
+
});
|
| 84 |
+
|
| 85 |
+
// Window resize
|
| 86 |
+
window.addEventListener('resize', () => {
|
| 87 |
+
this.camera.aspect = window.innerWidth / window.innerHeight;
|
| 88 |
+
this.camera.updateProjectionMatrix();
|
| 89 |
+
this.renderer.setSize(window.innerWidth, window.innerHeight);
|
| 90 |
+
});
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
animate() {
|
| 94 |
+
requestAnimationFrame(() => this.animate());
|
| 95 |
+
|
| 96 |
+
// Smooth mouse movement
|
| 97 |
+
this.targetX += (this.mouseX - this.targetX) * 0.05;
|
| 98 |
+
this.targetY += (this.mouseY - this.targetY) * 0.05;
|
| 99 |
+
|
| 100 |
+
// Update cubes
|
| 101 |
+
this.cubes.forEach((cube, index) => {
|
| 102 |
+
const data = cube.userData;
|
| 103 |
+
|
| 104 |
+
// Calculate warp effect based on mouse position and cube distance
|
| 105 |
+
const distanceToCenter = cube.position.length();
|
| 106 |
+
const mouseDistance = Math.sqrt(this.targetX * this.targetX + this.targetY * this.targetY);
|
| 107 |
+
|
| 108 |
+
// Warp factor increases with mouse movement and proximity
|
| 109 |
+
data.warpFactor = Math.min(1, mouseDistance * 2 + (1 - distanceToCenter / 20));
|
| 110 |
+
|
| 111 |
+
// Rotation
|
| 112 |
+
cube.rotation.x += data.rotationSpeed.x * (1 + data.warpFactor * 2);
|
| 113 |
+
cube.rotation.y += data.rotationSpeed.y * (1 + data.warpFactor * 2);
|
| 114 |
+
cube.rotation.z += data.rotationSpeed.z * (1 + data.warpFactor * 2);
|
| 115 |
+
|
| 116 |
+
// Position warping - cubes move towards each other and distort
|
| 117 |
+
const time = Date.now() * 0.001;
|
| 118 |
+
const warpX = Math.sin(time + index) * data.warpFactor * 3;
|
| 119 |
+
const warpY = Math.cos(time + index * 0.7) * data.warpFactor * 3;
|
| 120 |
+
const warpZ = Math.sin(time * 0.5 + index * 0.3) * data.warpFactor * 3;
|
| 121 |
+
|
| 122 |
+
cube.position.x = data.originalPosition.x + warpX + this.targetX * 2;
|
| 123 |
+
cube.position.y = data.originalPosition.y + warpY + this.targetY * 2;
|
| 124 |
+
cube.position.z = data.originalPosition.z + warpZ;
|
| 125 |
+
|
| 126 |
+
// Scale warping
|
| 127 |
+
const scale = 1 + data.warpFactor * 0.5;
|
| 128 |
+
cube.scale.set(scale, scale, scale);
|
| 129 |
+
|
| 130 |
+
// Color intensity based on warp factor
|
| 131 |
+
cube.material.color.setHSL(
|
| 132 |
+
(index * 0.1 + time * 0.1) % 1,
|
| 133 |
+
0.8,
|
| 134 |
+
0.6 + data.warpFactor * 0.4
|
| 135 |
+
);
|
| 136 |
+
|
| 137 |
+
// Opacity pulsing
|
| 138 |
+
cube.material.opacity = 0.6 + Math.sin(time * 2 + index) * 0.2;
|
| 139 |
+
});
|
| 140 |
+
|
| 141 |
+
this.renderer.render(this.scene, this.camera);
|
| 142 |
+
}
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
// Initialize when page loads
|
| 146 |
+
window.addEventListener('load', () => {
|
| 147 |
+
new CubeWarp();
|
| 148 |
+
});
|
index.html
CHANGED
|
@@ -1,97 +1,27 @@
|
|
|
|
|
| 1 |
<!DOCTYPE html>
|
| 2 |
<html lang="en">
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8">
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
-
<title>
|
| 7 |
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
|
| 8 |
<link rel="stylesheet" href="style.css">
|
| 9 |
<script src="https://cdn.tailwindcss.com"></script>
|
| 10 |
-
<
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
theme: {
|
| 15 |
-
extend: {
|
| 16 |
-
colors: {
|
| 17 |
-
cyan: {
|
| 18 |
-
50: '#ecfeff',
|
| 19 |
-
100: '#cffafe',
|
| 20 |
-
200: '#a5f3fc',
|
| 21 |
-
300: '#67e8f9',
|
| 22 |
-
400: '#22d3ee',
|
| 23 |
-
500: '#06b6d4',
|
| 24 |
-
600: '#0891b2',
|
| 25 |
-
700: '#0e7490',
|
| 26 |
-
800: '#155e75',
|
| 27 |
-
900: '#164e63',
|
| 28 |
-
}
|
| 29 |
-
}
|
| 30 |
-
}
|
| 31 |
-
}
|
| 32 |
-
}
|
| 33 |
-
</script>
|
| 34 |
</head>
|
| 35 |
-
<body class="bg-
|
| 36 |
-
<
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
<
|
| 41 |
-
<section class="bg-white rounded-2xl shadow-xl p-8 mb-8 border border-cyan-200">
|
| 42 |
-
<div class="text-center mb-8">
|
| 43 |
-
<h1 class="text-4xl font-bold text-cyan-800 mb-4">CodeFingerprint Detective</h1>
|
| 44 |
-
<p class="text-cyan-600 text-lg">Upload multiple code files to detect their largest common similarities</p>
|
| 45 |
-
</div>
|
| 46 |
-
|
| 47 |
-
<div class="border-2 border-dashed border-cyan-300 rounded-xl p-8 text-center bg-cyan-50 transition-all duration-300 hover:border-cyan-400 hover:bg-cyan-100">
|
| 48 |
-
<i data-feather="upload-cloud" class="w-16 h-16 text-cyan-500 mx-auto mb-4"></i>
|
| 49 |
-
<input type="file" id="fileInput" multiple accept=".py,.js,.java,.cpp,.c,.html,.css,.txt,.md,.json,.xml" class="hidden">
|
| 50 |
-
<button id="uploadBtn" class="bg-cyan-500 hover:bg-cyan-600 text-white font-semibold py-3 px-8 rounded-lg transition-colors duration-300 flex items-center justify-center mx-auto">
|
| 51 |
-
<i data-feather="upload" class="w-5 h-5 mr-2"></i>
|
| 52 |
-
Choose Files to Analyze
|
| 53 |
-
</button>
|
| 54 |
-
<p class="text-cyan-600 mt-4 text-sm">Supported: Python, JavaScript, Java, C++, C, HTML, CSS, Text, Markdown, JSON, XML</p>
|
| 55 |
-
</div>
|
| 56 |
-
|
| 57 |
-
<div id="fileList" class="mt-6 space-y-3 hidden">
|
| 58 |
-
<h3 class="text-lg font-semibold text-cyan-800 mb-3">Selected Files:</h3>
|
| 59 |
-
<div id="fileItems" class="space-y-2"></div>
|
| 60 |
-
</div>
|
| 61 |
-
|
| 62 |
-
<div class="mt-6 text-center">
|
| 63 |
-
<button id="analyzeBtn" class="bg-gradient-to-r from-cyan-500 to-cyan-600 hover:from-cyan-600 hover:to-cyan-700 text-white font-bold py-4 px-12 rounded-xl transition-all duration-300 transform hover:scale-105 shadow-lg hidden">
|
| 64 |
-
<i data-feather="search" class="w-5 h-5 mr-2 inline"></i>
|
| 65 |
-
Analyze Common Patterns
|
| 66 |
-
</button>
|
| 67 |
-
</div>
|
| 68 |
-
</section>
|
| 69 |
-
|
| 70 |
-
<!-- Results Section -->
|
| 71 |
-
<section id="resultsSection" class="bg-white rounded-2xl shadow-xl p-8 border border-cyan-200 hidden">
|
| 72 |
-
<h2 class="text-3xl font-bold text-cyan-800 mb-6 text-center">Analysis Results</h2>
|
| 73 |
-
<div id="resultsContainer" class="space-y-6"></div>
|
| 74 |
-
</section>
|
| 75 |
-
|
| 76 |
-
<!-- Loading State -->
|
| 77 |
-
<div id="loadingState" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
|
| 78 |
-
<div class="bg-white rounded-2xl p-8 text-center max-w-md">
|
| 79 |
-
<div class="animate-spin rounded-full h-16 w-16 border-b-2 border-cyan-500 mx-auto mb-4"></div>
|
| 80 |
-
<h3 class="text-xl font-semibold text-cyan-800 mb-2">Analyzing Files</h3>
|
| 81 |
-
<p class="text-cyan-600">Detecting largest common similarities...</p>
|
| 82 |
-
</div>
|
| 83 |
-
</div>
|
| 84 |
</div>
|
| 85 |
-
</
|
| 86 |
-
|
| 87 |
-
<custom-footer></custom-footer>
|
| 88 |
|
| 89 |
-
<script src="
|
| 90 |
-
<script src="components/footer.js"></script>
|
| 91 |
-
<script src="script.js"></script>
|
| 92 |
-
<script>
|
| 93 |
-
feather.replace();
|
| 94 |
-
</script>
|
| 95 |
-
<script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
|
| 96 |
</body>
|
| 97 |
-
</html>
|
|
|
|
| 1 |
+
|
| 2 |
<!DOCTYPE html>
|
| 3 |
<html lang="en">
|
| 4 |
<head>
|
| 5 |
<meta charset="UTF-8">
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 7 |
+
<title>Cube Warp Homepage</title>
|
| 8 |
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
|
| 9 |
<link rel="stylesheet" href="style.css">
|
| 10 |
<script src="https://cdn.tailwindcss.com"></script>
|
| 11 |
+
<style>
|
| 12 |
+
body { margin: 0; padding: 0; overflow: hidden; }
|
| 13 |
+
canvas { display: block; }
|
| 14 |
+
</style>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
</head>
|
| 16 |
+
<body class="bg-black">
|
| 17 |
+
<div id="container"></div>
|
| 18 |
+
<div class="absolute top-0 left-0 w-full h-full flex items-center justify-center pointer-events-none">
|
| 19 |
+
<div class="text-center text-white">
|
| 20 |
+
<h1 class="text-6xl font-bold mb-4">Cube Warp</h1>
|
| 21 |
+
<p class="text-xl opacity-80">Move your mouse to warp the cubes</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
</div>
|
| 23 |
+
</div>
|
|
|
|
|
|
|
| 24 |
|
| 25 |
+
<script src="cube-warp.js"></script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
</body>
|
| 27 |
+
</html>
|
style.css
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
|
|
| 1 |
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600;700&family=Inter:wght@300;400;500;600;700&display=swap');
|
| 2 |
|
| 3 |
* {
|
| 4 |
font-family: 'Inter', sans-serif;
|
| 5 |
}
|
| 6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
.code-font {
|
| 8 |
font-family: 'JetBrains Mono', monospace;
|
| 9 |
}
|
|
@@ -48,4 +59,4 @@
|
|
| 48 |
.lcs-tag:hover {
|
| 49 |
transform: scale(1.05);
|
| 50 |
box-shadow: 0 4px 12px rgba(6, 182, 212, 0.3);
|
| 51 |
-
}
|
|
|
|
| 1 |
+
|
| 2 |
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600;700&family=Inter:wght@300;400;500;600;700&display=swap');
|
| 3 |
|
| 4 |
* {
|
| 5 |
font-family: 'Inter', sans-serif;
|
| 6 |
}
|
| 7 |
|
| 8 |
+
body {
|
| 9 |
+
margin: 0;
|
| 10 |
+
padding: 0;
|
| 11 |
+
overflow: hidden;
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
canvas {
|
| 15 |
+
display: block;
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
.code-font {
|
| 19 |
font-family: 'JetBrains Mono', monospace;
|
| 20 |
}
|
|
|
|
| 59 |
.lcs-tag:hover {
|
| 60 |
transform: scale(1.05);
|
| 61 |
box-shadow: 0 4px 12px rgba(6, 182, 212, 0.3);
|
| 62 |
+
}
|