js/bmr-calculator.js

"use strict"; /* Settings */ let _settings = { theme: 'light-green', // dark-grey, dark-simplistic, light-simplistic, light-simplistic-grey, light-white, light-green animation: true, // true or false animationDuration: 200, // milliseconds units: "m", // Set default measurement system. "i" for imperial, "m" for metric formula: "jeor", // Set default formula. You can use one of these values: "jeor", "benedict", "katch" genre: "m", // Set default genre. "m" for male, "f" for female }; /* Translation texts */ let _translation = { // Title title: 'Basal Metabolic Rate (BMR)', btnCalculate: 'Calculate', btnReset: 'Reset', // Units unitsTitle: 'Measurement units', unitsTooltip: `Metric (kg/cm) or
Imperial (lb/inch)`, unitsOp1: 'Metric', unitsOp2: 'Imperial', // Gender genderTitle: 'Gender', genderTooltip: `Select your gender`, genderOp1: 'Male', genderOp2: 'Female', // Age ageTitle: 'Age', ageMeasurement: 'years', ageTooltip: 'Enter your age', // Weight weightTitle: 'Weight', weightTooltip: 'Enter your weight', // Height heightTitle: 'Height', heightTooltip: 'Enter your height', // Activity level activityLevelTitle: 'Activity level', activityLevelTooltip: 'Activity level that best matches your lifestyle', activityLevelOp1: 'Sedentary Lifestyle (very little exercise)', activityLevelOp2: 'Lightly Active Lifestyle (exercise 1-3 days/week)', activityLevelOp3: 'Moderately Active Lifestyle (exercise 3-5 days/week)', activityLevelOp4: 'Very Active Lifestyle (exercise 6-7 days/week)', activityLevelOp5: 'Extremely Active Lifestyle (very hard exercise)', // Goal goalTitle: 'Goal', goalTooltip: 'Select your goal', goalOp1: 'Fat loss', goalOp2: 'Maintenance', goalOp3: 'Gain', // Formula formulaTitle: 'Calculation formula', formulaTooltip: 'Choose which formula to use for calculating BMR', formulaOp1: 'Mifflin St. Jeor', formulaOp2: 'Harris-Benedict', // Results // Calories caloriesTitle: 'BMR calories/day', caloriesTooltip: 'Basal Metabolic Rate (BMR)', // Carbs carbsTitle: 'Carbs/day', carbsTooltip: 'Carbohydrates intake per day', // Proteins proteinsTitle: 'Proteins/day', proteinsTooltip: 'Proteins intake per day', // Fats fatsTitle: 'Fats/day', fatsTooltip: 'Fats intake per day', } /* Initiate */ initCalc(); function initCalc() { /* Replace style */ let styleLink = document.querySelector('#bmr-style'); let hrefLinkArr = styleLink.href.split('/'); hrefLinkArr[hrefLinkArr.length - 1] = `bmr-${_settings.theme}.css`; styleLink.href = hrefLinkArr.join('/'); /* If JavaScript is enabled, display content */ document.getElementsByName("bmrCalculator")[0].style.display = "block"; document.getElementById("bmrNoScript").style.display = "none"; /* Translation */ let mainHtml = document.querySelector('.bmrCalculator').innerHTML; Object.keys(_translation).forEach(function(item) { mainHtml = mainHtml.replace(`[${item}]`, _translation[item]); }); document.querySelector('.bmrCalculator').innerHTML = mainHtml; bmrSetUnit(_settings.units); bmrSetFormula(_settings.formula); bmrSetGenre(_settings.genre); } /* Input and Input Labels size adjustments */ function bmrAdjustInputSizes() { let _inputLabels = document.getElementsByClassName("bmr-input-label"); let _inputs = document.getElementsByClassName("bmr-calculator-input"); for (let i = 0; i < _inputs.length; i++) { if (_inputLabels[i] != undefined) _inputs[i].style.paddingLeft = 10 * 1 + _inputLabels[i].offsetWidth; // "10" is left padding in pixels } } /* Check if the input is a number */ function isNumeric(n) { if (!isNaN(n)) { return Number(n); } else { return 0 } } /* Reset form's data */ function bmrCalculatorReset() { /* Reset inputs */ document.getElementsByName("bmrCalculator")[0].reset(); /* Reset results */ document.getElementById("bmrResult").innerHTML = "-"; document.getElementById("carbsResult").innerHTML = "-"; document.getElementById("proteinResult").innerHTML = "-"; document.getElementById("fatResult").innerHTML = "-"; bmrSetUnit(_settings.units); bmrSetFormula(_settings.formula); } /* Change measurement unit */ function bmrSetUnit(unitType, event) { if (event != null) event.preventDefault(); let oldUnitType = _settings.units; let imperialButton = document.getElementById("bmrMeasurement2"); let metricButton = document.getElementById("bmrMeasurement1"); let unitKG = document.getElementsByClassName("bmrUnitKG"); let unitCM = document.getElementsByClassName("bmrUnitCM"); let unitMM = document.getElementsByClassName("bmrUnitMM"); let unitConvertKG = document.getElementsByClassName("bmrUnitConvertKG"); let unitConvertCM = document.getElementsByClassName("bmrUnitConvertCM"); let unitConvertMM = document.getElementsByClassName("bmrUnitConvertMM"); let fatRes = document.getElementById("bmrResult"); metricButton.className = (metricButton.className).replace("bmr-active", ""); imperialButton.className = (imperialButton.className).replace("bmr-active", ""); if (unitType == "i") { _settings.units = "i"; /* Make the imperial button active */ imperialButton.className += " bmr-active"; /* Replace labels from metric to imperial */ for (let i = 0; i < unitKG.length; i++) { unitKG[i].innerHTML = "lb"; } for (let i = 0; i < unitCM.length; i++) { unitCM[i].innerHTML = "in"; } for (let i = 0; i < unitMM.length; i++) { unitMM[i].innerHTML = "in"; } /* Convert input values from metric to imperial */ if (oldUnitType == "m") { for (let i = 0; i < unitConvertKG.length; i++) { unitConvertKG[i].value = Math.round(unitConvertKG[i].value * 2.20462262 * 1000) / 1000; } for (let i = 0; i < unitConvertCM.length; i++) { unitConvertCM[i].value = Math.round(unitConvertCM[i].value * 0.393700787 * 1000) / 1000; } for (let i = 0; i < unitConvertMM.length; i++) { unitConvertMM[i].value = Math.round(unitConvertMM[i].value * 0.0393700787 * 1000) / 1000; } } } else { _settings.units = "m"; /* Make the metric button active */ metricButton.className += " bmr-active"; /* Replace labels from imperial to metric */ for (let i = 0; i < unitKG.length; i++) { unitKG[i].innerHTML = "kg"; } for (let i = 0; i < unitCM.length; i++) { unitCM[i].innerHTML = "cm"; } for (let i = 0; i < unitMM.length; i++) { unitMM[i].innerHTML = "mm"; } /* Convert input values from imperial to metric */ if (oldUnitType == "i") { for (let i = 0; i < unitConvertKG.length; i++) { unitConvertKG[i].value = Math.round(unitConvertKG[i].value / 2.20462262 * 1000) / 1000; } for (let i = 0; i < unitConvertCM.length; i++) { unitConvertCM[i].value = Math.round(unitConvertCM[i].value / 0.393700787 * 1000) / 1000; } for (let i = 0; i < unitConvertMM.length; i++) { unitConvertMM[i].value = Math.round(unitConvertMM[i].value / 0.0393700787 * 1000) / 1000; } } } /* Since the label size was changed (because of replacing its value, ex "mm" -> "in" or viceversa) * we need to re-adjust input sizes */ bmrAdjustInputSizes(); } /* Change genre */ function bmrSetGenre(genre, event) { if (event != null) event.preventDefault(); let maleButton = document.getElementById("bmrGenre1"); let femaleButton = document.getElementById("bmrGenre2"); /* Change buttons' style */ maleButton.className = (maleButton.className).replace("bmr-active", ""); femaleButton.className = (femaleButton.className).replace("bmr-active", ""); if (genre == "m") { _settings.genre = "m"; maleButton.className += " bmr-active"; } else { _settings.genre = "f"; femaleButton.className += " bmr-active"; } bmrAdjustInputSizes(); } /* Change formula used */ function bmrSetFormula(formula) { let formulaSelect = document.getElementById("bmrFormula"); _settings.formula = formula || formulaSelect.options[formulaSelect.selectedIndex].value; /* If formula is set programatically, update the default option on select element */ for (let i, j = 0; i = formulaSelect.options[j]; j++) { if (i.value == formula) { formulaSelect.selectedIndex = j; break; } } /* Show result area */ let resultItems = document.getElementsByClassName("bmrResults"); for (let i = 0; i < resultItems.length; i++) { resultItems[i].style.display = "inline-block"; } bmrSetGenre(_settings.genre, null); bmrAdjustInputSizes(); } /* Convert to imperial system */ function bmrImperial(number, type) { if (_settings.units == "i") { return number; } else { if (type == "kg") { return number * 2.20462262; } else if (type == "cm") { return number * 0.393700787; } else if (type == "mm") { return number * 0.0393700787; } } } /* Convert to metric system */ function bmrMetric(number, type) { if (_settings.units == "m") { return number; } else { if (type == "kg") { return number / 2.20462262; } else if (type == "cm") { return number / 0.393700787; } else if (type == "mm") { return number / 0.0393700787; } } } /* Calculate function */ function bmrCalculatorCalculate() { /* Input fields */ let ageVal = isNumeric(document.getElementById("bmrAge").value); let heightVal = bmrMetric(isNumeric(document.getElementById("bmrHeight").value), "cm"); let originalWeight = isNumeric(document.getElementById("bmrWeight").value); let weightVal = bmrMetric(originalWeight, "kg"); let activity = isNumeric(document.getElementById("bmrActivity").value); let goal = document.getElementById('goal').value; /* Output fields */ let Result = document.getElementById("bmrResult"); let carbsResult = document.getElementById("carbsResult"); let proteinResult = document.getElementById("proteinResult"); let fatResult = document.getElementById("fatResult"); let bmr = 0; /* Check which calculation method is selected and apply its formula */ if (_settings.formula == "jeor") { if (_settings.genre == "m") { bmr = 10 * weightVal + 6.25 * heightVal - 5 * ageVal + 5; } else { bmr = 10 * weightVal + 6.25 * heightVal - 5 * ageVal - 161; } } else if (_settings.formula == "benedict") { if (_settings.genre == "m") { bmr = 66.5 + (13.75 * weightVal) + (5.003 * heightVal) - (6.775 * ageVal); } else { bmr = 655.1 + (9.563 * weightVal) + (1.85 * heightVal) - (4.676 * ageVal); } } /* Output results */ let resValue = Math.round(bmr * activity); animateValue(Result, 0, resValue, _settings.animationDuration); let totalResult = isNumeric(resValue); /* Calculate MacroNutrients */ switch (goal) { case "fat-loss": if (totalResult <= 2000) totalResult = Math.round(0.9 * totalResult); if (totalResult > 2000) totalResult = Math.round(0.8 * totalResult); animateValue(carbsResult, 0, Math.round(0.4 * totalResult / 4), _settings.animationDuration); animateValue(proteinResult, 0, Math.round(0.4 * totalResult / 4), _settings.animationDuration); animateValue(fatResult, 0, Math.round(0.2 * totalResult / 9), _settings.animationDuration); break; case 'maintenance': animateValue(carbsResult, 0, Math.round(0.45 * totalResult / 4), _settings.animationDuration); animateValue(proteinResult, 0, Math.round(0.3 * totalResult / 4), _settings.animationDuration); animateValue(fatResult, 0, Math.round(0.25 * totalResult / 9), _settings.animationDuration); break; case 'gains': totalResult += 500; animateValue(carbsResult, 0, Math.round(0.45 * totalResult / 4), _settings.animationDuration); animateValue(proteinResult, 0, Math.round(0.3 * totalResult / 4), _settings.animationDuration); animateValue(fatResult, 0, Math.round(0.25 * totalResult / 9), _settings.animationDuration); break; } } /* Counter animation */ function animateValue(obj, start, end, duration) { if (!_settings.animation) { obj.innerHTML = end; return; } if (isNaN(start)) start = 0; let startTimestamp = null; const step = (timestamp) => { if (!startTimestamp) startTimestamp = timestamp; const progress = Math.min((timestamp - startTimestamp) / duration, 1); obj.innerHTML = Math.floor(progress * (end - start) + start); if (progress < 1) { window.requestAnimationFrame(step); } }; window.requestAnimationFrame(step); }

Contact Form