<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>Canvas 内凹弧形导航菜单(顶部内凹)</title><style>* {margin: 0;padding: 0;box-sizing: border-box;}body {background-color: #f0f0f0;}.nav-menu {display: flex;justify-content: space-around;position: relative;height: 100px;z-index: 5;color: white;overflow: hidden;margin: 0;padding: 0 140px;width: 1120px;box-sizing: border-box; }.nav-menu li {list-style-type: none;padding:30px 20px 0;text-align: center;line-height: 60px;width: 100%;cursor: pointer;transition: all 0.3s ease;}.nav-menu li.active a{color: #000;}.nav-menu a {color: white;text-decoration: none;}canvas {position: absolute;top: 0;left: 0;pointer-events: none;z-index: 1;}</style>
</head>
<body><ul class="nav-menu" id="navMenu"><li><a href="#">企业使命</a></li><li><a href="#">企业愿景</a></li><li><a href="#">核心价值观</a></li><li><a href="#">企业精神</a></li></ul><canvas id="arcCanvas"></canvas><script>document.addEventListener('DOMContentLoaded', function () {const canvas = document.getElementById('arcCanvas');const ctx = canvas.getContext('2d');const navMenu = document.getElementById('navMenu');const items = navMenu.querySelectorAll('li');let targetIndex = 0;let currentLeft = 0;let currentWidth = 0;let currentCenterX = 0;const ease = 0.15; let animationId = null;let resizeTimer = null; function resizeCanvas() {if (animationId) {cancelAnimationFrame(animationId);animationId = null;}canvas.width = navMenu.offsetWidth;canvas.height = navMenu.offsetHeight;drawArc();}function initFirstItem() {const first = items[0];currentLeft = first.offsetLeft;currentWidth = first.offsetWidth;currentCenterX = first.offsetLeft + first.offsetWidth / 2;}function drawArc() {const depth = 15; const cornerRadius = 30; const midWidth = currentWidth / 2; const width = currentWidth;const left = currentLeft;const right = left + width;const centerX = currentCenterX;const midStartX = centerX - midWidth / 2;const midEndX = centerX + midWidth / 2;const ctrlY = depth * 3; ctx.clearRect(0, 0, canvas.width, canvas.height);ctx.beginPath();ctx.moveTo(0, cornerRadius);ctx.arcTo(0, 0, cornerRadius, 0, cornerRadius);ctx.lineTo(left, 0);const cornerEndLeft = left + 2 * cornerRadius;ctx.quadraticCurveTo(left + cornerRadius, 0,cornerEndLeft, depth);if (cornerEndLeft < midStartX) {ctx.lineTo(midStartX, depth);}ctx.quadraticCurveTo(centerX, ctrlY,midEndX, depth);const cornerStartRight = right - 2 * cornerRadius;if (midEndX < cornerStartRight) {ctx.lineTo(cornerStartRight, depth);}ctx.quadraticCurveTo(right - cornerRadius, 0,right, 0);ctx.lineTo(canvas.width - cornerRadius, 0);ctx.arcTo(canvas.width, 0, canvas.width, cornerRadius, cornerRadius);ctx.lineTo(canvas.width, canvas.height);ctx.lineTo(0, canvas.height);ctx.lineTo(0, cornerRadius);ctx.closePath();ctx.fillStyle = 'rgba(255, 0, 0, 1)';ctx.fill();}function update() {const targetItem = items[targetIndex];const targetLeft = targetItem.offsetLeft;const targetWidth = targetItem.offsetWidth;const targetCenterX = targetLeft + targetWidth / 2;let changed = false;const dxLeft = targetLeft - currentLeft;if (Math.abs(dxLeft) > 0.5) {currentLeft += dxLeft * ease;changed = true;} else {currentLeft = targetLeft;}const dxWidth = targetWidth - currentWidth;if (Math.abs(dxWidth) > 0.5) {currentWidth += dxWidth * ease;changed = true;} else {currentWidth = targetWidth;}const dxCenter = targetCenterX - currentCenterX;if (Math.abs(dxCenter) > 0.5) {currentCenterX += dxCenter * ease;changed = true;} else {currentCenterX = targetCenterX;}drawArc();if (changed) {animationId = requestAnimationFrame(update);}}function setActive(index) {items.forEach(item => item.classList.remove('active'));items[index].classList.add('active');if (targetIndex === index) return;targetIndex = index;if (animationId) {cancelAnimationFrame(animationId);}animationId = requestAnimationFrame(update);}navMenu.addEventListener('mousemove', function (e) {for (let i = 0; i < items.length; i++) {const rect = items[i].getBoundingClientRect();if (e.clientX >= rect.left && e.clientX <= rect.right) {setActive(i);return;}}});navMenu.addEventListener('mouseleave', function () {setActive(0);});window.addEventListener('resize', function () {clearTimeout(resizeTimer);resizeTimer = setTimeout(resizeCanvas, 100);});resizeCanvas(); initFirstItem(); drawArc(); setActive(0); });</script>
</body>
</html>
