This commit is contained in:
Kenwood 2025-06-26 02:28:15 -04:00
commit b04f473a62
12 changed files with 362 additions and 0 deletions

41
nginx.conf Normal file
View File

@ -0,0 +1,41 @@
worker_processes auto;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
sendfile on;
server {
listen 80;
server_name cumtanks.snowsune.net;
# Docker container path
root /usr/share/nginx/html;
index index.html;
# Low TTL for data.json
location /data.json {
add_header Cache-Control "max-age=5, must-revalidate";
try_files $uri =404;
}
# Normal caching for other static files
location / {
expires 1h;
add_header Cache-Control "public, no-transform";
try_files $uri $uri/ =404;
}
# Ignore favicon requests
location /favicon.ico {
log_not_found off;
access_log off;
}
# Optional: Serve index on 404
error_page 404 /index.html;
}
}

2
update.sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/bash
rsync -avz --delete www/* joe@snowsunehost:/opt/cumtanks.snowsune.net/www --progress

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

BIN
www/bkground.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

20
www/data.json Normal file
View File

@ -0,0 +1,20 @@
{
"liquids": [
{
"name": "Coyote Cum",
"volume": 12,
"color": "#f1f2f2",
"url": "https://www.f-list.net/c/alice%20prairie"
},
{
"name": "Bear Cum",
"volume": 9,
"color": "#523a33",
"url": "https://www.f-list.net/c/Glyren"
}
],
"settings": {
"tankTopOffset": 265,
"tankBottomOffset": 100
}
}

142
www/index.html Normal file
View File

@ -0,0 +1,142 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Cumtanks.snowusne.net</title>
<!-- Open Graph / Discord -->
<meta property="og:type" content="website" />
<meta property="og:title" content="cumtanks.snowusne.net" />
<meta property="og:image" content="/preview.png" />
<!-- Twitter -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="cumtanks.snowusne.net" />
<meta name="twitter:image" content="/preview.png" />
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div class="container">
<div class="tank-container">
<img src="Alice_close_up_sheath_background.png" alt="Tank Background Back"
class="background-image background-image-back" />
<img src="Alice_close_up_sheath_shot.png" alt="Tank Background Foreground"
class="background-image background-image-fore" />
<!-- Liquid layers will be inserted here by JavaScript! -->
<div class="artist-link">
<a href="https://x.com/Raven4Seth" target="_blank" rel="noopener noreferrer">Art by SethRaven4</a>
</div>
</div>
<div class="settings">
<h2>Settings</h2>
<label>
Tank Top Offset (px):
<input type="number" id="tankTopOffset" value="22" min="0" max="800" />
</label>
<label>
Tank Bottom Offset (px):
<input type="number" id="tankBottomOffset" value="40" min="0" max="800" />
</label>
</div>
</div>
<script>
let tankData = null;
const tankContainer = document.querySelector(".tank-container");
const tankTopInput = document.getElementById("tankTop");
const tankBottomInput = document.getElementById("tankBottom");
const tankTopOffsetInput = document.getElementById("tankTopOffset");
const tankBottomOffsetInput = document.getElementById("tankBottomOffset");
async function loadData() {
try {
const response = await fetch("data.json");
tankData = await response.json();
updateTank();
} catch (error) {
console.error("Error loading tank data:", error);
}
}
function updateTank() {
if (!tankData) return;
// Clear existing liquid layers
const existingLayers = document.querySelectorAll(".liquid-layer");
existingLayers.forEach((layer) => layer.remove());
const tankContainerHeight = tankContainer.offsetHeight;
const tankTopOffset = tankData.settings.tankTopOffset;
const tankBottomOffset = tankData.settings.tankBottomOffset;
const tankHeight = tankContainerHeight - tankTopOffset - tankBottomOffset;
let currentHeight = 0;
let cumulativeVolume = 0;
tankData.liquids.forEach((liquid) => {
const layer = document.createElement("div");
layer.className = "liquid-layer";
layer.style.backgroundColor = liquid.color;
// Create the label
const label = document.createElement("div");
label.className = "liquid-label";
// If there's a URL, make it a clickable link
if (liquid.url) {
const link = document.createElement("a");
link.href = liquid.url;
link.textContent = `${liquid.name} (${liquid.volume}%)`;
link.className = "liquid-link";
label.appendChild(link);
} else {
label.textContent = `${liquid.name} (${liquid.volume}%)`;
}
cumulativeVolume += liquid.volume;
// Shift label left if cumulative volume is under 20%
if (cumulativeVolume < 20) {
label.style.left = '18%';
label.style.transform = 'translate(-30%, -50%)';
} else {
label.style.left = '50%';
label.style.transform = 'translate(-50%, -50%)';
}
// Calculate height based on volume percentage
const height = (liquid.volume / 100) * tankHeight;
layer.style.height = `${height}px`;
// Position from bottom, stacking up, starting at tankBottomOffset
layer.style.bottom = `${currentHeight + tankBottomOffset}px`;
currentHeight += height;
// Add the label to the layer
layer.appendChild(label);
tankContainer.appendChild(layer);
});
}
// Update settings
function updateSettings() {
if (!tankData) return;
tankData.settings.tankTopOffset = parseInt(tankTopOffsetInput.value);
tankData.settings.tankBottomOffset = parseInt(tankBottomOffsetInput.value);
updateTank();
}
// Event listeners
tankTopOffsetInput.addEventListener("change", updateSettings);
tankBottomOffsetInput.addEventListener("change", updateSettings);
// Initial load
loadData();
</script>
</body>
</html>

BIN
www/preview.kra Normal file

Binary file not shown.

BIN
www/preview.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

BIN
www/preview.png~ Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

157
www/styles.css Normal file
View File

@ -0,0 +1,157 @@
body {
margin: 0;
padding: 0;
background: #23232b;
font-family: Arial, sans-serif;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
}
.container {
width: 100%;
max-width: 1200px;
padding: 20px;
}
h1 {
color: white;
text-align: center;
margin: 20px 0;
}
.tank-container {
position: relative;
width: 100%;
height: 850px;
background: #23232b;
overflow: hidden;
border-radius: 0;
margin: 0 auto;
left: 0;
top: 0;
padding: 0;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
}
.background-image {
position: absolute;
width: auto;
height: 100%;
max-width: 110%;
max-height: 110%;
object-fit: contain;
border: 4px solid #000;
box-sizing: border-box;
pointer-events: none;
left: 50%;
top: 0;
transform: translateX(-50%);
margin: 0;
padding: 0;
}
.background-image-back {
z-index: 1;
}
.background-image-fore {
z-index: 3;
}
.liquid-layer {
position: absolute;
width: 80%;
left: 50%;
transform: translateX(-50%);
transition: all 0.3s ease;
z-index: 2;
overflow: hidden;
}
.liquid-layer > div {
width: 100%;
height: 100%;
position: relative;
}
.liquid-label {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
font-weight: bold;
z-index: 2;
padding: 5px 10px;
background: rgba(0, 0, 0, 0.3);
border-radius: 4px;
text-align: center;
white-space: nowrap;
font-size: 1.2em;
}
.liquid-link {
color: white;
text-decoration: none;
cursor: pointer;
transition: opacity 0.2s ease;
}
.liquid-link:hover {
opacity: 0.8;
text-decoration: underline;
}
/* Settings are hidden but still in the DOM for development */
.settings {
display: none;
}
.artist-credit {
text-align: center;
padding: 1rem;
color: #666;
font-size: 0.9rem;
font-style: italic;
margin-top: 2rem;
}
.artist-link {
position: absolute;
top: 80px;
right: 100px;
transform: rotate(51deg);
z-index: 100;
width: 150px;
height: 100px;
pointer-events: auto;
/* DEBUG: Temporary visible area for clickable link */
/* outline: 2px dashed #ff0;
background: rgba(255, 255, 0, 0.2); */
}
.artist-link a {
display: block;
width: 100%;
height: 100%;
text-indent: -9999px;
background: transparent;
border: none;
outline: none;
cursor: pointer;
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
.artist-link a:hover {
background: #fff;
color: #23232b;
}