圧力と流量の単位変換を行う(HTML+CSS+JavaScript)プログラムを、オンライン平均自由行程計算機 に続いて ChatGPT に作ってもらいました。
圧力単位変換計算機(Pressure Unit Converter)
流量単位変換計算機(Flow Rate Unit Converter)
単位変換の計算部分自体はすぐに出来たのですが、モバイル端末で見たときの各ボックスのレイアウトの変更(CSSのレスポンシブ対応)の指示が ChatGPT になかなかうまく伝わらず少し大変でした。指示の出し方が悪いのもしれませんが、一度直したところをまた元に戻されたりします。ソースコードはそれぞれ以下の通りです(自分の勉強用に貼り付けます)。
圧力単位変換のソースコード
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>圧力単位変換計算機</title>
<style>
.pressure-converter {
font-family: sans-serif;
max-width: 900px;
margin: 40px auto;
padding: 50px 20px 30px 20px;
border: 2px solid #777;
border-radius: 15px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.12);
background-color: #fafafa;
position: relative;
box-sizing: border-box;
overflow-x: hidden;
}
.pressure-converter-title {
position: absolute;
top: 12px;
left: 20px;
right: 20px;
font-weight: bold;
font-size: 1.2em;
background-color: #fafafa;
padding: 0 8px;
color: #333;
word-break: keep-all;
white-space: normal;
}
.pressure-units-row {
display: flex;
flex-wrap: wrap;
gap: 12px;
justify-content: space-between;
margin-top: 25px;
padding-top: 25px;
}
.pressure-unit {
display: flex;
flex-direction: column;
align-items: center;
flex: 1 1 18%;
min-width: 100px;
max-width: 180px;
box-sizing: border-box;
}
.pressure-unit label {
margin-bottom: 6px;
font-weight: bold;
}
.pressure-unit input {
width: 100%;
padding: 6px 8px;
text-align: right;
font-size: 1em;
border: 1px solid #ccc;
border-radius: 6px;
transition: border-color 0.3s ease;
}
.pressure-unit input:focus {
border-color: #0066cc;
outline: none;
}
@media (max-width: 600px) {
.pressure-unit {
flex: 1 1 calc(48% - 6px);
max-width: calc(48% - 6px);
}
}
</style>
</head>
<body>
<div class="pressure-converter" role="region" aria-label="圧力単位変換計算機">
<div class="pressure-converter-title">圧力単位変換計算機(Pressure Unit Converter)</div>
<div class="pressure-units-row">
<div class="pressure-unit">
<label for="pressure-pa">Pa</label>
<input type="number" id="pressure-pa" min="0" step="any" oninput="convertPressureFrom('pa')" />
</div>
<div class="pressure-unit">
<label for="pressure-mbar">mbar (hPa)</label>
<input type="number" id="pressure-mbar" min="0" step="any" oninput="convertPressureFrom('mbar')" />
</div>
<div class="pressure-unit">
<label for="pressure-mtorr">mTorr</label>
<input type="number" id="pressure-mtorr" min="0" step="any" oninput="convertPressureFrom('mtorr')" />
</div>
<div class="pressure-unit">
<label for="pressure-torr">Torr</label>
<input type="number" id="pressure-torr" min="0" step="any" oninput="convertPressureFrom('torr')" />
</div>
<div class="pressure-unit">
<label for="pressure-atm">atm</label>
<input type="number" id="pressure-atm" min="0" step="any" oninput="convertPressureFrom('atm')" />
</div>
</div>
</div>
<script>
const PA_ATM = 101325;
const TORR_ATM = 760;
let pressureUpdating = false;
function convertPressureFrom(unit) {
if (pressureUpdating) return;
pressureUpdating = true;
const inputs = {
pa: document.getElementById("pressure-pa"),
mbar: document.getElementById("pressure-mbar"),
mtorr: document.getElementById("pressure-mtorr"),
torr: document.getElementById("pressure-torr"),
atm: document.getElementById("pressure-atm"),
};
let val = parseFloat(inputs[unit].value);
if (isNaN(val) || val < 0) {
clearPressureFields(unit);
pressureUpdating = false;
return;
}
let pa;
switch (unit) {
case "pa":
pa = val;
break;
case "mbar":
pa = val * 100;
break;
case "mtorr":
pa = (val / 1000) * (PA_ATM / TORR_ATM);
break;
case "torr":
pa = val * (PA_ATM / TORR_ATM);
break;
case "atm":
pa = val * PA_ATM;
break;
}
inputs.pa.value = formatPressure(pa);
inputs.mbar.value = formatPressure(pa / 100);
inputs.mtorr.value = formatPressure((pa / PA_ATM) * TORR_ATM * 1000);
inputs.torr.value = formatPressure((pa / PA_ATM) * TORR_ATM);
inputs.atm.value = formatPressure(pa / PA_ATM);
pressureUpdating = false;
}
function clearPressureFields(except = "") {
const ids = ["pa", "mbar", "mtorr", "torr", "atm"];
for (const id of ids) {
if (id !== except) {
document.getElementById("pressure-" + id).value = "";
}
}
}
function formatPressure(val) {
if (val === 0) return "0";
if (Math.abs(val) >= 1e6 || Math.abs(val) < 1e-4) {
return val.toExponential(5);
} else {
return parseFloat(val.toFixed(6));
}
}
</script>
</body>
</html>
流量単位変換のソースコード
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>流量単位変換計算機</title>
<style>
.flow-converter {
font-family: sans-serif;
max-width: 1100px;
margin: 40px auto;
padding: 60px 30px 30px;
border: 2px solid #777;
border-radius: 15px;
box-shadow: 0 4px 8px rgba(0,0,0,0.12);
background-color: #fafafa;
position: relative;
box-sizing: border-box;
}
.flow-converter-title {
position: absolute;
top: 12px;
left: 20px;
right: 20px;
font-weight: bold;
font-size: 1.2em;
background-color: #fafafa;
padding: 0 8px;
color: #333;
text-align: left;
}
.gas-select-row {
display: flex;
flex-wrap: wrap;
gap: 30px;
margin-top: 40px;
margin-bottom: 20px;
justify-content: flex-start;
}
.gas-column {
display: flex;
flex-direction: column;
align-items: center;
flex: 1 1 130px;
min-width: 130px;
max-width: 180px;
}
.gas-column label {
font-weight: bold;
margin-bottom: 5px;
text-align: center;
}
.gas-column select,
.gas-column input {
padding: 6px 8px;
font-size: 1em;
width: 100%;
box-sizing: border-box;
}
.flow-units-row {
display: flex;
flex-wrap: wrap;
gap: 12px;
justify-content: flex-start;
}
.flow-unit {
display: flex;
flex-direction: column;
align-items: center;
flex: 1 1 130px;
min-width: 130px;
max-width: 180px;
}
.flow-unit label {
margin-bottom: 6px;
font-weight: bold;
text-align: center;
}
.flow-unit input {
width: 100%;
padding: 6px 8px;
text-align: right;
font-size: 1em;
border: 1px solid #ccc;
border-radius: 6px;
box-sizing: border-box;
}
.flow-unit input:focus {
border-color: #0066cc;
outline: none;
}
@media (max-width: 600px) {
.flow-unit,
.gas-column {
flex: 1 1 calc(48% - 6px);
max-width: calc(48% - 6px);
}
}
</style>
</head>
<body>
<div class="flow-converter" role="region" aria-label="流量単位変換計算機">
<div class="flow-converter-title">流量単位変換計算機(Flow Rate Unit Converter)</div>
<div class="gas-select-row">
<div class="gas-column">
<label for="gas-select">ガス分子</label>
<select id="gas-select" onchange="updateGas()">
<option value="">-- 選択 --</option>
<option value="H2">H₂</option>
<option value="He">He</option>
<option value="CH4">CH₄</option>
<option value="NH3">NH₃</option>
<option value="H2O">H₂O</option>
<option value="Ne">Ne</option>
<option value="C2H2">C₂H₂</option>
<option value="N2">N₂</option>
<option value="CO">CO</option>
<option value="C2H4">C₂H₄</option>
<option value="NO">NO</option>
<option value="O2">O₂</option>
<option value="H2S">H₂S</option>
<option value="HCl">HCl</option>
<option value="Ar">Ar</option>
<option value="C3H6">C₃H₆</option>
<option value="CO2">CO₂</option>
<option value="N2O">N₂O</option>
<option value="C3H8">C₃H₈</option>
<option value="SO2">SO₂</option>
<option value="Cl2">Cl₂</option>
<option value="C6H6">C₆H₆</option>
<option value="HBr">HBr</option>
<option value="Kr">Kr</option>
<option value="Xe">Xe</option>
<option value="SF6">SF₆</option>
<option value="CCl4">CCl₄</option>
<option value="Br2">Br₂</option>
</select>
</div>
<div class="gas-column">
<label for="gas-molar-mass">分子量 (g/mol)</label>
<input type="number" id="gas-molar-mass" min="0" step="any" oninput="updateMolarMassFromInput()">
</div>
</div>
<div class="flow-units-row">
<div class="flow-unit">
<label for="flow-sccm">sccm</label>
<input id="flow-sccm" type="number" min="0" step="any" oninput="convertFlowFrom('sccm')">
</div>
<div class="flow-unit">
<label for="flow-pam3s">Pa·m³/s</label>
<input id="flow-pam3s" type="number" min="0" step="any" oninput="convertFlowFrom('pam3s')">
</div>
<div class="flow-unit">
<label for="flow-mbarls">mbar·L/s</label>
<input id="flow-mbarls" type="number" min="0" step="any" oninput="convertFlowFrom('mbarls')">
</div>
<div class="flow-unit">
<label for="flow-molps">molecule/s</label>
<input id="flow-molps" type="number" min="0" step="any" oninput="convertFlowFrom('molps')">
</div>
<div class="flow-unit">
<label for="flow-kgps">kg/s</label>
<input id="flow-kgps" type="number" min="0" step="any" oninput="convertFlowFrom('kgps')">
</div>
</div>
</div>
<script>
const kB = 1.380649e-23;
const R = 8.31446261815324;
const T0 = 273.15;
const P0 = 101325;
const molarMasses = {
H2: 2.01588, He: 4.002602, CH4: 16.043, NH3: 17.031, H2O: 18.01528,
Ne: 20.1797, C2H2: 26.038, N2: 28.0134, CO: 28.01, C2H4: 28.054,
NO: 30.006, O2: 31.9988, H2S: 34.08, HCl: 36.46, Ar: 39.948,
C3H6: 42.08, CO2: 44.0095, N2O: 44.0128, C3H8: 44.095, SO2: 64.066,
Cl2: 70.906, C6H6: 78.1118, HBr: 80.912, Kr: 83.798,
Xe: 131.293, SF6: 146.06, CCl4: 153.82, Br2: 159.808
};
let currentMolarMass = null;
let flowUpdating = false;
function updateGas() {
const gas = document.getElementById("gas-select").value;
if (molarMasses[gas]) {
document.getElementById("gas-molar-mass").value = molarMasses[gas];
currentMolarMass = molarMasses[gas] / 1000;
} else {
document.getElementById("gas-molar-mass").value = "";
currentMolarMass = null;
}
updateKgpsOnly();
}
function updateMolarMassFromInput() {
const val = parseFloat(document.getElementById("gas-molar-mass").value);
if (!isNaN(val) && val > 0) {
currentMolarMass = val / 1000;
updateKgpsOnly();
}
}
function updateKgpsOnly() {
const sccm = parseFloat(document.getElementById("flow-sccm").value);
if (!isNaN(sccm) && sccm >= 0 && currentMolarMass) {
const kgps = sccm * (P0 / (R * T0)) * (1e-6 / 60) * currentMolarMass;
document.getElementById("flow-kgps").value = formatValue(kgps);
}
}
function convertFlowFrom(source) {
if (flowUpdating) return;
flowUpdating = true;
const ids = {
sccm: "flow-sccm",
pam3s: "flow-pam3s",
mbarls: "flow-mbarls",
molps: "flow-molps",
kgps: "flow-kgps"
};
const input = parseFloat(document.getElementById(ids[source]).value);
if (isNaN(input) || input < 0) {
clearFlowFields(source);
flowUpdating = false;
return;
}
let sccm;
switch (source) {
case "sccm": sccm = input; break;
case "pam3s": sccm = input / (P0 * (1e-6 / 60)); break;
case "mbarls": sccm = (input / 10) / (P0 * (1e-6 / 60)); break;
case "molps": sccm = input / ((P0 / (kB * T0)) * (1e-6 / 60)); break;
case "kgps":
if (currentMolarMass) {
sccm = input / ((P0 / (R * T0)) * (1e-6 / 60) * currentMolarMass);
} else {
alert("分子量を入力してください。");
flowUpdating = false;
return;
}
break;
}
const pam3s = sccm * P0 * (1e-6 / 60);
const mbarls = pam3s * 10;
const molps = sccm * (P0 / (kB * T0)) * (1e-6 / 60);
const kgps = currentMolarMass ? sccm * (P0 / (R * T0)) * (1e-6 / 60) * currentMolarMass : null;
document.getElementById("flow-sccm").value = formatValue(sccm);
document.getElementById("flow-pam3s").value = formatValue(pam3s);
document.getElementById("flow-mbarls").value = formatValue(mbarls);
document.getElementById("flow-molps").value = formatValue(molps);
document.getElementById("flow-kgps").value = kgps !== null ? formatValue(kgps) : "";
flowUpdating = false;
}
function clearFlowFields(except = "") {
const ids = ["sccm", "pam3s", "mbarls", "molps", "kgps"];
for (const id of ids) {
if (id !== except) {
document.getElementById("flow-" + id).value = "";
}
}
}
function formatValue(val) {
if (val === 0) return "0";
if (Math.abs(val) >= 1e6 || Math.abs(val) < 1e-4) {
return val.toExponential(5);
} else {
return parseFloat(val.toFixed(8));
}
}
</script>
</body>
</html>
コメント