Created
May 10, 2025 04:13
-
-
Save EncodeTheCode/dbff0f90e67d6b3a7c577c42747944d5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Top-down Shadows with Transparent Bottom Gradient</title> | |
<style> | |
body { margin: 0; background: #222; } | |
canvas { display: block; margin: auto; background: #333; } | |
</style> | |
</head> | |
<body> | |
<canvas id="gameCanvas" width="800" height="600"></canvas> | |
<script> | |
const canvas = document.getElementById("gameCanvas"); | |
const ctx = canvas.getContext("2d"); | |
const lightDir = { x: 1, y: 1 }; // Diagonal light direction | |
const shadowLength = 60; | |
const player = { x: 200, y: 200, w: 32, h: 32, color: 'blue' }; | |
const walls = [ | |
{ x: 300, y: 100, w: 100, h: 40 }, | |
{ x: 500, y: 300, w: 120, h: 50 }, | |
{ x: 200, y: 400, w: 80, h: 60 } | |
]; | |
function draw() { | |
ctx.clearRect(0, 0, canvas.width, canvas.height); | |
// Draw shadows first | |
for (let obj of [...walls, player]) { | |
drawShadow(obj); | |
} | |
// Draw walls and player on top | |
for (let wall of walls) { | |
ctx.fillStyle = "gray"; | |
ctx.fillRect(wall.x, wall.y, wall.w, wall.h); | |
} | |
ctx.fillStyle = player.color; | |
ctx.fillRect(player.x, player.y, player.w, player.h); | |
requestAnimationFrame(draw); | |
} | |
function drawShadow(obj) { | |
const { x, y, w, h } = obj; | |
const dx = lightDir.x * shadowLength; | |
const dy = lightDir.y * shadowLength; | |
const faces = [ | |
// Bottom face shadow (cast down and to the right) | |
{ | |
corners: [ | |
{ x: x, y: y + h }, | |
{ x: x + w, y: y + h }, | |
{ x: x + w + dx, y: y + h + dy }, | |
{ x: x + dx, y: y + h + dy } | |
] | |
}, | |
// Right face shadow (cast down and to the right) | |
{ | |
corners: [ | |
{ x: x + w, y: y }, | |
{ x: x + w, y: y + h }, | |
{ x: x + w + dx, y: y + h + dy }, | |
{ x: x + w + dx, y: y + dy } | |
] | |
} | |
]; | |
for (let face of faces) { | |
const [p1, p2, p3, p4] = face.corners; | |
// Compute center for gradient direction (fading from top to bottom) | |
const gx0 = (p1.x + p2.x) / 3; | |
const gy0 = (p1.y + p2.y) / 2; | |
const gx1 = (p3.x + p4.x) / 2; | |
const gy1 = (p3.y + p4.y) / 2; | |
// Create gradient that fades from black (top) to transparent (bottom) | |
const gradient = ctx.createLinearGradient(gx0, gy0, gx1, gy1); | |
gradient.addColorStop(0, "rgba(0,0,0,0.35)"); // Fully opaque at the top | |
gradient.addColorStop(1, "rgba(0,0,0,0)"); // Fully transparent at the bottom | |
ctx.fillStyle = gradient; | |
ctx.beginPath(); | |
ctx.moveTo(p1.x, p1.y); | |
ctx.lineTo(p2.x, p2.y); | |
ctx.lineTo(p3.x, p3.y); | |
ctx.lineTo(p4.x, p4.y); | |
ctx.closePath(); | |
ctx.fill(); | |
} | |
} | |
draw(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment