Here's a **"Fractal Web Explorer"** that organizes websites in an infinitely zoomable fractal structure, where each branch reveals new related sites in a mesmerizing visual interface:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fractal Web Explorer</title>
<style>
body {
margin: 0;
overflow: hidden;
background: #000;
font-family: 'Arial', sans-serif;
}
#fractalCanvas {
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
.fractal-node {
position: absolute;
width: 80px;
height: 80px;
border-radius: 50%;
background: radial-gradient(circle at 30% 30%, #ff2d75, #7e00ff);
box-shadow: 0 0 30px rgba(255, 45, 117, 0.7);
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 12px;
text-align: center;
cursor: pointer;
z-index: 2;
transition: all 0.3s;
overflow: hidden;
transform-origin: center;
}
.fractal-node.active {
box-shadow: 0 0 60px rgba(0, 255, 200, 0.9);
transform: scale(1.2);
z-index: 3;
}
.fractal-node .iframe-wrapper {
width: 100%;
height: 100%;
border-radius: 50%;
overflow: hidden;
opacity: 0.4;
transition: opacity 0.3s;
}
.fractal-node.active .iframe-wrapper {
opacity: 0.8;
}
.fractal-node iframe {
width: 100%;
height: 100%;
border: none;
pointer-events: none;
}
.fractal-node .node-label {
position: absolute;
bottom: -25px;
left: 0;
right: 0;
color: #0cf;
text-align: center;
font-size: 11px;
text-shadow: 0 0 5px #000;
white-space: nowrap;
}
#mainDisplay {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80vw;
height: 70vh;
background: rgba(10, 5, 20, 0.95);
border-radius: 20px;
box-shadow: 0 0 60px rgba(126, 0, 255, 0.7);
z-index: 10;
display: none;
flex-direction: column;
overflow: hidden;
border: 1px solid rgba(255, 45, 117, 0.5);
}
#mainDisplay.active {
display: flex;
}
#mainIframe {
flex: 1;
border: none;
background: #000;
}
#displayTitle {
padding: 15px;
background: linear-gradient(to right, #7e00ff, #ff2d75);
color: white;
text-align: center;
font-size: 16px;
letter-spacing: 1px;
}
#controls {
position: fixed;
bottom: 30px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 20px;
z-index: 20;
}
.control-btn {
width: 60px;
height: 60px;
border-radius: 50%;
background: rgba(30, 0, 60, 0.8);
border: 1px solid #ff2d75;
color: #ff7eb9;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-size: 24px;
box-shadow: 0 0 20px rgba(255, 45, 117, 0.5);
transition: all 0.3s;
}
.control-btn:hover {
background: rgba(126, 0, 255, 0.8);
transform: scale(1.1);
}
#zoomInfo {
position: fixed;
top: 20px;
left: 20px;
color: white;
background: rgba(0, 0, 0, 0.5);
padding: 10px;
border-radius: 5px;
z-index: 20;
font-size: 12px;
}
.fractal-connection {
position: absolute;
height: 2px;
background: linear-gradient(to right, rgba(255, 45, 117, 0.3), rgba(126, 0, 255, 0.7));
transform-origin: 0 0;
z-index: 1;
}
#particles {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0;
}
@keyframes float {
0%, 100% { transform: translateY(0) scale(1); }
50% { transform: translateY(-10px) scale(1.05); }
}
</style>
</head>
<body>
<canvas id="fractalCanvas"></canvas>
<canvas id="particles"></canvas>
<div id="nodesContainer">
<!-- Fractal nodes will be added by JavaScript -->
</div>
<div id="connectionsContainer">
<!-- Fractal connections will be added by JavaScript -->
</div>
<div id="mainDisplay">
<div id="displayTitle">Fractal Web Explorer</div>
<iframe id="mainIframe" sandbox="allow-same-origin allow-scripts allow-popups allow-forms"></iframe>
</div>
<div id="controls">
<div class="control-btn" id="zoomInBtn">+</div>
<div class="control-btn" id="zoomOutBtn">-</div>
<div class="control-btn" id="recenterBtn">⊙</div>
</div>
<div id="zoomInfo">
Zoom: <span id="zoomLevel">100%</span> |
Nodes: <span id="nodeCount">0</span> |
Depth: <span id="fractalDepth">0</span>
</div>
<script>
// Fractal parameters
const BRANCH_FACTOR = 3;
const MAX_DEPTH = 5;
const INITIAL_SCALE = 1;
const ZOOM_FACTOR = 0.8;
// Sites data
const sites = [
{ url: 'https://advertica13.blogspot.com/', title: 'Advertica 13', category: 'tech' },
{ url: 'https://advertica12.blogspot.com/', title: 'Advertica 12', category: 'tech' },
{ url: 'https://advertica08.blogspot.com/', title: 'Advertica 08', category: 'tech' },
{ url: 'https://advertica07.blogspot.com/', title: 'Advertica 07', category: 'tech' },
{ url: 'https://www.softmod.shop/', title: 'Softmod Shop', category: 'shop' },
{ url: 'https://advertica06.blogspot.com/', title: 'Advertica 06', category: 'tech' },
{ url: 'https://advertica18.blogspot.com/', title: 'Advertica 18', category: 'tech' },
{ url: 'https://advertica19.blogspot.com/', title: 'Advertica 19', category: 'tech' },
{ url: 'https://example.com/news', title: 'News Portal', category: 'news' },
{ url: 'https://example.com/blog', title: 'Tech Blog', category: 'blog' }
];
// DOM elements
const fractalCanvas = document.getElementById('fractalCanvas');
const ctx = fractalCanvas.getContext('2d');
const particlesCanvas = document.getElementById('particles');
const particlesCtx = particlesCanvas.getContext('2d');
const nodesContainer = document.getElementById('nodesContainer');
const connectionsContainer = document.getElementById('connectionsContainer');
const mainDisplay = document.getElementById('mainDisplay');
const mainIframe = document.getElementById('mainIframe');
const displayTitle = document.getElementById('displayTitle');
const zoomInBtn = document.getElementById('zoomInBtn');
const zoomOutBtn = document.getElementById('zoomOutBtn');
const recenterBtn = document.getElementById('recenterBtn');
const zoomLevel = document.getElementById('zoomLevel');
const nodeCount = document.getElementById('nodeCount');
const fractalDepth = document.getElementById('fractalDepth');
// Fractal state
let nodes = [];
let connections = [];
let activeNode = null;
let transform = {
x: window.innerWidth / 2,
y: window.innerHeight / 2,
scale: INITIAL_SCALE,
depth: 0
};
let isDragging = false;
let lastX, lastY;
let particles = [];
// Canvas setup
fractalCanvas.width = window.innerWidth;
fractalCanvas.height = window.innerHeight;
particlesCanvas.width = window.innerWidth;
particlesCanvas.height = window.innerHeight;
// Fractal node class
class FractalNode {
constructor(id, x, y, depth, parentId, url, title) {
this.id = id;
this.x = x;
this.y = y;
this.depth = depth;
this.parentId = parentId;
this.url = url;
this.title = title;
this.children = [];
this.element = this.createDOMElement();
this.updatePosition();
}
createDOMElement() {
const el = document.createElement('div');
el.className = 'fractal-node';
el.id = `node-${this.id}`;
el.innerHTML = `
<div class="iframe-wrapper">
<iframe src="${this.url}"
sandbox="allow-same-origin allow-scripts allow-popups allow-forms"></iframe>
</div>
<div class="node-label">${this.title}</div>
`;
el.addEventListener('click', (e) => {
e.stopPropagation();
this.activate();
});
nodesContainer.appendChild(el);
return el;
}
updatePosition() {
const scaledX = this.x * transform.scale + transform.x;
const scaledY = this.y * transform.scale + transform.y;
const scaledSize = 80 * transform.scale;
this.element.style.width = `${scaledSize}px`;
this.element.style.height = `${scaledSize}px`;
this.element.style.left = `${scaledX - scaledSize/2}px`;
this.element.style.top = `${scaledY - scaledSize/2}px`;
// Adjust font size based on zoom
const label = this.element.querySelector('.node-label');
if (label) {
label.style.fontSize = `${Math.max(8, 11 * transform.scale)}px`;
label.style.bottom = `${-25 * transform.scale}px`;
}
}
activate() {
// Show in main display
mainIframe.src = this.url;
displayTitle.textContent = this.title;
mainDisplay.classList.add('active');
// Visual activation
nodes.forEach(n => n.element.classList.remove('active'));
this.element.classList.add('active');
activeNode = this;
// Center view on this node
transform.x = window.innerWidth/2 - this.x * transform.scale;
transform.y = window.innerHeight/2 - this.y * transform.scale;
updateAllPositions();
// If this node has children, they're already visible
// If not, generate children
if (this.children.length === 0 && this.depth < MAX_DEPTH) {
this.generateChildren();
}
}
generateChildren() {
const angleStep = (Math.PI * 2) / BRANCH_FACTOR;
const distance = 200 / Math.pow(1.5, this.depth);
for (let i = 0; i < BRANCH_FACTOR; i++) {
const angle = angleStep * i + (Math.random() - 0.5) * angleStep * 0.5;
const x = this.x + Math.cos(angle) * distance;
const y = this.y + Math.sin(angle) * distance;
// Find a site that matches category or random
const parentSite = sites.find(s => s.url === this.url);
let childSite;
if (parentSite && parentSite.category) {
const sameCategory = sites.filter(s => s.category === parentSite.category);
childSite = sameCategory[Math.floor(Math.random() * sameCategory.length)];
} else {
childSite = sites[Math.floor(Math.random() * sites.length)];
}
const newNode = new FractalNode(
nodes.length,
x,
y,
this.depth + 1,
this.id,
childSite.url,
childSite.title
);
nodes.push(newNode);
this.children.push(newNode.id);
// Create connection
const connection = new FractalConnection(
connections.length,
this.id,
newNode.id
);
connections.push(connection);
}
updateStats();
}
}
// Fractal connection class
class FractalConnection {
constructor(id, fromId, toId) {
this.id = id;
this.fromId = fromId;
this.toId = toId;
this.element = this.createDOMElement();
this.updatePosition();
}
createDOMElement() {
const el = document.createElement('div');
el.className = 'fractal-connection';
el.id = `connection-${this.id}`;
connectionsContainer.appendChild(el);
return el;
}
updatePosition() {
const fromNode = nodes.find(n => n.id === this.fromId);
const toNode = nodes.find(n => n.id === this.toId);
if (fromNode && toNode) {
const fromX = fromNode.x * transform.scale + transform.x;
const fromY = fromNode.y * transform.scale + transform.y;
const toX = toNode.x * transform.scale + transform.x;
const toY = toNode.y * transform.scale + transform.y;
const dx = toX - fromX;
const dy = toY - fromY;
const length = Math.sqrt(dx * dx + dy * dy);
const angle = Math.atan2(dy, dx);
this.element.style.width = `${length}px`;
this.element.style.left = `${fromX}px`;
this.element.style.top = `${fromY}px`;
this.element.style.transform = `rotate(${angle}rad)`;
this.element.style.opacity = Math.min(1, 0.3 + 0.7 / transform.scale);
}
}
}
// Initialize fractal
function initFractal() {
clearFractal();
// Create root node
const rootSite = sites[Math.floor(Math.random() * sites.length)];
const rootNode = new FractalNode(
0,
0,
0,
0,
null,
rootSite.url,
rootSite.title
);
nodes.push(rootNode);
rootNode.activate();
updateStats();
}
// Clear all fractal elements
function clearFractal() {
nodesContainer.innerHTML = '';
connectionsContainer.innerHTML = '';
nodes = [];
connections = [];
activeNode = null;
}
// Update all node and connection positions
function updateAllPositions() {
nodes.forEach(node => node.updatePosition());
connections.forEach(conn => conn.updatePosition());
zoomLevel.textContent = `${Math.round(transform.scale * 100)}%`;
}
// Update statistics
function updateStats() {
nodeCount.textContent = nodes.length;
fractalDepth.textContent = transform.depth;
}
// Handle zoom
function zoom(zoomFactor, centerX, centerY) {
const newScale = transform.scale * zoomFactor;
// Limit zoom levels
if (newScale < 0.1 || newScale > 10) return;
// Calculate new transform
transform.x = centerX - (centerX - transform.x) * zoomFactor;
transform.y = centerY - (centerY - transform.y) * zoomFactor;
transform.scale = newScale;
// Adjust depth level based on zoom
transform.depth = Math.floor(Math.log(1/transform.scale) / Math.log(1/ZOOM_FACTOR));
updateAllPositions();
updateStats();
}
// Recenter view
function recenterView() {
if (activeNode) {
transform.x = window.innerWidth/2 - activeNode.x * transform.scale;
transform.y = window.innerHeight/2 - activeNode.y * transform.scale;
} else {
transform.x = window.innerWidth/2;
transform.y = window.innerHeight/2;
transform.scale = INITIAL_SCALE;
transform.depth = 0;
}
updateAllPositions();
updateStats();
}
// Initialize particles
function initParticles() {
for (let i = 0; i < 100; i++) {
particles.push({
x: Math.random() * particlesCanvas.width,
y: Math.random() * particlesCanvas.height,
size: Math.random() * 3 + 1,
speed: Math.random() * 2 + 0.5,
color: `rgba(${Math.floor(255 * Math.random())}, ${Math.floor(255 * Math.random())}, 255, ${Math.random() * 0.2 + 0.1})`
});
}
animateParticles();
}
// Animate particles
function animateParticles() {
particlesCtx.clearRect(0, 0, particlesCanvas.width, particlesCanvas.height);
particles.forEach(p => {
p.y -= p.speed;
if (p.y < 0) {
p.y = particlesCanvas.height;
p.x = Math.random() * particlesCanvas.width;
}
particlesCtx.fillStyle = p.color;
particlesCtx.beginPath();
particlesCtx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
particlesCtx.fill();
});
requestAnimationFrame(animateParticles);
}
// Event listeners
zoomInBtn.addEventListener('click', () => {
zoom(ZOOM_FACTOR, window.innerWidth/2, window.innerHeight/2);
});
zoomOutBtn.addEventListener('click', () => {
zoom(1/ZOOM_FACTOR, window.innerWidth/2, window.innerHeight/2);
});
recenterBtn.addEventListener('click', recenterView);
// Canvas drag to pan
fractalCanvas.addEventListener('mousedown', (e) => {
isDragging = true;
lastX = e.clientX;
lastY = e.clientY;
});
window.addEventListener('mousemove', (e) => {
if (isDragging) {
transform.x += e.clientX - lastX;
transform.y += e.clientY - lastY;
lastX = e.clientX;
lastY = e.clientY;
updateAllPositions();
}
});
window.addEventListener('mouseup', () => {
isDragging = false;
});
// Mouse wheel to zoom
fractalCanvas.addEventListener('wheel', (e) => {
e.preventDefault();
const zoomFactor = e.deltaY > 0 ? 1/ZOOM_FACTOR : ZOOM_FACTOR;
zoom(zoomFactor, e.clientX, e.clientY);
});
// Close main display when clicking outside
document.addEventListener('click', (e) => {
if (!mainDisplay.contains(e.target)) {
mainDisplay.classList.remove('active');
nodes.forEach(node => {
node.element.classList.remove('active');
});
activeNode = null;
}
});
// Handle window resize
window.addEventListener('resize', () => {
fractalCanvas.width = window.innerWidth;
fractalCanvas.height = window.innerHeight;
particlesCanvas.width = window.innerWidth;
particlesCanvas.height = window.innerHeight;
recenterView();
});
// Initialize
initFractal();
initParticles();
</script>
</body>
</html>
```
### Key Features of This Fractal Web Explorer:
1. **Infinite Fractal Structure**:
- Websites organized in an infinitely zoomable fractal pattern
- Each node branches into related sites
- Depth-based organization with automatic categorization
2. **Immersive Navigation**:
- Smooth zooming and panning through the fractal space
- Click any node to view its website in the main display
- Automatic generation of related sites as you explore deeper
3. **Visual Effects**:
- Glowing fractal nodes with live website previews
- Dynamic connections that adjust with zoom level
- Floating particle background for depth perception
- Smooth animations during navigation
4. **Interactive Controls**:
- Zoom in/out buttons
- Recenter view button
- Mouse wheel zooming
- Click-and-drag panning
5. **Contextual Organization**:
- Sites automatically grouped by category
- Related sites appear near each other in the fractal
- Depth level indicators
6. **Responsive Design**:
- Adapts to window resizing
- Dynamic scaling of all elements
- Touch-friendly controls (would need additional touch event handlers)
This implementation creates a completely unique way to explore the web, where sites aren't just linked but organized in a spatial, infinitely deep structure. The fractal metaphor provides an intuitive way to discover related content by "zooming in" to topics.
Additional features you could add:
- Search functionality to find specific sites
- Custom site addition form
- Save/load favorite fractal configurations
- Different fractal generation algorithms
- More advanced category-based organization
- Sound effects for navigation actions