<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>小鼠鼠粮配比计算器</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/css/font-awesome.min.css" rel="stylesheet">
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#4361ee',
secondary: '#3f37c9',
accent: '#4895ef',
neutral: '#f8f9fa',
'protein-highlight': '#e6f2ff'
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
},
}
}
}
</script>
<style type="text/tailwindcss">
@layer utilities {
.content-auto {
content-visibility: auto;
}
.card-shadow {
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
}
.transition-custom {
transition: all 0.3s ease;
}
}
</style>
</head>
<body class="bg-gray-50 font-sans">
<header class="bg-primary text-white shadow-md">
<div class="container mx-auto px-4 py-6">
<div class="flex flex-col md:flex-row items-center justify-between">
<div class="flex items-center mb-4 md:mb-0">
<i class="fa fa-mouse-pointer text-3xl mr-3"></i>
<h1 class="text-2xl md:text-3xl font-bold">小鼠鼠粮配比计算器</h1>
</div>
<p class="text-white/80">按体积计算蛋白比例 · 精确配比</p>
</div>
</div>
</header>
<main class="container mx-auto px-4 py-8">
<section class="max-w-5xl mx-auto">
<!-- 输入区域 -->
<div class="bg-white rounded-xl p-6 mb-8 card-shadow">
<h2 class="text-xl font-bold mb-6 text-gray-800 flex items-center">
<i class="fa fa-calculator text-primary mr-2"></i>配比参数设置
</h2>
<form id="ratio-form" class="space-y-6">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label for="total-weight" class="block text-gray-700 font-medium mb-2">总重量 (g)</label>
<div class="relative">
<span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-500">
<i class="fa fa-balance-scale"></i>
</span>
<input
type="number"
id="total-weight"
name="total-weight"
value="7750.0"
min="10"
step="0.1"
class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary outline-none transition-custom"
required
>
</div>
</div>
<div>
<label for="protein-ratio" class="block text-gray-700 font-medium mb-2">蛋白食材体积比例 (%)</label>
<div class="relative">
<span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-500">
<i class="fa fa-percent"></i>
</span>
<input
type="number"
id="protein-ratio"
name="protein-ratio"
value="10.0"
min="5"
max="30"
step="0.1"
class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary outline-none transition-custom"
required
>
</div>
</div>
</div>
<div class="flex justify-center">
<button
type="button"
id="calculate-btn"
class="bg-primary hover:bg-secondary text-white font-bold py-2 px-6 rounded-lg flex items-center transition-custom"
>
<i class="fa fa-calculator mr-2"></i> 计算配比
</button>
</div>
</form>
</div>
<!-- 结果展示区域 -->
<div id="result-section" class="bg-white rounded-xl p-6 mb-8 card-shadow">
<h2 class="text-xl font-bold mb-6 text-gray-800 flex items-center">
<i class="fa fa-list-alt text-primary mr-2"></i>鼠粮配比结果
<span class="ml-3 text-sm font-normal text-primary bg-protein-highlight px-3 py-1 rounded-full">
<i class="fa fa-diamond mr-1"></i> 蓝色标注为含蛋白食材
</span>
</h2>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
食材名称
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
体积占比 (%)
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
质量 (g)
</th>
</tr>
</thead>
<tbody id="result-table-body" class="bg-white divide-y divide-gray-200">
<!-- 结果将通过JavaScript动态插入 -->
</tbody>
</table>
</div>
<div class="mt-6 pt-6 border-t border-gray-200">
<div class="flex flex-col md:flex-row justify-between items-center">
<div class="mb-4 md:mb-0">
<p class="text-gray-600"><span class="font-semibold">总质量:</span><span id="total-weight-result">7750.0 g</span></p>
<p class="text-gray-600"><span class="font-semibold">蛋白食材体积比例:</span><span id="protein-ratio-result">10.0%</span></p>
<p class="text-gray-600"><span class="font-semibold">蛋白食材总质量:</span><span id="total-protein-weight">约 500.0 g</span></p>
</div>
<button id="print-result" class="bg-primary hover:bg-secondary text-white font-bold py-2 px-6 rounded-lg flex items-center transition-custom">
<i class="fa fa-print mr-2"></i> 打印结果
</button>
</div>
</div>
</div>
<!-- 标准配方参考 -->
<div class="bg-white rounded-xl p-6 card-shadow">
<h2 class="text-xl font-bold mb-6 text-gray-800 flex items-center">
<i class="fa fa-book text-primary mr-2"></i>标准配方参考 (7750g)
</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div class="p-3 bg-neutral rounded-lg">
<span>25谷米</span>
<span class="float-right font-medium">2500.0g</span>
</div>
<div class="p-3 bg-neutral rounded-lg">
<span>青稞米</span>
<span class="float-right font-medium">500.0g</span>
</div>
<div class="p-3 bg-neutral rounded-lg">
<span>大麦米</span>
<span class="float-right font-medium">500.0g</span>
</div>
<div class="p-3 bg-neutral rounded-lg">
<span>三色藜麦</span>
<span class="float-right font-medium">500.0g</span>
</div>
<div class="p-3 bg-neutral rounded-lg">
<span>糙米</span>
<span class="float-right font-medium">500.0g</span>
</div>
<div class="p-3 bg-neutral rounded-lg">
<span>养麦米</span>
<span class="float-right font-medium">500.0g</span>
</div>
<div class="p-3 bg-neutral rounded-lg">
<span>意面</span>
<span class="float-right font-medium">700.0g</span>
</div>
<div class="p-3 bg-neutral rounded-lg">
<span>谷物圈</span>
<span class="float-right font-medium">250.0g</span>
</div>
<div class="p-3 bg-neutral rounded-lg">
<span>玉米片</span>
<span class="float-right font-medium">250.0g</span>
</div>
<div class="p-3 bg-neutral rounded-lg">
<span>玉米山药芝麻脆片</span>
<span class="float-right font-medium">50.0g</span>
</div>
<div class="p-3 bg-protein-highlight rounded-lg border-l-4 border-primary">
<span>三色豆片 <span class="text-primary text-xs">(含蛋白)</span></span>
<span class="float-right font-medium">250.0g</span>
</div>
<div class="p-3 bg-protein-highlight rounded-lg border-l-4 border-primary">
<span>冻干鳕鱼 <span class="text-primary text-xs">(含蛋白)</span></span>
<span class="float-right font-medium">50.0g</span>
</div>
<div class="p-3 bg-protein-highlight rounded-lg border-l-4 border-primary">
<span>渴望6种鱼 <span class="text-primary text-xs">(含蛋白)</span></span>
<span class="float-right font-medium">200.0g</span>
</div>
<div class="p-3 bg-neutral rounded-lg">
<span>果蔬冻干</span>
<span class="float-right font-medium">400.0g</span>
</div>
<div class="p-3 bg-neutral rounded-lg">
<span>金丝黄菊</span>
<span class="float-right font-medium">100.0g</span>
</div>
<div class="p-3 bg-neutral rounded-lg">
<span>山姆种子</span>
<span class="float-right font-medium">500.0g</span>
</div>
</div>
<div class="mt-6 p-4 bg-blue-50 rounded-lg border border-blue-100">
<p class="text-gray-700 text-sm">
标准配方总质量为7750g。蛋白食材包括:三色豆片、冻干鳕鱼和渴望6种鱼,它们的体积比例总和为10%。当调整蛋白体积比例时,这三种食材会按其原有体积比例关系进行调整,其他食材体积占比保持不变。
</p>
</div>
</div>
</section>
</main>
<footer class="bg-gray-800 text-white mt-12">
<div class="container mx-auto px-4 py-6">
<div class="flex flex-col md:flex-row justify-between items-center">
<div class="mb-4 md:mb-0">
<p class="text-gray-400">© 2025 小鼠鼠粮配比计算器</p>
</div>
</div>
</div>
</footer>
<script>
// 标准配方数据 (g)
const standardIngredients = [
{ name: "25谷米", weight: 2500, isProtein: false, density: 1.0 },
{ name: "青稞米", weight: 500, isProtein: false, density: 1.0 },
{ name: "大麦米", weight: 500, isProtein: false, density: 1.0 },
{ name: "三色藜麦", weight: 500, isProtein: false, density: 1.0 },
{ name: "糙米", weight: 500, isProtein: false, density: 1.0 },
{ name: "养麦米", weight: 500, isProtein: false, density: 1.0 },
{ name: "意面", weight: 700, isProtein: false, density: 0.5 },
{ name: "谷物圈", weight: 250, isProtein: false, density: 0.5 },
{ name: "玉米片", weight: 250, isProtein: false, density: 0.5 },
{ name: "玉米山药芝麻脆片", weight: 50, isProtein: false, density: 0.5 },
{ name: "三色豆片", weight: 250, isProtein: true, density: 0.5 },
{ name: "冻干鳕鱼", weight: 50, isProtein: true, density: 0.5 },
{ name: "渴望6种鱼", weight: 200, isProtein: true, density: 0.5 },
{ name: "果蔬冻干", weight: 400, isProtein: false, density: 0.5 },
{ name: "金丝黄菊", weight: 100, isProtein: false, density: 0.5 },
{ name: "山姆种子", weight: 500, isProtein: false, density: 1.0 }
];
// 计算每种食材的标准体积
standardIngredients.forEach(ingredient => {
ingredient.volume = ingredient.weight / ingredient.density;
});
// 计算标准总体积和总质量
const standardTotalVolume = standardIngredients.reduce((sum, item) => sum + item.volume, 0);
const standardTotalWeight = standardIngredients.reduce((sum, item) => sum + item.weight, 0);
// 计算标准蛋白食材总体积和体积占比
const standardProteinIngredients = standardIngredients.filter(item => item.isProtein);
const standardProteinTotalVolume = standardProteinIngredients.reduce((sum, item) => sum + item.volume, 0);
const standardProteinRatio = (standardProteinTotalVolume / standardTotalVolume) * 100;
// 计算蛋白食材之间的体积比例关系
const proteinVolumeRelations = standardProteinIngredients.map(item => ({
name: item.name,
relation: item.volume / standardProteinTotalVolume
}));
// 计算非蛋白食材
const nonProteinIngredients = standardIngredients.filter(item => !item.isProtein);
const standardNonProteinTotalVolume = standardTotalVolume - standardProteinTotalVolume;
// 初始化页面
document.addEventListener('DOMContentLoaded', () => {
// 初始计算并显示结果
calculateAndDisplayResults(standardTotalWeight, standardProteinRatio);
// 计算按钮点击事件(修改为直接绑定按钮点击,而非表单提交)
document.getElementById('calculate-btn').addEventListener('click', function() {
try {
const totalWeightInput = document.getElementById('total-weight');
const proteinRatioInput = document.getElementById('protein-ratio');
// 验证输入
if (!totalWeightInput.checkValidity() || !proteinRatioInput.checkValidity()) {
alert('请输入有效的数值(总重量不小于10g,蛋白比例在5%-30%之间)');
return;
}
const totalWeight = parseFloat(totalWeightInput.value);
const proteinRatio = parseFloat(proteinRatioInput.value);
calculateAndDisplayResults(totalWeight, proteinRatio);
// 添加结果区域的动画效果
const resultSection = document.getElementById('result-section');
resultSection.classList.add('scale-105');
setTimeout(() => {
resultSection.classList.remove('scale-105');
}, 300);
} catch (error) {
console.error('计算出错:', error);
alert('计算过程中出现错误,请重试');
}
});
// 打印结果按钮
document.getElementById('print-result').addEventListener('click', function() {
window.print();
});
});
// 计算并显示结果
function calculateAndDisplayResults(totalWeight, proteinRatio) {
// 1. 计算标准密度比例(总质量/总体积)
const standardDensityRatio = standardTotalWeight / standardTotalVolume;
// 2. 计算目标总体积
const targetTotalVolume = totalWeight / standardDensityRatio;
// 3. 计算蛋白食材和非蛋白食材的目标体积
const targetProteinVolume = (proteinRatio / 100) * targetTotalVolume;
const targetNonProteinVolume = targetTotalVolume - targetProteinVolume;
// 4. 计算非蛋白食材的体积缩放比例
const nonProteinScale = targetNonProteinVolume / standardNonProteinTotalVolume;
// 5. 计算每种食材的目标体积和质量
const results = standardIngredients.map(ingredient => {
let targetVolume, volumeRatio;
if (ingredient.isProtein) {
// 蛋白食材按体积比例关系分配
const relation = proteinVolumeRelations.find(r => r.name === ingredient.name).relation;
targetVolume = targetProteinVolume * relation;
volumeRatio = (targetVolume / targetTotalVolume) * 100;
} else {
// 非蛋白食材按比例缩放
targetVolume = ingredient.volume * nonProteinScale;
volumeRatio = (targetVolume / targetTotalVolume) * 100;
}
// 计算目标质量
const targetWeight = targetVolume * ingredient.density;
return {
...ingredient,
targetVolume: targetVolume,
targetWeight: targetWeight,
volumeRatio: volumeRatio
};
});
// 6. 计算蛋白食材总质量
const totalProteinWeight = results
.filter(item => item.isProtein)
.reduce((sum, item) => sum + item.targetWeight, 0);
// 7. 更新显示
document.getElementById('total-weight-result').textContent = `${totalWeight.toFixed(1)} g`;
document.getElementById('protein-ratio-result').textContent = `${proteinRatio.toFixed(1)}%`;
document.getElementById('total-protein-weight').textContent = `约 ${totalProteinWeight.toFixed(1)} g`;
// 8. 显示结果表格
displayResultsTable(results);
}
// 显示结果表格
function displayResultsTable(results) {
const tableBody = document.getElementById('result-table-body');
tableBody.innerHTML = '';
results.forEach(item => {
const row = document.createElement('tr');
row.className = item.isProtein ? 'bg-protein-highlight hover:bg-blue-100 transition-custom' : 'hover:bg-gray-50 transition-custom';
// 添加动画效果
row.classList.add('opacity-0', 'translate-y-2');
setTimeout(() => {
row.classList.remove('opacity-0', 'translate-y-2');
row.classList.add('transition-all', 'duration-300', 'opacity-100', 'translate-y-0');
}, 50 * results.indexOf(item));
row.innerHTML = `
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm font-medium text-gray-900">
${item.name} ${item.isProtein ? '<span class="text-primary text-xs ml-2">(含蛋白)</span>' : ''}
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-600">${item.volumeRatio.toFixed(1)}</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm font-semibold ${item.isProtein ? 'text-primary' : 'text-gray-800'}">${item.targetWeight.toFixed(1)}</div>
</td>
`;
tableBody.appendChild(row);
});
}
</script>
</body>
</html>
index.html
index.html