Here's a **"Liquid Web Matrix"** interface where websites exist as shimmering droplets in a constantly flowing digital liquid that responds to your touch, merging and splitting in fluid dynamics simulations:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Liquid Web Matrix</title>
<style>
body {
margin: 0;
overflow: hidden;
background: #001f3f;
font-family: 'Arial', sans-serif;
}
#liquidCanvas {
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
.droplet {
position: absolute;
border-radius: 50%;
filter: drop-shadow(0 0 15px currentColor);
overflow: hidden;
cursor: pointer;
z-index: 2;
transition: transform 0.5s ease-out;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 10px;
text-align: center;
transform-origin: center;
}
.droplet.active {
filter: drop-shadow(0 0 30px gold);
z-index: 3;
transform: scale(1.3);
}
.droplet .iframe-container {
width: 100%;
height: 100%;
border-radius: 50%;
overflow: hidden;
opacity: 0.6;
transition: opacity 0.3s;
}
.droplet.active .iframe-container {
opacity: 0.9;
}
.droplet iframe {
width: 100%;
height: 100%;
border: none;
pointer-events: none;
}
.droplet .droplet-label {
position: absolute;
bottom: -25px;
left: 0;
right: 0;
color: #7FDBFF;
text-align: center;
font-size: 11px;
text-shadow: 0 0 5px #001f3f;
opacity: 0;
transition: opacity 0.3s;
}
.droplet:hover .droplet-label {
opacity: 1;
}
#mainInterface {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80vw;
height: 70vh;
background: rgba(0, 31, 63, 0.9);
border-radius: 20px;
box-shadow: 0 0 50px rgba(0, 150, 255, 0.6);
z-index: 10;
display: none;
flex-direction: column;
overflow: hidden;
border: 2px solid #7FDBFF;
}
#mainInterface.active {
display: flex;
animation: interfacePulse 3s infinite alternate;
}
@keyframes interfacePulse {
0% { box-shadow: 0 0 50px rgba(0, 150, 255, 0.6); }
100% { box-shadow: 0 0 80px rgba(127, 219, 255, 0.9); }
}
#mainIframe {
flex: 1;
border: none;
background: #000;
}
#interfaceTitle {
padding: 15px;
background: linear-gradient(to right, #001f3f, #0074D9);
color: #7FDBFF;
text-align: center;
font-size: 16px;
letter-spacing: 1px;
}
#liquidControls {
position: fixed;
bottom: 30px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 20px;
z-index: 20;
}
.liquid-btn {
width: 60px;
height: 60px;
border-radius: 50%;
background: rgba(0, 74, 149, 0.7);
border: 2px solid #7FDBFF;
color: #7FDBFF;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-size: 24px;
box-shadow: 0 0 20px rgba(0, 150, 255, 0.5);
transition: all 0.3s;
opacity: 0.8;
}
.liquid-btn:hover {
background: rgba(0, 116, 217, 0.8);
transform: scale(1.1);
opacity: 1;
}
#liquidStats {
position: fixed;
top: 20px;
left: 20px;
color: #7FDBFF;
background: rgba(0, 31, 63, 0.7);
padding: 10px;
border-radius: 5px;
z-index: 20;
font-size: 12px;
border: 1px solid #0074D9;
}
.liquid-connection {
position: absolute;
height: 2px;
background: linear-gradient(to right, rgba(0, 150, 255, 0.3), rgba(127, 219, 255, 0.7));
transform-origin: 0 0;
z-index: 1;
border-radius: 50%;
transition: all 0.5s ease-out;
}
.ripple {
position: absolute;
border-radius: 50%;
background: rgba(127, 219, 255, 0.3);
transform: scale(0);
pointer-events: none;
z-index: 4;
}
@keyframes rippleEffect {
to {
transform: scale(4);
opacity: 0;
}
}
#gravityWell {
position: absolute;
width: 300px;
height: 300px;
border-radius: 50%;
background: radial-gradient(circle at center, rgba(0, 116, 217, 0.1), transparent 70%);
z-index: 0;
pointer-events: none;
display: none;
}
</style>
</head>
<body>
<canvas id="liquidCanvas"></canvas>
<div id="gravityWell"></div>
<div id="dropletsContainer">
<!-- Liquid droplets will be added by JavaScript -->
</div>
<div id="connectionsContainer">
<!-- Liquid connections will be added by JavaScript -->
</div>
<div id="ripplesContainer">
<!-- Ripple effects will be added by JavaScript -->
</div>
<div id="mainInterface">
<div id="interfaceTitle">Liquid Web Matrix</div>
<iframe id="mainIframe" sandbox="allow-same-origin allow-scripts allow-popups allow-forms"></iframe>
</div>
<div id="liquidControls">
<div class="liquid-btn" id="mergeBtn">🌀</div>
<div class="liquid-btn" id="splitBtn">💧</div>
<div class="liquid-btn" id="flowBtn">🌊</div>
</div>
<div id="liquidStats">
Droplets: <span id="dropletCount">0</span> |
Connections: <span id="connectionCount">0</span> |
Viscosity: <span id="viscosity">0.5</span>
</div>
<script>
// Liquid physics parameters
const DROPLET_COUNT = 7;
const MAX_CONNECTIONS = 15;
const VISCOSITY = 0.5;
const MERGE_DISTANCE = 80;
const SPLIT_ENERGY = 150;
// Sites data with liquid properties
const liquidSites = [
{ url: 'https://advertica13.blogspot.com/', title: 'Azure Current', color: '#0074D9', density: 1.0 },
{ url: 'https://advertica12.blogspot.com/', title: 'Deep Stream', color: '#0066cc', density: 1.1 },
{ url: 'https://www.softmod.shop/', title: 'Golden Ripple', color: '#FFDC00', density: 0.9 },
{ url: 'https://example.com/news', title: 'Crystal Flow', color: '#2ECC40', density: 1.0 },
{ url: 'https://example.com/art', title: 'Prism Drop', color: '#FF851B', density: 0.8 },
{ url: 'https://example.com/music', title: 'Harmonic Wave', color: '#F012BE', density: 1.0 },
{ url: 'https://example.com/forum', title: 'Confluence', color: '#B10DC9', density: 1.2 }
];
// DOM elements
const liquidCanvas = document.getElementById('liquidCanvas');
const ctx = liquidCanvas.getContext('2d');
const dropletsContainer = document.getElementById('dropletsContainer');
const connectionsContainer = document.getElementById('connectionsContainer');
const ripplesContainer = document.getElementById('ripplesContainer');
const mainInterface = document.getElementById('mainInterface');
const mainIframe = document.getElementById('mainIframe');
const interfaceTitle = document.getElementById('interfaceTitle');
const mergeBtn = document.getElementById('mergeBtn');
const splitBtn = document.getElementById('splitBtn');
const flowBtn = document.getElementById('flowBtn');
const dropletCount = document.getElementById('dropletCount');
const connectionCount = document.getElementById('connectionCount');
const viscosity = document.getElementById('viscosity');
const gravityWell = document.getElementById('gravityWell');
// Liquid state
let droplets = [];
let connections = [];
let activeDroplet = null;
let currentViscosity = VISCOSITY;
let gravityWellActive = false;
let gravityWellX = 0;
let gravityWellY = 0;
// Canvas setup
liquidCanvas.width = window.innerWidth;
liquidCanvas.height = window.innerHeight;
// Droplet class
class LiquidDroplet {
constructor(id, x, y, radius, site) {
this.id = id;
this.x = x;
this.y = y;
this.radius = radius;
this.site = site;
this.vx = (Math.random() - 0.5) * 2;
this.vy = (Math.random() - 0.5) * 2;
this.energy = 100;
this.element = this.createDOMElement();
this.updatePosition();
}
createDOMElement() {
const el = document.createElement('div');
el.className = 'droplet';
el.id = `droplet-${this.id}`;
el.style.width = `${this.radius * 2}px`;
el.style.height = `${this.radius * 2}px`;
el.style.color = this.site.color;
el.innerHTML = `
<div class="iframe-container">
<iframe src="${this.site.url}"
sandbox="allow-same-origin allow-scripts allow-popups allow-forms"></iframe>
</div>
<div class="droplet-label">${this.site.title}</div>
`;
el.addEventListener('click', (e) => {
e.stopPropagation();
this.activate();
});
dropletsContainer.appendChild(el);
return el;
}
updatePosition() {
this.element.style.left = `${this.x - this.radius}px`;
this.element.style.top = `${this.y - this.radius}px`;
this.element.style.opacity = 0.7 + (this.energy / 200);
}
activate() {
// Show in main interface
mainIframe.src = this.site.url;
interfaceTitle.textContent = this.site.title;
mainInterface.classList.add('active');
// Visual activation
droplets.forEach(d => d.element.classList.remove('active'));
this.element.classList.add('active');
activeDroplet = this;
// Create ripple effect
this.createRipple(this.x, this.y, this.radius * 2);
}
createRipple(x, y, size) {
const ripple = document.createElement('div');
ripple.className = 'ripple';
ripple.style.width = `${size}px`;
ripple.style.height = `${size}px`;
ripple.style.left = `${x - size/2}px`;
ripple.style.top = `${y - size/2}px`;
ripple.style.backgroundColor = this.site.color;
ripplesContainer.appendChild(ripple);
setTimeout(() => {
ripple.style.animation = 'rippleEffect 1s forwards';
setTimeout(() => ripple.remove(), 1000);
}, 10);
}
move() {
// Apply viscosity
this.vx *= (1 - currentViscosity * 0.05);
this.vy *= (1 - currentViscosity * 0.05);
// Apply gravity well if active
if (gravityWellActive) {
const dx = gravityWellX - this.x;
const dy = gravityWellY - this.y;
const dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 300) {
const force = 300 / (dist + 1);
this.vx += dx * 0.0005 * force;
this.vy += dy * 0.0005 * force;
}
}
// Update position
this.x += this.vx;
this.y += this.vy;
// Boundary bounce with energy loss
if (this.x < this.radius) {
this.x = this.radius;
this.vx *= -0.8;
this.energy *= 0.98;
}
if (this.x > liquidCanvas.width - this.radius) {
this.x = liquidCanvas.width - this.radius;
this.vx *= -0.8;
this.energy *= 0.98;
}
if (this.y < this.radius) {
this.y = this.radius;
this.vy *= -0.8;
this.energy *= 0.98;
}
if (this.y > liquidCanvas.height - this.radius) {
this.y = liquidCanvas.height - this.radius;
this.vy *= -0.8;
this.energy *= 0.98;
}
this.updatePosition();
}
mergeWith(other) {
// Create a new larger droplet
const newRadius = Math.sqrt(this.radius * this.radius + other.radius * other.radius);
const newX = (this.x + other.x) / 2;
const newY = (this.y + other.y) / 2;
// Combine site properties (random choice for demo)
const newSite = Math.random() > 0.5 ? this.site : other.site;
// Remove old droplets
this.remove();
other.remove();
// Create new droplet
const newDroplet = new LiquidDroplet(
droplets.length,
newX,
newY,
newRadius,
newSite
);
// Transfer energy
newDroplet.energy = (this.energy + other.energy) * 0.8;
newDroplet.vx = (this.vx + other.vx) / 2;
newDroplet.vy = (this.vy + other.vy) / 2;
droplets.push(newDroplet);
// Create splash effect
for (let i = 0; i < 5; i++) {
setTimeout(() => {
newDroplet.createRipple(
newX + (Math.random() - 0.5) * newRadius,
newY + (Math.random() - 0.5) * newRadius,
newRadius * (0.5 + Math.random())
);
}, i * 100);
}
return newDroplet;
}
split() {
if (this.radius < 40) return; // Too small to split
const splitCount = 2 + Math.floor(Math.random() * 2);
const newRadius = this.radius / Math.sqrt(splitCount);
// Remove original
this.remove();
// Create new droplets
for (let i = 0; i < splitCount; i++) {
const angle = (Math.PI * 2 / splitCount) * i;
const distance = this.radius;
const newDroplet = new LiquidDroplet(
droplets.length,
this.x + Math.cos(angle) * distance,
this.y + Math.sin(angle) * distance,
newRadius,
this.site
);
// Apply split energy
newDroplet.vx = this.vx + Math.cos(angle) * 3;
newDroplet.vy = this.vy + Math.sin(angle) * 3;
newDroplet.energy = this.energy / splitCount;
droplets.push(newDroplet);
// Create splash effect
newDroplet.createRipple(newDroplet.x, newDroplet.y, newRadius * 2);
}
}
remove() {
dropletsContainer.removeChild(this.element);
if (activeDroplet === this) {
mainInterface.classList.remove('active');
activeDroplet = null;
}
}
}
// Connection class
class LiquidConnection {
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 = 'liquid-connection';
el.id = `connection-${this.id}`;
connectionsContainer.appendChild(el);
return el;
}
updatePosition() {
const fromDroplet = droplets.find(d => d.id === this.fromId);
const toDroplet = droplets.find(d => d.id === this.toId);
if (fromDroplet && toDroplet) {
const dx = toDroplet.x - fromDroplet.x;
const dy = toDroplet.y - fromDroplet.y;
const length = Math.sqrt(dx * dx + dy * dy);
const angle = Math.atan2(dy, dx);
this.element.style.width = `${length}px`;
this.element.style.left = `${fromDroplet.x}px`;
this.element.style.top = `${fromDroplet.y}px`;
this.element.style.transform = `rotate(${angle}rad)`;
this.element.style.opacity = Math.min(0.7, 100 / length);
}
}
}
// Initialize liquid matrix
function initLiquidMatrix() {
clearMatrix();
// Create initial droplets
for (let i = 0; i < DROPLET_COUNT; i++) {
const x = Math.random() * (liquidCanvas.width - 200) + 100;
const y = Math.random() * (liquidCanvas.height - 200) + 100;
const radius = 40 + Math.random() * 30;
const site = liquidSites[i % liquidSites.length];
droplets.push(new LiquidDroplet(
droplets.length,
x,
y,
radius,
site
));
}
// Create some initial connections
createRandomConnections(5);
updateStats();
}
// Clear the matrix
function clearMatrix() {
dropletsContainer.innerHTML = '';
connectionsContainer.innerHTML = '';
ripplesContainer.innerHTML = '';
droplets = [];
connections = [];
activeDroplet = null;
}
// Create random connections
function createRandomConnections(count) {
for (let i = 0; i < count && connections.length < MAX_CONNECTIONS; i++) {
const fromIndex = Math.floor(Math.random() * droplets.length);
const toIndex = Math.floor(Math.random() * droplets.length);
if (fromIndex !== toIndex) {
const exists = connections.some(conn =>
(conn.fromId === fromIndex && conn.toId === toIndex) ||
(conn.fromId === toIndex && conn.toId === fromIndex)
);
if (!exists) {
connections.push(new LiquidConnection(
connections.length,
fromIndex,
toIndex
));
}
}
}
}
// Merge close droplets
function mergeCloseDroplets() {
for (let i = 0; i < droplets.length; i++) {
for (let j = i + 1; j < droplets.length; j++) {
const dx = droplets[j].x - droplets[i].x;
const dy = droplets[j].y - droplets[i].y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < MERGE_DISTANCE) {
const newDroplet = droplets[i].mergeWith(droplets[j]);
droplets = droplets.filter(d => d !== droplets[i] && d !== droplets[j]);
// Update connections
connections = connections.filter(conn =>
conn.fromId !== droplets[i].id &&
conn.toId !== droplets[i].id &&
conn.fromId !== droplets[j].id &&
conn.toId !== droplets[j].id
);
// Create new connections
if (Math.random() > 0.7) {
const randomTarget = Math.floor(Math.random() * droplets.length);
if (randomTarget !== newDroplet.id) {
connections.push(new LiquidConnection(
connections.length,
newDroplet.id,
randomTarget
));
}
}
return; // Only merge one pair per call
}
}
}
}
// Split active or random droplet
function splitDroplet() {
if (activeDroplet && activeDroplet.energy > SPLIT_ENERGY) {
activeDroplet.split();
} else {
// Split a random large droplet
const largeDroplets = droplets.filter(d => d.radius > 50);
if (largeDroplets.length > 0) {
const randomLarge = largeDroplets[Math.floor(Math.random() * largeDroplets.length)];
randomLarge.split();
}
}
// Update connections
if (connections.length < MAX_CONNECTIONS) {
createRandomConnections(2);
}
}
// Toggle gravity well
function toggleFlow() {
gravityWellActive = !gravityWellActive;
if (gravityWellActive) {
flowBtn.style.background = 'rgba(0, 255, 255, 0.8)';
gravityWell.style.display = 'block';
} else {
flowBtn.style.background = 'rgba(0, 74, 149, 0.7)';
gravityWell.style.display = 'none';
}
}
// Update statistics
function updateStats() {
dropletCount.textContent = droplets.length;
connectionCount.textContent = connections.length;
viscosity.textContent = currentViscosity.toFixed(2);
}
// Simulation loop
function simulateLiquid() {
// Update all droplets
droplets.forEach(droplet => {
droplet.move();
});
// Update all connections
connections.forEach(connection => {
connection.updatePosition();
});
// Randomly adjust viscosity
if (Math.random() > 0.98) {
currentViscosity = Math.max(0.1, Math.min(0.9, currentViscosity + (Math.random() - 0.5) * 0.1));
}
// Randomly create new connections
if (Math.random() > 0.95 && connections.length < MAX_CONNECTIONS) {
createRandomConnections(1);
}
// Randomly remove connections
if (Math.random() > 0.96 && connections.length > 3) {
const randomIndex = Math.floor(Math.random() * connections.length);
connectionsContainer.removeChild(connections[randomIndex].element);
connections.splice(randomIndex, 1);
}
updateStats();
requestAnimationFrame(simulateLiquid);
}
// Event listeners
mergeBtn.addEventListener('click', mergeCloseDroplets);
splitBtn.addEventListener('click', splitDroplet);
flowBtn.addEventListener('click', toggleFlow);
// Track mouse for gravity well
document.addEventListener('mousemove', (e) => {
if (gravityWellActive) {
gravityWell.style.left = `${e.clientX - 150}px`;
gravityWell.style.top = `${e.clientY - 150}px`;
gravityWellX = e.clientX;
gravityWellY = e.clientY;
}
});
// Close main interface when clicking outside
document.addEventListener('click', (e) => {
if (!mainInterface.contains(e.target)) {
mainInterface.classList.remove('active');
droplets.forEach(droplet => {
droplet.element.classList.remove('active');
});
activeDroplet = null;
}
});
// Handle window resize
window.addEventListener('resize', () => {
liquidCanvas.width = window.innerWidth;
liquidCanvas.height = window.innerHeight;
});
// Initialize
initLiquidMatrix();
simulateLiquid();
// Background animation
function animateBackground() {
ctx.fillStyle = 'rgba(0, 15, 30, 0.05)';
ctx.fillRect(0, 0, liquidCanvas.width, liquidCanvas.height);
// Draw faint grid
ctx.strokeStyle = 'rgba(0, 100, 150, 0.03)';
ctx.lineWidth = 1;
const gridSize = 50;
for (let x = 0; x < liquidCanvas.width; x += gridSize) {
ctx.beginPath();
ctx.moveTo(x, 0);
ctx.lineTo(x, liquidCanvas.height);
ctx.stroke();
}
for (let y = 0; y < liquidCanvas.height; y += gridSize) {
ctx.beginPath();
ctx.moveTo(0, y);
ctx.lineTo(liquidCanvas.width, y);
ctx.stroke();
}
requestAnimationFrame(animateBackground);
}
animateBackground();
</script>
</body>
</html>
```
### Key Features of This Liquid Web Matrix:
1. **Fluid Dynamics Interface**:
- Websites exist as liquid droplets that move and interact
- Realistic physics with viscosity, merging, and splitting
- Dynamic connections that form and break
2. **Interactive Liquid Manipulation**:
- Merge droplets to combine sites
- Split droplets to create new instances
- Gravity well to attract droplets with mouse movement
- Adjustable viscosity controls flow speed
3. **Visual Effects**:
- Ripple effects on interactions
- Glowing connections between related sites
- Smooth transitions and animations
- Depth perception through opacity changes
4. **Organic Navigation**:
- Click droplets to view their websites
- Discover relationships through liquid connections
- Emergent behavior from physics interactions
5. **Dynamic Ecosystem**:
- Droplets gain/lose energy through interactions
- Connections form and break organically
- System evolves over time
6. **Stats Dashboard**:
- Droplet count
- Connection count
- Current viscosity level
This implementation creates a completely unique way to browse and interact with websites by representing them as living elements in a digital liquid environment. The fluid dynamics create an intuitive interface where spatial relationships and movements convey information about how sites relate to each other.
Additional features you could add:
- Custom site addition with URL input
- Different "liquid types" with unique properties
- Saving/loading favorite configurations
- More advanced physics simulations
- Sound effects for liquid interactions
- Touchscreen optimizations for mobile devices