Spaces:
Running
Running
| <html lang="es"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Plan nutricional 🍎</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| .gradient-bg { | |
| background: linear-gradient(135deg, #8E2DE2 0%, #4A00E0 100%); | |
| } | |
| .gradient-bg-secondary { | |
| background: linear-gradient(135deg, #f5af19 0%, #f12711 100%); | |
| } | |
| .gradient-bg-green { | |
| background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%); | |
| } | |
| .result-card { | |
| transition: all 0.3s ease; | |
| box-shadow: 0 4px 15px rgba(0,0,0,0.1); | |
| } | |
| .result-card:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 10px 25px rgba(0,0,0,0.2); | |
| } | |
| .nutri-circle { | |
| width: 100px; | |
| height: 100px; | |
| border-radius: 50%; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-weight: bold; | |
| margin: 0 auto; | |
| box-shadow: inset 0 0 10px rgba(0,0,0,0.1); | |
| } | |
| input[type="range"] { | |
| -webkit-appearance: none; | |
| height: 12px; | |
| border-radius: 10px; | |
| background: #e0e0e0; | |
| outline: none; | |
| } | |
| input[type="range"]::-webkit-slider-thumb { | |
| -webkit-appearance: none; | |
| appearance: none; | |
| width: 25px; | |
| height: 25px; | |
| border-radius: 50%; | |
| background: #8E2DE2; | |
| cursor: pointer; | |
| box-shadow: 0 0 5px rgba(0,0,0,0.3); | |
| } | |
| .tab-btn { | |
| transition: all 0.3s ease; | |
| box-shadow: 0 2px 5px rgba(0,0,0,0.1); | |
| } | |
| .tab-btn.active { | |
| background: linear-gradient(135deg, #8E2DE2 0%, #4A00E0 100%); | |
| color: white; | |
| transform: translateY(-2px); | |
| } | |
| .emoji-input { | |
| font-size: 1.2em; | |
| margin-right: 5px; | |
| } | |
| .pulse-animation { | |
| animation: pulse 2s infinite; | |
| } | |
| .food-card { | |
| transition: all 0.3s ease; | |
| border-radius: 12px; | |
| overflow: hidden; | |
| } | |
| .food-card:hover { | |
| transform: translateY(-3px); | |
| box-shadow: 0 10px 20px rgba(0,0,0,0.1); | |
| } | |
| .food-category { | |
| border-left: 5px solid; | |
| border-radius: 8px 0 0 8px; | |
| } | |
| .macro-slider-container { | |
| background-color: #f8f9fa; | |
| border-radius: 10px; | |
| padding: 15px; | |
| margin-bottom: 15px; | |
| } | |
| .macro-slider-label { | |
| display: flex; | |
| justify-content: space-between; | |
| margin-bottom: 5px; | |
| } | |
| .macro-percentage { | |
| font-weight: bold; | |
| color: #4A00E0; | |
| } | |
| .meal-plan-card { | |
| transition: all 0.3s ease; | |
| border-left: 4px solid; | |
| } | |
| .meal-plan-card:hover { | |
| transform: translateX(5px); | |
| } | |
| .supplement-card { | |
| transition: all 0.3s ease; | |
| border-radius: 10px; | |
| overflow: hidden; | |
| } | |
| .supplement-card:hover { | |
| transform: translateY(-3px); | |
| box-shadow: 0 10px 20px rgba(0,0,0,0.1); | |
| } | |
| @keyframes pulse { | |
| 0% { transform: scale(1); } | |
| 50% { transform: scale(1.05); } | |
| 100% { transform: scale(1); } | |
| } | |
| </style> | |
| </head> | |
| <body class="min-h-screen bg-gradient-to-br from-blue-50 to-purple-50"> | |
| <div class="gradient-bg text-white py-12 px-4 shadow-lg"> | |
| <div class="max-w-4xl mx-auto text-center"> | |
| <h1 class="text-4xl font-bold mb-4">Plan nutricional🍏</h1> | |
| <p class="text-xl opacity-90">Calcula tus necesidades nutricionales personalizadas 📊</p> | |
| </div> | |
| </div> | |
| <div class="max-w-4xl mx-auto px-4 py-8"> | |
| <div class="bg-white rounded-2xl shadow-xl p-6 mb-8 border-2 border-purple-100"> | |
| <h2 class="text-2xl font-semibold text-gray-800 mb-6 flex items-center"> | |
| <span class="emoji-input">👤</span> Datos Personales | |
| </h2> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
| <div> | |
| <label class="block text-gray-700 mb-2 flex items-center"> | |
| <span class="emoji-input">🚻</span> Género | |
| </label> | |
| <div class="flex space-x-4"> | |
| <button id="maleBtn" class="gender-btn px-4 py-3 rounded-xl bg-blue-100 text-blue-700 font-medium hover:bg-blue-200 transition duration-300 flex items-center"> | |
| <span class="emoji-input">👨</span> Hombre | |
| </button> | |
| <button id="femaleBtn" class="gender-btn px-4 py-3 rounded-xl bg-pink-100 text-pink-700 font-medium hover:bg-pink-200 transition duration-300 flex items-center"> | |
| <span class="emoji-input">👩</span> Mujer | |
| </button> | |
| </div> | |
| </div> | |
| <div> | |
| <label class="block text-gray-700 mb-2 flex items-center"> | |
| <span class="emoji-input">🎯</span> Objetivo | |
| </label> | |
| <select id="goal" class="w-full px-4 py-3 border-2 border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent"> | |
| <option value="loss">📉 Pérdida de peso</option> | |
| <option value="maintenance" selected>⚖️ Mantenimiento</option> | |
| <option value="gain">📈 Aumento de peso</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label class="block text-gray-700 mb-2 flex items-center"> | |
| <span class="emoji-input">🎂</span> Edad (años) | |
| </label> | |
| <input type="number" id="age" class="w-full px-4 py-3 border-2 border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent" min="15" max="100" value="30"> | |
| </div> | |
| <div> | |
| <label class="block text-gray-700 mb-2 flex items-center"> | |
| <span class="emoji-input">🏃</span> Nivel de actividad | |
| </label> | |
| <select id="activity" class="w-full px-4 py-3 border-2 border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent"> | |
| <option value="1.2">🛋️ Sedentario (poco o nada de ejercicio)</option> | |
| <option value="1.375">🚶♂️ Ligero (ejercicio 1-3 días/semana)</option> | |
| <option value="1.55" selected>🏋️♂️ Moderado (ejercicio 3-5 días/semana)</option> | |
| <option value="1.725">🚴♀️ Activo (ejercicio 6-7 días/semana)</option> | |
| <option value="1.9">🔥 Muy activo (ejercicio intenso diario)</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label class="block text-gray-700 mb-2 flex items-center"> | |
| <span class="emoji-input">⚖️</span> Peso (kg) | |
| </label> | |
| <input type="number" id="weight" class="w-full px-4 py-3 border-2 border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent" min="40" max="200, value="70"> | |
| </div> | |
| <div> | |
| <label class="block text-gray-700 mb-2 flex items-center"> | |
| <span class="emoji-input">📏</span> Altura (cm) | |
| </label> | |
| <input type="number" id="height" class="w-full px-4 py-3 border-2 border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent" min="140" max="220" value="170"> | |
| </div> | |
| </div> | |
| <div class="mt-6"> | |
| <div class="flex mb-4"> | |
| <button id="manualTab" class="tab-btn px-4 py-3 rounded-l-xl border-2 border-gray-200 font-medium active flex items-center"> | |
| <span class="emoji-input">✋</span> Manual | |
| </button> | |
| <button id="calculateTab" class="tab-btn px-4 py-3 rounded-r-xl border-2 border-gray-200 font-medium flex items-center"> | |
| <span class="emoji-input">🧮</span> Calcular % Grasa | |
| </button> | |
| </div> | |
| <div id="manualBodyfatSection"> | |
| <label class="block text-gray-700 mb-2 flex items-center"> | |
| <span class="emoji-input">💪</span> % Grasa corporal | |
| </label> | |
| <input type="range" id="bodyfat" class="w-full" min="5" max="50" value="20"> | |
| <div class="flex justify-between text-sm text-gray-600 mt-1"> | |
| <span>5% 🏃♂️</span> | |
| <span id="bodyfatValue">20%</span> | |
| <span>50% 🍔</span> | |
| </div> | |
| </div> | |
| <div id="calculateBodyfatSection" class="hidden"> | |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4"> | |
| <div> | |
| <label class="block text-gray-700 mb-2 flex items-center"> | |
| <span class="emoji-input">👔</span> Cuello (cm) | |
| </label> | |
| <input type="number" id="neck" class="w-full px-4 py-3 border-2 border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent" min="20" max="50" value="38"> | |
| </div> | |
| <div> | |
| <label class="block text-gray-700 mb-2 flex items-center"> | |
| <span class="emoji-input">👖</span> Cintura (cm) | |
| </label> | |
| <input type="number" id="waist" class="w-full px-4 py-3 border-2 border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent" min="50" max="150, value="80"> | |
| </div> | |
| <div id="hipSection"> | |
| <label class="block text-gray-700 mb-2 flex items-center"> | |
| <span class="emoji-input">👗</span> Cadera (cm) | |
| </label> | |
| <input type="number" id="hip" class="w-full px-4 py-3 border-2 border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent" min="60" max="150" value="95"> | |
| </div> | |
| </div> | |
| <button id="calculateBodyfatBtn" class="w-full gradient-bg-secondary text-white py-3 rounded-xl font-bold text-lg hover:opacity-90 transition duration-300 flex items-center justify-center pulse-animation"> | |
| <span class="emoji-input">🧠</span> Calcular % Grasa | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Nueva sección para personalizar macros --> | |
| <div class="mt-8"> | |
| <h3 class="text-xl font-semibold text-gray-800 mb-4 flex items-center"> | |
| <span class="emoji-input">⚖️</span> Distribución de Macronutrientes | |
| </h3> | |
| <div class="mb-4"> | |
| <div class="flex items-center mb-2"> | |
| <input type="checkbox" id="customMacrosToggle" class="mr-2 h-5 w-5"> | |
| <label for="customMacrosToggle" class="text-gray-700 font-medium flex items-center"> | |
| <span class="emoji-input">🎛️</span> Personalizar distribución de macros | |
| </label> | |
| </div> | |
| <p class="text-sm text-gray-500 mb-4">Deja desmarcado para usar valores recomendados según tu objetivo</p> | |
| </div> | |
| <div id="customMacrosSection" class="hidden"> | |
| <div class="macro-slider-container"> | |
| <div class="macro-slider-label"> | |
| <span class="flex items-center"> | |
| <span class="emoji-input">🍗</span> Proteína (%) | |
| </span> | |
| <span id="proteinPercentValue" class="macro-percentage">30%</span> | |
| </div> | |
| <input type="range" id="proteinPercent" class="w-full" min="10" max="50" value="30" step="1"> | |
| <div class="flex justify-between text-xs text-gray-500 mt-1"> | |
| <span>10%</span> | |
| <span>50%</span> | |
| </div> | |
| </div> | |
| <div class="macro-slider-container"> | |
| <div class="macro-slider-label"> | |
| <span class="flex items-center"> | |
| <span class="emoji-input">🥑</span> Grasas (%) | |
| </span> | |
| <span id="fatPercentValue" class="macro-percentage">30%</span> | |
| </div> | |
| <input type="range" id="fatPercent" class="w-full" min="10" max="50" value="30" step="1"> | |
| <div class="flex justify-between text-xs text-gray-500 mt-1"> | |
| <span>10%</span> | |
| <span>50%</span> | |
| </div> | |
| </div> | |
| <div class="macro-slider-container"> | |
| <div class="macro-slider-label"> | |
| <span class="flex items-center"> | |
| <span class="emoji-input">🍞</span> Carbohidratos (%) | |
| </span> | |
| <span id="carbsPercentValue" class="macro-percentage">40%</span> | |
| </div> | |
| <input type="range" id="carbsPercent" class="w-full" min="10, max="80" value="40" step="1"> | |
| <div class="flex justify-between text-xs text-gray-500 mt-1"> | |
| <span>10%</span> | |
| <span>80%</span> | |
| </div> | |
| <div class="mt-2 text-sm text-gray-600"> | |
| <span id="totalPercent" class="font-bold">Total: 100%</span> | |
| <span id="percentError" class="text-red-500 ml-2 hidden">⚠️ La suma debe ser 100%</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Nueva sección para seleccionar número de comidas --> | |
| <div class="mt-6"> | |
| <h3 class="text-xl font-semibold text-gray-800 mb-4 flex items-center"> | |
| <span class="emoji-input">🍽️</span> Plan de Comidas | |
| </h3> | |
| <div class="mb-4"> | |
| <label class="block text-gray-700 mb-2 flex items-center"> | |
| <span class="emoji-input">⏱️</span> Número de comidas al día | |
| </label> | |
| <select id="mealsPerDay" class="w-full px-4 py-3 border-2 border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent"> | |
| <option value="3">3 comidas (Desayuno, Almuerzo, Cena)</option> | |
| <option value="4" selected>4 comidas (Desayuno, Almuerzo, Merienda, Cena)</option> | |
| <option value="5">5 comidas (Desayuno, Media mañana, Almuerzo, Merienda, Cena)</option> | |
| <option value="6">6 comidas (3 comidas principales + 3 snacks)</option> | |
| </select> | |
| </div> | |
| </div> | |
| <div class="mt-8"> | |
| <button id="calculateBtn" class="w-full gradient-bg text-white py-4 rounded-xl font-bold text-lg hover:opacity-90 transition duration-300 flex items-center justify-center pulse-animation"> | |
| <span class="emoji-input">✨</span> Calcular mis macronutrientes | |
| </button> | |
| </div> | |
| </div> | |
| <div id="results" class="hidden bg-white rounded-2xl shadow-xl p-6 mb-8 border-2 border-purple-100"> | |
| <h2 class="text-2xl font-semibold text-gray-800 mb-6 flex items-center"> | |
| <span class="emoji-input">📊</span> Tus resultados nutricionales | |
| </h2> | |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8"> | |
| <div class="result-card bg-gradient-to-br from-blue-50 to-indigo-50 rounded-2xl p-6 text-center border-2 border-blue-100"> | |
| <div class="nutri-circle bg-gradient-to-br from-blue-100 to-blue-200 text-blue-700 text-3xl mb-4" id="caloriesCircle">0</div> | |
| <h3 class="text-xl font-semibold text-blue-800 mb-2 flex items-center justify-center"> | |
| <span class="emoji-input">🔥</span> Calorías diarias | |
| </h3> | |
| <p class="text-gray-600">Recomendación basada en tus datos</p> | |
| </div> | |
| <div class="result-card bg-gradient-to-br from-green-50 to-teal-50 rounded-2xl p-6 text-center border-2 border-green-100"> | |
| <div class="nutri-circle bg-gradient-to-br from-green-100 to-green-200 text-green-700 text-3xl mb-4" id="proteinCircle">0g</div> | |
| <h3 class="text-xl font-semibold text-green-800 mb-2 flex items-center justify-center"> | |
| <span class="emoji-input">🍗</span> Proteína | |
| </h3> | |
| <p class="text-gray-600">Esencial para músculos y recuperación</p> | |
| </div> | |
| <div class="result-card bg-gradient-to-br from-yellow-50 to-amber-50 rounded-2xl p-6 text-center border-2 border-yellow-100"> | |
| <div class="nutri-circle bg-gradient-to-br from-yellow-100 to-yellow-200 text-yellow-700 text-3xl mb-4" id="carbsCircle">0g</div> | |
| <h3 class="text-xl font-semibold text-yellow-800 mb-2 flex items-center justify-center"> | |
| <span class="emoji-input">🍞</span> Carbohidratos | |
| </h3> | |
| <p class="text-gray-600">Energía para tu día y entrenamientos</p> | |
| </div> | |
| </div> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
| <div class="result-card bg-gradient-to-br from-purple-50 to-indigo-50 rounded-2xl p-6 border-2 border-purple-100"> | |
| <h3 class="text-xl font-semibold text-purple-800 mb-4 flex items-center"> | |
| <span class="emoji-input">📊</span> Distribución de macronutrientes | |
| </h3> | |
| <div class="h-64 flex items-center justify-center"> | |
| <canvas id="macrosChart"></canvas> | |
| </div> | |
| </div> | |
| <div class="result-card bg-gradient-to-br from-red-50 to-pink-50 rounded-2xl p-6 border-2 border-red-100"> | |
| <h3 class="text-xl font-semibold text-red-800 mb-4 flex items-center"> | |
| <span class="emoji-input">🔍</span> Detalles nutricionales | |
| </h3> | |
| <div class="space-y-4"> | |
| <div class="flex justify-between items-center"> | |
| <span class="text-gray-700 flex items-center"> | |
| <span class="emoji-input">🥑</span> Grasas | |
| </span> | |
| <span class="font-semibold text-red-700" id="fatValue">0g</span> | |
| </div> | |
| <div class="w-full bg-gray-200 rounded-full h-3"> | |
| <div id="fatBar" class="bg-gradient-to-r from-red-400 to-red-600 h-3 rounded-full" style="width: 0%"></div> | |
| </div> | |
| <div class="flex justify-between items-center"> | |
| <span class="text-gray-700 flex items-center"> | |
| <span class="emoji-input">🍗</span> Proteína | |
| </span> | |
| <span class="font-semibold text-blue-700" id="proteinValue">0g</span> | |
| </div> | |
| <div class="w-full bg-gray-200 rounded-full h-3"> | |
| <div id="proteinBar" class="bg-gradient-to-r from-blue-400 to-blue-600 h-3 rounded-full" style="width: 0%"></div> | |
| </div> | |
| <div class="flex justify-between items-center"> | |
| <span class="text-gray-700 flex items-center"> | |
| <span class="emoji-input">🍞</span> Carbohidratos | |
| </span> | |
| <span class="font-semibold text-yellow-700" id="carbsValue">0g</span> | |
| </div> | |
| <div class="w-full bg-gray-200 rounded-full h-3"> | |
| <div id="carbsBar" class="bg-gradient-to-r from-yellow-400 to-yellow-600 h-3 rounded-full" style="width: 0%"></div> | |
| </div> | |
| <div class="pt-4 border-t border-gray-200"> | |
| <div class="flex justify-between items-center"> | |
| <span class="text-gray-700 font-medium flex items-center"> | |
| <span class="emoji-input">💧</span> Agua recomendada | |
| </span> | |
| <span class="font-semibold text-blue-700" id="waterValue">0L</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Nueva sección de plan de comidas --> | |
| <div class="mt-8 bg-gradient-to-br from-gray-50 to-gray-100 rounded-2xl p-6 border-2 border-gray-200"> | |
| <h3 class="text-xl font-semibold text-gray-800 mb-4 flex items-center"> | |
| <span class="emoji-input">🍽️</span> Plan de Comidas Diario | |
| </h3> | |
| <div id="mealPlanContainer" class="space-y-4"> | |
| <!-- El plan de comidas se generará aquí dinámicamente --> | |
| </div> | |
| </div> | |
| <!-- Nueva sección de suplementos recomendados --> | |
| <div class="mt-8 bg-gradient-to-br from-gray-50 to-gray-100 rounded-2xl p-6 border-2 border-gray-200"> | |
| <h3 class="text-xl font-semibold text-gray-800 mb-4 flex items-center"> | |
| <span class="emoji-input">💊</span> Suplementos recomendados | |
| </h3> | |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-4" id="supplementsContainer"> | |
| <!-- Los suplementos se generarán aquí dinámicamente --> | |
| </div> | |
| </div> | |
| <!-- Nueva sección de alimentos recomendados --> | |
| <div class="mt-8 bg-gradient-to-br from-gray-50 to-gray-100 rounded-2xl p-6 border-2 border-gray-200"> | |
| <h3 class="text-xl font-semibold text-gray-800 mb-4 flex items-center"> | |
| <span class="emoji-input">🍽️</span> Alimentos recomendados para tus macros | |
| </h3> | |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-4" id="foodRecommendations"> | |
| <!-- Proteínas --> | |
| <div class="food-card bg-gradient-to-br from-green-50 to-teal-50 border-2 border-green-100"> | |
| <div class="food-category bg-green-500 p-4"> | |
| <h4 class="text-lg font-bold text-white flex items-center"> | |
| <span class="emoji-input">🍗</span> Proteínas | |
| </h4> | |
| </div> | |
| <div class="p-4"> | |
| <ul class="space-y-2"> | |
| <li class="flex items-start"> | |
| <span class="text-green-500 mr-2">•</span> | |
| <span>Pechuga de pollo 🐔 (30g proteína/100g)</span> | |
| </li> | |
| <li class="flex items-start"> | |
| <span class="text-green-500 mr-2">•</span> | |
| <span>Salmón 🐟 (25g proteína/100g)</span> | |
| </li> | |
| <li class="flex items-start"> | |
| <span class="text-green-500 mr-2">•</span> | |
| <span>Huevos 🥚 (6g proteína/huevo)</span> | |
| </li> | |
| <li class="flex items-start"> | |
| <span class="text-green-500 mr-2">•</span> | |
| <span>Garbanzos 🌱 (19g proteína/100g)</span> | |
| </li> | |
| <li class="flex items-start"> | |
| <span class="text-green-500 mr-2">•</span> | |
| <span>Requesón 🧀 (12g proteína/100g)</span> | |
| </li> | |
| </ul> | |
| </div> | |
| </div> | |
| <!-- Carbohidratos --> | |
| <div class="food-card bg-gradient-to-br from-yellow-50 to-amber-50 border-2 border-yellow-100"> | |
| <div class="food-category bg-yellow-500 p-4"> | |
| <h4 class="text-lg font-bold text-white flex items-center"> | |
| <span class="emoji-input">🍞</span> Carbohidratos | |
| </h4> | |
| </div> | |
| <div class="p-4"> | |
| <ul class="space-y-2"> | |
| <li class="flex items-start"> | |
| <span class="text-yellow-500 mr-2">•</span> | |
| <span>Arroz integral 🍚 (28g carbos/100g)</span> | |
| </li> | |
| <li class="flex items-start"> | |
| <span class="text-yellow-500 mr-2">•</span> | |
| <span>Avena 🥣 (66g carbos/100g)</span> | |
| </li> | |
| <li class="flex items-start"> | |
| <span class="text-yellow-500 mr-2">•</span> | |
| <span>Batata 🍠 (20g carbos/100g)</span> | |
| </li> | |
| <li class="flex items-start"> | |
| <span class="text-yellow-500 mr-2">•</span> | |
| <span>Plátano 🍌 (23g carbos/100g)</span> | |
| </li> | |
| <li class="flex items-start"> | |
| <span class="text-yellow-500 mr-2">•</span> | |
| <span>Quinoa 🌾 (21g carbos/100g)</span> | |
| </li> | |
| </ul> | |
| </div> | |
| </div> | |
| <!-- Grasas saludables --> | |
| <div class="food-card bg-gradient-to-br from-red-50 to-pink-50 border-2 border-red-100"> | |
| <div class="food-category bg-red-500 p-4"> | |
| <h4 class="text-lg font-bold text-white flex items-center"> | |
| <span class="emoji-input">🥑</span> Grasas saludables | |
| </h4> | |
| </div> | |
| <div class="p-4"> | |
| <ul class="space-y-2"> | |
| <li class="flex items-start"> | |
| <span class="text-red-500 mr-2">•</span> | |
| <span>Aguacate 🥑 (15g grasas/100g)</span> | |
| </li> | |
| <li class="flex items-start"> | |
| <span class="text-red-500 mr-2">•</span> | |
| <span>Almendras 🥜 (49g grasas/100g)</span> | |
| </li> | |
| <li class="flex items-start"> | |
| <span class="text-red-500 mr-2">•</span> | |
| <span>Aceite de oliva 🫒 (100g grasas/100g)</span> | |
| </li> | |
| <li class="flex items-start"> | |
| <span class="text-red-500 mr-2">•</span> | |
| <span>Salmón 🐟 (13g grasas/100g)</span> | |
| </li> | |
| <li class="flex items-start"> | |
| <span class="text-red-500 mr-2">•</span> | |
| <span>Semillas de chía 🌱 (31g grasas/100g)</span> | |
| </li> | |
| </ul> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="mt-6 bg-white p-4 rounded-lg border border-gray-200"> | |
| <h4 class="text-lg font-semibold text-gray-800 mb-3 flex items-center"> | |
| <span class="emoji-input">💡</span> Ideas de comidas balanceadas | |
| </h4> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
| <div class="bg-blue-50 p-3 rounded-lg border border-blue-100"> | |
| <p class="font-medium text-blue-800">Desayuno:</p> | |
| <p>🥣 Avena con plátano y almendras + 🥚 Huevos revueltos</p> | |
| </div> | |
| <div class="bg-green-50 p-3 rounded-lg border border-green-100"> | |
| <p class="font-medium text-green-800">Almuerzo:</p> | |
| <p>🍗 Pechuga a la plancha + 🍚 Arroz integral + 🥑 Aguacate</p> | |
| </div> | |
| <div class="bg-yellow-50 p-3 rounded-lg border border-yellow-100"> | |
| <p class="font-medium text-yellow-800">Merienda:</p> | |
| <p>🧀 Requesón con semillas de chía + 🍎 Manzana</p> | |
| </div> | |
| <div class="bg-purple-50 p-3 rounded-lg border border-purple-100"> | |
| <p class="font-medium text-purple-800">Cena:</p> | |
| <p>🐟 Salmón al horno + 🍠 Batata asada + 🥦 Brócoli</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="mt-8 bg-gradient-to-br from-gray-50 to-gray-100 rounded-2xl p-6 border-2 border-gray-200"> | |
| <h3 class="text-xl font-semibold text-gray-800 mb-4 flex items-center"> | |
| <span class="emoji-input">💡</span> Recomendaciones personalizadas | |
| </h3> | |
| <div id="recommendations" class="space-y-3 text-gray-700"> | |
| <!-- Las recomendaciones se generarán aquí --> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | |
| <script> | |
| // Variables globales | |
| let gender = 'male'; | |
| let macrosChart = null; | |
| // Event listeners | |
| document.getElementById('maleBtn').addEventListener('click', () => setGender('male')); | |
| document.getElementById('femaleBtn').addEventListener('click', () => setGender('female')); | |
| document.getElementById('bodyfat').addEventListener('input', updateBodyfatValue); | |
| document.getElementById('calculateBtn').addEventListener('click', calculateNutrition); | |
| document.getElementById('manualTab').addEventListener('click', () => switchBodyfatTab('manual')); | |
| document.getElementById('calculateTab').addEventListener('click', () => switchBodyfatTab('calculate')); | |
| document.getElementById('calculateBodyfatBtn').addEventListener('click', calculateBodyfatPercentage); | |
| document.getElementById('customMacrosToggle').addEventListener('change', toggleCustomMacros); | |
| // Sliders de macros personalizados | |
| document.getElementById('proteinPercent').addEventListener('input', updateMacroPercentages); | |
| document.getElementById('fatPercent').addEventListener('input', updateMacroPercentages); | |
| document.getElementById('carbsPercent').addEventListener('input', updateMacroPercentages); | |
| // Funciones | |
| function setGender(selectedGender) { | |
| gender = selectedGender; | |
| document.querySelectorAll('.gender-btn').forEach(btn => { | |
| btn.classList.remove('gradient-bg', 'text-white'); | |
| if (btn.id === 'maleBtn') { | |
| btn.classList.add('bg-blue-100', 'text-blue-700'); | |
| } else { | |
| btn.classList.add('bg-pink-100', 'text-pink-700'); | |
| } | |
| }); | |
| if (selectedGender === 'male') { | |
| document.getElementById('maleBtn').classList.remove('bg-blue-100', 'text-blue-700'); | |
| document.getElementById('maleBtn').classList.add('gradient-bg', 'text-white'); | |
| document.getElementById('hipSection').classList.add('hidden'); | |
| } else { | |
| document.getElementById('femaleBtn').classList.remove('bg-pink-100', 'text-pink-700'); | |
| document.getElementById('femaleBtn').classList.add('gradient-bg', 'text-white'); | |
| document.getElementById('hipSection').classList.remove('hidden'); | |
| } | |
| } | |
| function switchBodyfatTab(tab) { | |
| if (tab === 'manual') { | |
| document.getElementById('manualTab').classList.add('active'); | |
| document.getElementById('calculateTab').classList.remove('active'); | |
| document.getElementById('manualBodyfatSection').classList.remove('hidden'); | |
| document.getElementById('calculateBodyfatSection').classList.add('hidden'); | |
| } else { | |
| document.getElementById('manualTab').classList.remove('active'); | |
| document.getElementById('calculateTab').classList.add('active'); | |
| document.getElementById('manualBodyfatSection').classList.add('hidden'); | |
| document.getElementById('calculateBodyfatSection').classList.remove('hidden'); | |
| } | |
| } | |
| function updateBodyfatValue() { | |
| const bodyfat = document.getElementById('bodyfat').value; | |
| document.getElementById('bodyfatValue').textContent = `${bodyfat}%`; | |
| } | |
| function toggleCustomMacros() { | |
| const customMacrosSection = document.getElementById('customMacrosSection'); | |
| if (document.getElementById('customMacrosToggle').checked) { | |
| customMacrosSection.classList.remove('hidden'); | |
| // Actualizar porcentajes iniciales | |
| updateMacroPercentages(); | |
| } else { | |
| customMacrosSection.classList.add('hidden'); | |
| } | |
| } | |
| function updateMacroPercentages() { | |
| const proteinPercent = parseInt(document.getElementById('proteinPercent').value); | |
| const fatPercent = parseInt(document.getElementById('fatPercent').value); | |
| const carbsPercent = parseInt(document.getElementById('carbsPercent').value); | |
| // Actualizar valores mostrados | |
| document.getElementById('proteinPercentValue').textContent = `${proteinPercent}%`; | |
| document.getElementById('fatPercentValue').textContent = `${fatPercent}%`; | |
| document.getElementById('carbsPercentValue').textContent = `${carbsPercent}%`; | |
| // Calcular total | |
| const total = proteinPercent + fatPercent + carbsPercent; | |
| document.getElementById('totalPercent').textContent = `Total: ${total}%`; | |
| // Mostrar error si no suma 100% | |
| const errorElement = document.getElementById('percentError'); | |
| if (total !== 100) { | |
| errorElement.classList.remove('hidden'); | |
| } else { | |
| errorElement.classList.add('hidden'); | |
| } | |
| } | |
| function calculateBodyfatPercentage() { | |
| const neck = parseFloat(document.getElementById('neck').value); | |
| const waist = parseFloat(document.getElementById('waist').value); | |
| const height = parseFloat(document.getElementById('height').value); | |
| // Fórmula de la Marina de EE.UU. para calcular % de grasa corporal | |
| let bodyfatPercentage; | |
| if (gender === 'male') { | |
| // Fórmula para hombres | |
| bodyfatPercentage = 86.010 * Math.log10(waist - neck) - 70.041 * Math.log10(height) + 36.76; | |
| } else { | |
| // Fórmula para mujeres (necesita medida de cadera) | |
| const hip = parseFloat(document.getElementById('hip').value); | |
| bodyfatPercentage = 163.205 * Math.log10(waist + hip - neck) - 97.684 * Math.log10(height) - 78.387; | |
| } | |
| // Asegurarse que el porcentaje esté dentro de límites razonables | |
| bodyfatPercentage = Math.max(5, Math.min(50, bodyfatPercentage)); | |
| // Actualizar el slider y el valor mostrado | |
| document.getElementById('bodyfat').value = Math.round(bodyfatPercentage); | |
| document.getElementById('bodyfatValue').textContent = `${Math.round(bodyfatPercentage)}%`; | |
| // Mostrar notificación de éxito | |
| alert(`🎉 Tu porcentaje de grasa corporal calculado es: ${Math.round(bodyfatPercentage)}%`); | |
| // Cambiar a la pestaña manual para mostrar el resultado | |
| switchBodyfatTab('manual'); | |
| } | |
| function calculateNutrition() { | |
| // Obtener valores del formulario | |
| const age = parseInt(document.getElementById('age').value); | |
| const weight = parseFloat(document.getElementById('weight').value); | |
| const height = parseFloat(document.getElementById('height').value); | |
| const activity = parseFloat(document.getElementById('activity').value); | |
| const goal = document.getElementById('goal').value; | |
| const bodyfat = parseInt(document.getElementById('bodyfat').value) || 20; | |
| const useCustomMacros = document.getElementById('customMacrosToggle').checked; | |
| const mealsPerDay = parseInt(document.getElementById('mealsPerDay').value); | |
| // Validaciones básicas | |
| if (age < 15 || age > 100 || weight < 40 || weight > 200 || height < 140 || height > 220) { | |
| alert('⚠️ Por favor ingresa valores válidos en todos los campos'); | |
| return; | |
| } | |
| // Validar porcentajes de macros si está usando valores personalizados | |
| if (useCustomMacros) { | |
| const proteinPercent = parseInt(document.getElementById('proteinPercent').value); | |
| const fatPercent = parseInt(document.getElementById('fatPercent').value); | |
| const carbsPercent = parseInt(document.getElementById('carbsPercent').value); | |
| const total = proteinPercent + fatPercent + carbsPercent; | |
| if (total !== 100) { | |
| alert('⚠️ La suma de los porcentajes de macronutrientes debe ser exactamente 100%'); | |
| return; | |
| } | |
| } | |
| // Calcular calorías (Harris-Benedict revisada por Mifflin-St Jeor) | |
| let bmr; | |
| if (gender === 'male') { | |
| bmr = 10 * weight + 6.25 * height - 5 * age + 5; | |
| } else { | |
| bmr = 10 * weight + 6.25 * height - 5 * age - 161; | |
| } | |
| let tdee = bmr * activity; | |
| // Ajustar según objetivo | |
| let calorieAdjustment = 0; | |
| switch(goal) { | |
| case 'loss': | |
| calorieAdjustment = -500; | |
| break; | |
| case 'gain': | |
| calorieAdjustment = 500; | |
| break; | |
| default: | |
| calorieAdjustment = 0; | |
| } | |
| const dailyCalories = Math.round(tdee + calorieAdjustment); | |
| // Calcular macronutrientes | |
| let proteinGrams, fatGrams, carbsGrams; | |
| if (useCustomMacros) { | |
| // Usar porcentajes personalizados | |
| const proteinPercent = parseInt(document.getElementById('proteinPercent').value); | |
| const fatPercent = parseInt(document.getElementById('fatPercent').value); | |
| const carbsPercent = parseInt(document.getElementById('carbsPercent').value); | |
| proteinGrams = Math.round((dailyCalories * proteinPercent / 100) / 4); | |
| fatGrams = Math.round((dailyCalories * fatPercent / 100) / 9); | |
| carbsGrams = Math.round((dailyCalories * carbsPercent / 100) / 4); | |
| } else { | |
| // Usar valores recomendados según objetivo | |
| // Proteína: 2.2g/kg para pérdida de peso, 1.8g/kg para mantenimiento, 1.6g/kg para aumento | |
| let proteinPerKg; | |
| if (goal === 'loss') { | |
| proteinPerKg = 2.2; | |
| } else if (goal === 'maintenance') { | |
| proteinPerKg = 1.8; | |
| } else { | |
| proteinPerKg = 1.6; | |
| } | |
| // Ajustar proteína si hay % grasa alto (>25%) | |
| if (bodyfat > 25) { | |
| proteinPerKg = Math.min(proteinPerKg + 0.2, 2.5); | |
| } | |
| proteinGrams = Math.round(weight * proteinPerKg); | |
| const proteinCalories = proteinGrams * 4; | |
| // Grasas: 25-35% de calorías | |
| const fatPercentage = 0.3; // 30% | |
| const fatCalories = Math.round(dailyCalories * fatPercentage); | |
| fatGrams = Math.round(fatCalories / 9); | |
| // Carbohidratos: resto de calorías | |
| const carbsCalories = dailyCalories - proteinCalories - fatCalories; | |
| carbsGrams = Math.round(carbsCalories / 4); | |
| } | |
| // Agua recomendada | |
| const waterIntake = Math.round((weight * 0.035) * 10) / 10; // 35ml por kg | |
| // Mostrar resultados | |
| document.getElementById('caloriesCircle').textContent = dailyCalories; | |
| document.getElementById('proteinCircle').textContent = `${proteinGrams}g`; | |
| document.getElementById('carbsCircle').textContent = `${carbsGrams}g`; | |
| document.getElementById('proteinValue').textContent = `${proteinGrams}g`; | |
| document.getElementById('carbsValue').textContent = `${carbsGrams}g`; | |
| document.getElementById('fatValue').textContent = `${fatGrams}g`; | |
| document.getElementById('waterValue').textContent = `${waterIntake}L`; | |
| // Actualizar barras de progreso | |
| document.getElementById('proteinBar').style.width = `${Math.min(proteinGrams / weight * 50, 100)}%`; | |
| document.getElementById('carbsBar').style.width = `${Math.min(carbsGrams / (weight * 3) * 100, 100)}%`; | |
| document.getElementById('fatBar').style.width = `${Math.min(fatGrams / (weight * 1.2) * 100, 100)}%`; | |
| // Generar recomendaciones | |
| generateRecommendations(goal, dailyCalories, proteinGrams, carbsGrams, fatGrams, waterIntake, useCustomMacros); | |
| // Generar plan de comidas | |
| generateMealPlan(mealsPerDay, dailyCalories, proteinGrams, carbsGrams, fatGrams); | |
| // Generar suplementos recomendados | |
| generateSupplementRecommendations(goal, proteinGrams, carbsGrams, fatGrams); | |
| // Crear/actualizar gráfico | |
| updateChart(proteinGrams, carbsGrams, fatGrams); | |
| // Mostrar resultados | |
| document.getElementById('results').classList.remove('hidden'); | |
| // Scroll a resultados | |
| document.getElementById('results').scrollIntoView({ behavior: 'smooth' }); | |
| } | |
| function generateSupplementRecommendations(goal, proteinGrams, carbsGrams, fatGrams) { | |
| const supplementsContainer = document.getElementById('supplementsContainer'); | |
| supplementsContainer.innerHTML = ''; | |
| // Suplementos de proteína | |
| const proteinSupplements = [ | |
| { name: 'Proteína de suero (Whey) 🥛', benefit: 'Absorción rápida, ideal post-entreno', dosage: `${Math.round(proteinGrams*0.2/25)} scoop(s) (25g proteína)'` }, | |
| { name: 'Proteína caseína 🧀', benefit: 'Absorción lenta, ideal para la noche', dosage: `${Math.round(proteinGrams*0.2/25)} scoop(s) (25g proteína)'` }, | |
| { name: 'Proteína vegetal 🌱', benefit: 'Opción vegana (arroz, guisante, etc.)', dosage: `${Math.round(proteinGrams*0.2/20)} scoop(s) (20g proteína)'` }, | |
| { name: 'BCAA 🧬', benefit: 'Aminoácidos esenciales para recuperación', dosage: '5-10g durante/post entreno' } | |
| ]; | |
| // Suplementos de carbohidratos | |
| const carbSupplements = [ | |
| { name: 'Maltodextrina 🏋️', benefit: 'Carbohidrato de rápida absorción', dosage: `${Math.round(carbsGrams*0.1/25)} cucharadas (25g carbos)'` }, | |
| { name: 'Dextrosa 🍬', benefit: 'Azúcar simple para energía rápida', dosage: `${Math.round(carbsGrams*0.1/25)} cucharadas (25g carbos)'` }, | |
| { name: 'Vitargo 🚀', benefit: 'Carbohidrato de alto peso molecular', dosage: `${Math.round(carbsGrams*0.1/50)} scoop(s) (50g carbos)'` } | |
| ]; | |
| // Suplementos de grasas | |
| const fatSupplements = [ | |
| { name: 'Omega-3 🐟', benefit: 'Ácidos grasos esenciales EPA/DHA', dosage: '1-3g diarios' }, | |
| { name: 'MCT Oil 🥥', benefit: 'Grasas de cadena media para energía', dosage: '5-15ml en batidos' }, | |
| { name: 'Aceite de coco 🥥', benefit: 'Fuente de ácido láurico', dosage: '5-15ml en comidas' } | |
| ]; | |
| // Suplementos generales | |
| const generalSupplements = [ | |
| { name: 'Creatina 💪', benefit: 'Mejora fuerza y recuperación muscular', dosage: '5g diarios' }, | |
| { name: 'Multivitamínico 🍊', benefit: 'Asegura ingesta de micronutrientes', dosage: '1 comprimido diario' }, | |
| { name: 'Vitamina D3 ☀️', benefit: 'Salud ósea y función muscular', dosage: '1000-5000 UI diarios' }, | |
| { name: 'Magnesio 🧘', benefit: 'Relajación muscular y sueño', dosage: '200-400mg antes de dormir' } | |
| ]; | |
| // Crear tarjetas de suplementos | |
| createSupplementCard('Proteína 🍗', proteinSupplements, 'from-green-50 to-teal-50', 'border-green-100'); | |
| createSupplementCard('Carbohidratos 🍞', carbSupplements, 'from-yellow-50 to-amber-50', 'border-yellow-100'); | |
| createSupplementCard('Grasas 🥑', fatSupplements, 'from-red-50 to-pink-50', 'border-red-100'); | |
| // Suplementos adicionales según objetivo | |
| const goalSpecificSupplements = []; | |
| if (goal === 'loss') { | |
| goalSpecificSupplements.push( | |
| { name: 'Cafeína ☕', benefit: 'Aumenta metabolismo y energía', dosage: '200-400mg pre-entreno' }, | |
| { name: 'L-Carnitina 🏃', benefit: 'Transporte de ácidos grasos', dosage: '1-3g diarios' }, | |
| { name: 'Té verde 🍵', benefit: 'Contiene EGCG para metabolismo', dosage: '2-3 tazas diarias' } | |
| ); | |
| } else if (goal === 'gain') { | |
| goalSpecificSupplements.push( | |
| { name: 'Gainer 🏋️', benefit: 'Mezcla de proteína y carbohidratos', dosage: `${Math.round(carbsGrams*0.2/50)} scoop(s) (50g carbos + 25g proteína)'` }, | |
| { name: 'HMB 🛡️', benefit: 'Reduce degradación muscular', dosage: '3g diarios' }, | |
| { name: 'Glutamina 🧠', benefit: 'Recuperación y salud intestinal', dosage: '5-10g diarios' } | |
| ); | |
| } | |
| if (goalSpecificSupplements.length > 0) { | |
| createSupplementCard( | |
| goal === 'loss' ? 'Pérdida de peso 📉' : 'Aumento muscular 📈', | |
| goalSpecificSupplements, | |
| 'from-purple-50 to-indigo-50', | |
| 'border-purple-100' | |
| ); | |
| } | |
| // Suplementos generales | |
| createSupplementCard('General 🧪', generalSupplements, 'from-blue-50 to-indigo-50', 'border-blue-100'); | |
| function createSupplementCard(title, supplements, bgGradient, borderClass) { | |
| const card = document.createElement('div'); | |
| card.className = `supplement-card bg-gradient-to-br ${bgGradient} border-2 ${borderClass}`; | |
| let html = ` | |
| <div class="p-4"> | |
| <h4 class="text-lg font-bold text-gray-800 mb-3">${title}</h4> | |
| <div class="space-y-3"> | |
| `; | |
| supplements.forEach(supp => { | |
| html += ` | |
| <div class="bg-white bg-opacity-50 p-3 rounded-lg"> | |
| <p class="font-semibold text-gray-800">${supp.name}</p> | |
| <p class="text-sm text-gray-600">${supp.benefit}</p> | |
| <p class="text-xs text-gray-500 mt-1">Dosis: ${supp.dosage}</p> | |
| </div> | |
| `; | |
| }); | |
| html += ` | |
| </div> | |
| </div> | |
| `; | |
| card.innerHTML = html; | |
| supplementsContainer.appendChild(card); | |
| } | |
| } | |
| function generateMealPlan(mealsPerDay, calories, protein, carbs, fat) { | |
| const mealPlanContainer = document.getElementById('mealPlanContainer'); | |
| mealPlanContainer.innerHTML = ''; | |
| // Calcular macros por comida | |
| const proteinPerMeal = Math.round(protein / mealsPerDay); | |
| const carbsPerMeal = Math.round(carbs / mealsPerDay); | |
| const fatPerMeal = Math.round(fat / mealsPerDay); | |
| const caloriesPerMeal = Math.round(calories / mealsPerDay); | |
| // Definir nombres de comidas según cantidad | |
| const mealNames = { | |
| 3: ['Desayuno', 'Almuerzo', 'Cena'], | |
| 4: ['Desayuno', 'Almuerzo', 'Merienda', 'Cena'], | |
| 5: ['Desayuno', 'Media mañana', 'Almuerzo', 'Merienda', 'Cena'], | |
| 6: ['Desayuno', 'Snack mañana', 'Almuerzo', 'Merienda', 'Cena', 'Snack noche'] | |
| }; | |
| // Generar cada comida | |
| for (let i = 0; i < mealsPerDay; i++) { | |
| const mealName = mealNames[mealsPerDay][i]; | |
| const mealType = getMealType(i, mealsPerDay); | |
| const mealCard = document.createElement('div'); | |
| mealCard.className = `meal-plan-card bg-white p-4 rounded-lg shadow-sm border-l-4 ${getMealColorClass(mealType)}`; | |
| // Sugerir alimentos según el tipo de comida | |
| const foodSuggestions = getFoodSuggestions(mealType, proteinPerMeal, carbsPerMeal, fatPerMeal); | |
| mealCard.innerHTML = ` | |
| <div class="flex justify-between items-start mb-2"> | |
| <h4 class="text-lg font-semibold text-gray-800 flex items-center"> | |
| <span class="emoji-input">${getMealEmoji(mealType)}</span> ${mealName} | |
| </h4> | |
| <span class="text-sm font-medium text-gray-500">${caloriesPerMeal} kcal</span> | |
| </div> | |
| <div class="grid grid-cols-3 gap-2 text-sm mb-3"> | |
| <div class="bg-blue-50 text-blue-700 px-2 py-1 rounded text-center"> | |
| <span class="font-medium">${proteinPerMeal}g</span> proteína | |
| </div> | |
| <div class="bg-yellow-50 text-yellow-700 px-2 py-1 rounded text-center"> | |
| <span class="font-medium">${carbsPerMeal}g</span> carbos | |
| </div> | |
| <div class="bg-red-50 text-red-700 px-2 py-1 rounded text-center"> | |
| <span class="font-medium">${fatPerMeal}g</span> grasas | |
| </div> | |
| </div> | |
| <div class="text-sm text-gray-700"> | |
| <p class="font-medium mb-1">Sugerencias:</p> | |
| <ul class="list-disc list-inside space-y-1"> | |
| ${foodSuggestions.map(item => `<li>${item}</li>`).join('')} | |
| </ul> | |
| </div> | |
| `; | |
| mealPlanContainer.appendChild(mealCard); | |
| } | |
| } | |
| function getMealType(mealIndex, totalMeals) { | |
| if (totalMeals === 3) { | |
| return mealIndex === 0 ? 'breakfast' : mealIndex === 1 ? 'lunch' : 'dinner'; | |
| } else if (totalMeals === 4) { | |
| return mealIndex === 0 ? 'breakfast' : mealIndex === 1 ? 'lunch' : mealIndex === 2 ? 'snack' : 'dinner'; | |
| } else if (totalMeals === 5) { | |
| return mealIndex === 0 ? 'breakfast' : mealIndex === 1 ? 'snack' : mealIndex === 2 ? 'lunch' : mealIndex === 3 ? 'snack' : 'dinner'; | |
| } else { | |
| return mealIndex === 0 ? 'breakfast' : mealIndex % 2 === 1 ? 'snack' : mealIndex === 2 ? 'lunch' : 'dinner'; | |
| } | |
| } | |
| function getMealColorClass(mealType) { | |
| switch(mealType) { | |
| case 'breakfast': return 'border-blue-400 bg-blue-50'; | |
| case 'lunch': return 'border-green-400 bg-green-50'; | |
| case 'dinner': return 'border-purple-400 bg-purple-50'; | |
| case 'snack': return 'border-yellow-400 bg-yellow-50'; | |
| default: return 'border-gray-400 bg-gray-50'; | |
| } | |
| } | |
| function getMealEmoji(mealType) { | |
| switch(mealType) { | |
| case 'breakfast': return '🥣'; | |
| case 'lunch': return '🍲'; | |
| case 'dinner': return '🍽️'; | |
| case 'snack': return '🍎'; | |
| default: return '🍴'; | |
| } | |
| } | |
| function getFoodSuggestions(mealType, protein, carbs, fat) { | |
| const suggestions = []; | |
| // Proteínas | |
| if (mealType === 'breakfast') { | |
| suggestions.push(`Huevos (${Math.min(3, Math.round(protein/6))} unidades)`); | |
| suggestions.push(`Requesón (${Math.round(protein/12*100)}g)`); | |
| } else if (mealType === 'lunch' || mealType === 'dinner') { | |
| suggestions.push(`Pollo (${Math.round(protein/30*100)}g)`); | |
| suggestions.push(`Pescado (${Math.round(protein/25*100)}g)`); | |
| } else { | |
| suggestions.push(`Yogur griego (${Math.round(protein/10*100)}g)`); | |
| } | |
| // Carbohidratos | |
| if (mealType === 'breakfast') { | |
| suggestions.push(`Avena (${Math.round(carbs/66*100)}g)`); | |
| suggestions.push(`Pan integral (${Math.round(carbs/50*100)}g)`); | |
| } else if (mealType === 'lunch' || mealType === 'dinner') { | |
| suggestions.push(`Arroz integral (${Math.round(carbs/28*100)}g)`); | |
| suggestions.push(`Quinoa (${Math.round(carbs/21*100)}g)`); | |
| } else { | |
| suggestions.push(`Fruta (${Math.round(carbs/20*100)}g)`); | |
| } | |
| // Grasas | |
| if (mealType === 'breakfast') { | |
| suggestions.push(`Aguacate (${Math.round(fat/15*100)}g)`); | |
| } else if (mealType === 'lunch' || mealType === 'dinner') { | |
| suggestions.push(`Aceite de oliva (${Math.round(fat/100*10)}ml)`); | |
| } else { | |
| suggestions.push(`Frutos secos (${Math.round(fat/50*30)}g)`); | |
| } | |
| return suggestions; | |
| } | |
| function generateRecommendations(goal, dailyCalories, proteinGrams, carbsGrams, fatGrams, waterIntake, useCustomMacros) { | |
| const recommendationsEl = document.getElementById('recommendations'); | |
| recommendationsEl.innerHTML = ''; | |
| // Recomendación general según objetivo | |
| let goalRecommendation = ''; | |
| switch(goal) { | |
| case 'loss': | |
| goalRecommendation = 'Para pérdida de peso 🏃♂️, mantén un déficit calórico constante y prioriza proteínas para preservar masa muscular 💪.'; | |
| break; | |
| case 'maintenance': | |
| goalRecommendation = 'Para mantenimiento ⚖️, sigue una dieta balanceada y mantén tus niveles de actividad 🚶♀️.'; | |
| break; | |
| case 'gain': | |
| goalRecommendation = 'Para aumento de peso 📈, asegúrate de consumir suficientes calorías y proteínas para apoyar el crecimiento muscular 🏋️♂️.'; | |
| break; | |
| } | |
| addRecommendation(goalRecommendation); | |
| if (useCustomMacros) { | |
| addRecommendation('Estás usando una distribución personalizada de macronutrientes 🎛️. Asegúrate de seguir tus porcentajes establecidos.'); | |
| } else { | |
| // Recomendación basada en valores por defecto | |
| addRecommendation(`Estás usando valores recomendados de macronutrientes para tu objetivo de ${goal === 'loss' ? 'pérdida' : goal === 'gain' ? 'aumento' : 'mantenimiento'} de peso.`); | |
| } | |
| // Recomendación de proteína | |
| addRecommendation(`Consume aproximadamente ${proteinGrams}g de proteína diarios 🍗. Buenas fuentes incluyen carnes magras, pescado 🐟, huevos 🥚 y lácteos 🧀.`); | |
| // Recomendación de carbohidratos | |
| if (goal === 'loss') { | |
| addRecommendation(`Prioriza carbohidratos complejos (${carbsGrams}g/día) como vegetales 🥦, granos enteros 🌾 y legumbres para energía sostenida ⚡.`); | |
| } else { | |
| addRecommendation(`Consume ${carbsGrams}g de carbohidratos diarios 🍞, priorizando fuentes complejas como arroz integral 🍚, quinoa y avena 🥣.`); | |
| } | |
| // Recomendación de grasas | |
| addRecommendation(`Incluye ${fatGrams}g de grasas saludables diarias 🥑 de fuentes como aguacate, frutos secos 🥜, aceite de oliva y pescados grasos 🐠.`); | |
| // Recomendación de agua | |
| addRecommendation(`Bebe al menos ${waterIntake} litros de agua al día 💧 para mantener una hidratación óptima.`); | |
| // Recomendación de comidas | |
| addRecommendation('Distribuye tus macronutrientes en 3-5 comidas al día 🍽️ para mejor digestión y absorción.'); | |
| function addRecommendation(text) { | |
| const div = document.createElement('div'); | |
| div.className = 'flex items-start bg-white p-4 rounded-lg border border-gray-200'; | |
| div.innerHTML = ` | |
| <span class="text-purple-500 mr-3 mt-1"><i class="fas fa-check-circle"></i></span> | |
| <span>${text}</span> | |
| `; | |
| recommendationsEl.appendChild(div); | |
| } | |
| } | |
| function updateChart(protein, carbs, fat) { | |
| const ctx = document.getElementById('macrosChart').getContext('2d'); | |
| // Destruir gráfico anterior si existe | |
| if (macrosChart) { | |
| macrosChart.destroy(); | |
| } | |
| macrosChart = new Chart(ctx, { | |
| type: 'doughnut', | |
| data: { | |
| labels: ['Proteína 🍗', 'Carbohidratos 🍞', 'Grasas 🥑'], | |
| datasets: [{ | |
| data: [protein, carbs, fat], | |
| backgroundColor: [ | |
| '#3b82f6', | |
| '#f59e0b', | |
| '#ef4444' | |
| ], | |
| borderWidth: 0, | |
| hoverOffset: 10 | |
| }] | |
| }, | |
| options: { | |
| responsive: true, | |
| maintainAspectRatio: false, | |
| plugins: { | |
| legend: { | |
| position: 'bottom', | |
| labels: { | |
| font: { | |
| size: 14, | |
| family: 'sans-serif' | |
| }, | |
| padding: 20, | |
| usePointStyle: true, | |
| pointStyle: 'circle' | |
| } | |
| }, | |
| tooltip: { | |
| callbacks: { | |
| label: function(context) { | |
| const label = context.label || ''; | |
| const value = context.raw || 0; | |
| const total = context.dataset.data.reduce((a, b) => a + b, 0); | |
| const percentage = Math.round((value / total) * 100); | |
| return `${label}: ${value}g (${percentage}%)`; | |
| } | |
| }, | |
| bodyFont: { | |
| size: 14 | |
| }, | |
| titleFont: { | |
| size: 16, | |
| weight: 'bold' | |
| } | |
| } | |
| }, | |
| cutout: '70%', | |
| animation: { | |
| animateScale: true, | |
| animateRotate: true | |
| } | |
| } | |
| }); | |
| } | |
| // Inicializar | |
| setGender('male'); | |
| updateMacroPercentages(); // Para mostrar los valores iniciales | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=andyontrade/macros" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |