Skip to content

Instantly share code, notes, and snippets.

@hideya
Last active August 13, 2025 20:32
Show Gist options
  • Save hideya/228c7e42b1a261f4c7bb868d9c0e66d8 to your computer and use it in GitHub Desktop.
Save hideya/228c7e42b1a261f4c7bb868d9c0e66d8 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Super Shiny Metal with Dynamic Lighting</title>
<style>
body {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
background: #1a1a1a;
min-height: 100vh;
overflow: hidden;
cursor: none;
}
.container {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
position: relative;
}
.metal-surface {
width: 100px;
height: 100px;
background: radial-gradient(ellipse at center, #e8e8e8, #c0c0c0, #a0a0a0);
border-radius: 15px;
position: relative;
filter: url(#ultraShiny);
box-shadow:
0 0 20px rgba(255,255,255,0.3),
inset 0 0 30px rgba(255,255,255,0.1);
border: 2px solid #999;
}
.surface-label {
position: absolute;
bottom: -40px;
left: 50%;
transform: translateX(-50%);
color: #ccc;
font-size: 16px;
font-weight: bold;
text-shadow: 2px 2px 4px rgba(0,0,0,0.8);
text-align: center;
white-space: nowrap;
}
.light-cursor {
position: fixed;
width: 40px;
height: 40px;
background: radial-gradient(circle,
#ffffff 0%,
#ffff99 20%,
#ffcc00 50%,
transparent 70%);
border-radius: 50%;
pointer-events: none;
z-index: 1000;
transform: translate(-50%, -50%);
box-shadow:
0 0 30px #ffff00,
0 0 60px #ffff00,
0 0 90px #ffaa00;
animation: pulse 2s ease-in-out infinite alternate;
}
@keyframes pulse {
0% {
transform: translate(-50%, -50%) scale(1);
opacity: 0.8;
}
100% {
transform: translate(-50%, -50%) scale(1.2);
opacity: 1;
}
}
.info-panel {
position: fixed;
top: 20px;
left: 20px;
background: rgba(0,0,0,0.8);
color: white;
padding: 20px;
border-radius: 10px;
font-size: 14px;
border: 1px solid #444;
max-width: 300px;
}
.info-panel h3 {
margin: 0 0 10px 0;
color: #ffdd00;
}
.coord-display {
position: fixed;
bottom: 20px;
right: 20px;
background: rgba(0,0,0,0.8);
color: #00ff00;
padding: 15px;
border-radius: 10px;
font-family: 'Courier New', monospace;
border: 1px solid #444;
}
</style>
</head>
<body>
<div class="container">
<!-- Custom light cursor -->
<div class="light-cursor" id="lightCursor"></div>
<!-- SVG Filter for ultra-shiny metal -->
<svg width="0" height="0" style="position: absolute;">
<defs>
<filter id="ultraShiny" x="-100%" y="-100%" width="300%" height="300%">
<!-- Create fine surface texture for smooth metallic finish -->
<feTurbulence type="fractalNoise" baseFrequency="0.3" numOctaves="2" result="fineBumps"/>
<!-- Convert to height map -->
<feColorMatrix type="saturate" values="0" in="fineBumps" result="heightMap"/>
<!-- Smooth out the surface for minimal texture -->
<feGaussianBlur stdDeviation="1" in="heightMap" result="smoothHeight"/>
<!-- Create ultra-strong diffuse lighting -->
<feDiffuseLighting in="enhancedHeight"
lighting-color="white"
surfaceScale="8"
diffuseConstant="1.5"
result="diffuse">
<fePointLight id="mainLight" x="300" y="200" z="150"/>
</feDiffuseLighting>
<!-- Create extremely strong specular highlights -->
<feSpecularLighting in="enhancedHeight"
lighting-color="#ffffff"
surfaceScale="12"
specularConstant="3.5"
specularExponent="35"
result="specular">
<fePointLight x="300" y="200" z="150"/>
</feSpecularLighting>
<!-- Create secondary specular for extra shine -->
<feSpecularLighting in="enhancedHeight"
lighting-color="#ffffcc"
surfaceScale="15"
specularConstant="2.8"
specularExponent="50"
result="specular2">
<fePointLight x="300" y="200" z="120"/>
</feSpecularLighting>
<!-- Combine specular highlights -->
<feComposite in="specular" in2="specular2" operator="screen" result="combinedSpecular"/>
<!-- Blend everything with the original surface -->
<feComposite in="combinedSpecular" in2="SourceGraphic" operator="arithmetic"
k1="0" k2="1" k3="2.5" k4="0" result="shinyMetal"/>
<feComposite in="shinyMetal" in2="diffuse" operator="multiply" result="litMetal"/>
<!-- Final brightness and contrast boost -->
<feComponentTransfer in="litMetal">
<feFuncR type="gamma" amplitude="1.2" exponent="0.8" offset="0.1"/>
<feFuncG type="gamma" amplitude="1.2" exponent="0.8" offset="0.1"/>
<feFuncB type="gamma" amplitude="1.2" exponent="0.8" offset="0.1"/>
</feComponentTransfer>
</filter>
</defs>
</svg>
<div class="metal-surface">
<div class="surface-label">Ultra-Shiny Chrome Metal</div>
</div>
<div class="info-panel">
<h3>Super Shiny Metal Demo</h3>
<p><strong>Surface Scale:</strong> 3-5 (high but controlled)</p>
<p><strong>Specular Constant:</strong> 1.2-1.8 (strong shininess)</p>
<p><strong>Specular Exponent:</strong> 40-60 (sharp highlights)</p>
<p><strong>Surface Texture:</strong> Smooth metallic finish with fine detail</p>
<p><strong>Lighting:</strong> Dual specular layers for ultra-bright reflections</p>
<br>
<p><em>Move your mouse to see the light reflections dance across the bumpy metal surface!</em></p>
</div>
<div class="coord-display" id="coordDisplay">
Light Position: (0, 0)
Azimuth: 0°
Elevation: 45°
</div>
</div>
<script>
const lightCursor = document.getElementById('lightCursor');
const coordDisplay = document.getElementById('coordDisplay');
const mainLight = document.getElementById('mainLight');
// Get all point lights in the filter
const pointLights = document.querySelectorAll('fePointLight');
let mouseX = window.innerWidth / 2;
let mouseY = window.innerHeight / 2;
// Update lighting based on mouse position
document.addEventListener('mousemove', (e) => {
mouseX = e.clientX;
mouseY = e.clientY;
updateLighting();
});
function updateLighting() {
// Update cursor position
lightCursor.style.left = mouseX + 'px';
lightCursor.style.top = mouseY + 'px';
// Get metal surface bounds for relative positioning
const metalSurface = document.querySelector('.metal-surface');
const rect = metalSurface.getBoundingClientRect();
// Calculate relative position within the metal surface (0-600 x 0-400)
const relativeX = ((mouseX - rect.left) / rect.width) * 600;
const relativeY = ((mouseY - rect.top) / rect.height) * 400;
// Calculate Z position based on distance from center (closer to center = higher Z)
const centerX = 300;
const centerY = 200;
const distanceFromCenter = Math.sqrt(
Math.pow(relativeX - centerX, 2) + Math.pow(relativeY - centerY, 2)
);
const maxDistance = Math.sqrt(centerX * centerX + centerY * centerY);
const zPosition = 100 + (1 - (distanceFromCenter / maxDistance)) * 100; // 100-200 range
// Update all point lights
pointLights.forEach((light, index) => {
const offset = index * 20; // Slight offset for multiple lights
light.setAttribute('x', Math.max(0, Math.min(600, relativeX + offset)));
light.setAttribute('y', Math.max(0, Math.min(400, relativeY + offset)));
light.setAttribute('z', zPosition + offset);
});
// Calculate angles for display
const azimuth = Math.atan2(relativeY - centerY, relativeX - centerX) * 180 / Math.PI;
const elevation = Math.atan2(zPosition, distanceFromCenter) * 180 / Math.PI;
// Update coordinate display
coordDisplay.innerHTML = `
Light Position: (${Math.round(relativeX)}, ${Math.round(relativeY)})
Z-Height: ${Math.round(zPosition)}
Azimuth: ${Math.round(azimuth)}°
Elevation: ${Math.round(elevation)}°
`;
}
// Initialize lighting
updateLighting();
// Add some subtle animation to the light cursor
let time = 0;
function animateLight() {
time += 0.02;
const pulse = Math.sin(time) * 0.1 + 1;
lightCursor.style.filter = `brightness(${pulse})`;
requestAnimationFrame(animateLight);
}
animateLight();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment