Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added images/.DS_Store
Binary file not shown.
Binary file added images/breakfast-burrito.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/breakfast-canned-bread.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/breakfast-omelette.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/brunch-coral-bits.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/brunch-french-toast.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/brunch-waffles.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dessert-fruitcake.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dessert-gooberry.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dessert-sponge-cake.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dinner-krabby-pate.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dinner-krusty-krab-pizza.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dinner-pasta.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/drinks-diet-dr-kelp.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/drinks-kelp-shake.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/drinks-milkshake.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/happyhour-blood-sausages.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/happyhour-kelp-cheese.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/happyhour-kelp-fries.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/lunch-krabby-patty.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/lunch-pulled-pork.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/lunch-salad.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
153 changes: 153 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Krusty Krab Menu</title>
<link rel="stylesheet" href="style.css" />
</head>

<body>

<div id="page-wrap">

<header class="hero" id="hero">
<h1>Krusty Krab</h1>
<p>Come spend your money here!</p>
</header>

<section class="menu-controls" id="controls">
<button class="menu-btn active" data-category="breakfast">Breakfast</button>
<button class="menu-btn" data-category="lunch">Lunch</button>
<button class="menu-btn" data-category="brunch">Brunch</button>
<button class="menu-btn" data-category="dinner">Dinner</button>
<button class="menu-btn" data-category="dessert">Dessert</button>
<button class="menu-btn" data-category="happyHour">Happy Hour</button>
<button class="menu-btn" data-category="drinks">Drinks</button>
</section>

<main class="menu-section" id="menu-board">
<h2 id="menu-title">Menu</h2>
<div id="menu-display"></div>
</main>

<svg id="rope-overlay" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"></svg>

</div>

<script src="script.js"></script>
<script>
const svg = document.getElementById('rope-overlay');

/* Returns the element's bounding box in page coordinates (not viewport) */
function pageBox(id) {
const el = document.getElementById(id);
const r = el.getBoundingClientRect();
const sy = window.scrollY;
const sx = window.scrollX;
return {
top: r.top + sy,
bottom: r.bottom + sy,
left: r.left + sx,
right: r.right + sx,
};
}

/* Draws a rope segment with a visible catenary sag between two nail points */
function rope(x1, y1, x2, y2) {
const SAG = 35;
const d = `M ${x1} ${y1} C ${x1} ${y1 + SAG} , ${x2} ${y2 - SAG} , ${x2} ${y2}`;

/* Dark base strand */
const base = document.createElementNS('http://www.w3.org/2000/svg', 'path');
base.setAttribute('d', d);
base.setAttribute('fill', 'none');
base.setAttribute('stroke', '#3d1f05');
base.setAttribute('stroke-width', '5');
base.setAttribute('stroke-linecap', 'round');
svg.appendChild(base);

/* Lighter highlight strand for texture */
const hi = document.createElementNS('http://www.w3.org/2000/svg', 'path');
hi.setAttribute('d', d);
hi.setAttribute('fill', 'none');
hi.setAttribute('stroke', '#9B6E3C');
hi.setAttribute('stroke-width', '2');
hi.setAttribute('stroke-linecap', 'round');
hi.setAttribute('stroke-dasharray', '5 8');
svg.appendChild(hi);
}

/* Draws a nail (screw head) at the given page coordinates */
function nail(x, y) {
const body = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
body.setAttribute('cx', x); body.setAttribute('cy', y); body.setAttribute('r', '7');
body.setAttribute('fill', '#888'); body.setAttribute('stroke', '#444'); body.setAttribute('stroke-width', '1.5');
svg.appendChild(body);

const shine = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
shine.setAttribute('cx', x - 2); shine.setAttribute('cy', y - 2); shine.setAttribute('r', '2.5');
shine.setAttribute('fill', '#ccc');
svg.appendChild(shine);
}

function drawRopes() {
/* Size SVG to exactly cover the full scrollable page */
svg.style.position = 'absolute';
svg.style.top = '0';
svg.style.left = '0';
svg.style.width = '100%';
svg.style.pointerEvents = 'none';
svg.style.zIndex = '999';
const pw = document.getElementById('page-wrap');
svg.style.height = pw.offsetHeight + 'px';
svg.setAttribute('height', pw.offsetHeight);

svg.innerHTML = '';

const h = pageBox('hero');
const c = pageBox('controls');
const m = pageBox('menu-board');

/* Nail attachment x-positions align with board corners */
const lx = h.left + 28;
const rx = h.right - 28;

/* Nail y-positions: bottom of upper board, top of lower board */
const heroBottomY = h.bottom - 14;
const ctrlTopY = c.top + 14;
const ctrlBottomY = c.bottom - 14;
const menuTopY = m.top + 14;

/* Left side rope chain */
rope(lx, heroBottomY, lx, ctrlTopY);
rope(lx, ctrlBottomY, lx, menuTopY);

/* Right side rope chain */
rope(rx, heroBottomY, rx, ctrlTopY);
rope(rx, ctrlBottomY, rx, menuTopY);

/* Nails at every attachment point */
nail(lx, heroBottomY);
nail(lx, ctrlTopY);
nail(lx, ctrlBottomY);
nail(lx, menuTopY);
nail(rx, heroBottomY);
nail(rx, ctrlTopY);
nail(rx, ctrlBottomY);
nail(rx, menuTopY);
}

window.addEventListener('load', drawRopes);
window.addEventListener('resize', drawRopes);

/* Redraw after menu content swaps (board height changes) */
new MutationObserver(() => {
setTimeout(drawRopes, 50);
}).observe(document.getElementById('menu-display'), { childList: true });
</script>

</body>

</html>
Binary file added interactive-restaurant-menu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
192 changes: 192 additions & 0 deletions script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
const buttons = document.querySelectorAll(".menu-btn");
const menuTitle = document.querySelector("#menu-title");
const menuDisplay = document.querySelector("#menu-display");

const menuData = {
breakfast: [
{
name: "Krusty Krab Omelette",
description: "A fluffy three-egg omelet stuffed with cheese, sausage, and seaweed-style spinach, served with coral hash browns.",
price: "$8",
image: "images/breakfast-omelette.jpeg"
},
{
name: "Squidward's Canned Bread",
description: "Canned bread served with a side of disappointment",
price: "$7",
image: "images/breakfast-canned-bread.webp"
},
{
name: "Bikini Bottom Breakfast Burrito",
description: "Scrambled eggs, crispy bacon, cheese, and potatoes wrapped in a warm tortilla with sandy salsa.",
price: "$6",
image: "images/breakfast-burrito.webp"
}
],
lunch: [
{
name: "Krabby Patty",
description: "THE burger. Secret sauce, lettuce, cheese, tomato, onion on a sesame bun",
price: "$12",
image: "images/lunch-krabby-patty.webp"
},
{
name: "Sandy's Texas Pulled Pork",
description: "Slow-smoked pulled pork sandwich with coleslaw on a brioche bun",
price: "$11",
image: "images/lunch-pulled-pork.jpeg"
},
{
name: "Jellyfish Fields Salad",
description: "Mixed greens, pickled beets, goat cheese & honey-lemon dressing. Stings in a good way!",
price: "$7",
image: "images/lunch-salad.webp"
}
],
brunch: [
{
name: "SpongeBob's Pineapple French Toast",
description: "Thick-cut French toast topped with caramelized pineapple and powdered sugar.",
price: "$14",
image: "images/brunch-french-toast.jpeg"
},
{
name: "Patrick's Starfish Waffles",
description: "Crispy waffles shaped like starfish, served with strawberry syrup and whipped cream.",
price: "$10",
image: "images/brunch-waffles.jpg"
},
{
name: "Coral Bits",
description: "Crispy fried coral bits served with a tangy dipping sauce.",
price: "$9",
image: "images/brunch-coral-bits.webp"
}
],
dinner: [
{
name: "Krabby Pâté",
description: "Ground Krabby Patties minced into a spreadable paste, with jewelry added to make the food appear fancier.",
price: "$18",
image: "images/dinner-krabby-pate.webp"
},
{
name: "Spongebob's Sea Salt Pasta",
description: "Creamy Alfredo pasta with grilled chicken and garlic bread.",
price: "$19",
image: "images/dinner-pasta.webp"
},
{
name: "Krusty Krab Pizza",
description: "A delicious pizza with a krabby patty topping, served with a side of coral ranch dressing.",
price: "$15",
image: "images/dinner-krusty-krab-pizza.webp"
}
],
dessert: [
{
name: "Triple Gooberry Surprise",
description: "A massive mountain of ice cream, syrup, whipped cream, and gooberries.",
price: "$7",
image: "images/dessert-gooberry.jpg"
},
{
name: "Fruitcake",
description: "A classic fruitcake packed with dried fruits and nuts.",
price: "$6",
image: "images/dessert-fruitcake.webp"
},
{
name: "Sponge Cake",
description: "A moist and spongy cake made with secret ingredients from the Krusty Krab.",
price: "$5",
image: "images/dessert-sponge-cake.webp"
}
],
happyHour: [
{
name: "Kelp Cheese",
description: "A creamy cheese made from fermented kelp, served with crackers.",
price: "$6",
image: "images/happyhour-kelp-cheese.webp"
},
{
name: "Kelp Fries",
description: "Crispy kelp fries with a side of spicy coral sauce.",
price: "$7",
image: "images/happyhour-kelp-fries.webp"
},
{
name: "Blood Sausages",
description: "Juicy sausages made from the blood of sea creatures, served with a side of seaweed salad.",
price: "$6",
image: "images/happyhour-blood-sausages.webp"
}
],
drinks: [
{
name: "Goofy Goober Milkshake",
description: "Vanilla milkshake topped with whipped cream and sprinkles.",
price: "$4",
image: "images/drinks-milkshake.webp"
},
{
name: "Kelp Shake",
description: "A refreshing blend of kelp and sea minerals, served chilled.",
price: "$5",
image: "images/drinks-kelp-shake.jpeg"
},
{
name: "Diet Dr. Kelp",
description: "A refreshing sugar-free sea soda with a crisp and bubbly finish.",
price: "$6",
image: "images/drinks-diet-dr-kelp.webp"
}
]
};

function displayMenu(category) {
menuDisplay.innerHTML = "";

const categoryTitles = {
breakfast: "Breakfast Menu",
lunch: "Lunch Menu",
brunch: "Brunch Menu",
dinner: "Dinner Menu",
dessert: "Dessert Menu",
happyHour: "Happy Hour Menu",
drinks: "Drinks Menu"
};

menuTitle.textContent = categoryTitles[category];

menuData[category].forEach(item => {
const menuItem = document.createElement("div");
menuItem.classList.add("menu-item");

menuItem.innerHTML = `
<img class="menu-item-img" src="${item.image}" alt="${item.name}" />
<div class="menu-item-body">
<div class="menu-item-header">
<h3>${item.name}</h3>
<span class="leader"></span>
<span class="price">${item.price}</span>
</div>
<p>${item.description}</p>
</div>
`;

menuDisplay.appendChild(menuItem);
});
}

displayMenu("breakfast");

buttons.forEach(button => {
button.addEventListener("click", function () {
buttons.forEach(btn => btn.classList.remove("active"));
button.classList.add("active");
const selectedCategory = button.dataset.category;
displayMenu(selectedCategory);
});
});
Loading