Prompt
iphoneだよ?コピーできようにもう一回コード書いて?
Response
あ、ごめん!iPhoneだもんね、スマホからでも一発でコピーできるように、余計な省略なしでちゃんと完全なコードを書き直すね。
下のコードブロックの右上にあるコピーボタン(またはコードを長押しして全選択)で、そのままコピーしてみて。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>真空配管ジェネレータ(部材リスト対応版)</title>
<style>
body { font-family: sans-serif; padding: 15px; background: #f0f2f5; color: #333; }
.container { max-width: 700px; margin: 0 auto; background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
h2 { font-size: 1.2rem; margin-bottom: 15px; text-align: center; }
.step-row { display: flex; gap: 5px; margin-bottom: 8px; align-items: center; background: #f8f9fa; padding: 8px; border-radius: 8px; }
select, input { padding: 6px; font-size: 0.9rem; border: 1px solid #ccc; border-radius: 4px; }
button { padding: 6px 12px; background: #007aff; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; }
button.delete { background: #ff3b30; }
.btn-container { text-align: center; margin: 15px 0; }
canvas { border: 1px solid #ddd; background: #fafafa; width: 100%; max-height: 300px; border-radius: 8px; display: block; margin: 10px auto; }
table { width: 100%; border-collapse: collapse; margin-top: 15px; font-size: 0.85rem; }
th, td { border: 1px solid #ddd; padding: 6px; text-align: left; }
th { background: #f1f3f5; }
</style>
</head>
<body>
<div class="container">
<h2>真空配管アイソメ・部材ジェネレータ</h2>
<div id="steps-container">
<!-- 動的に行が追加されます -->
</div>
<div class="btn-container">
<button onclick="addStep()">+ 配管ルートを追加</button>
<button onclick="generate()" style="background: #34c759;">更新・計算</button>
</div>
<canvas id="canvas" width="400" height="300"></canvas>
<h3>部材リスト (BOM) & サポート</h3>
<table id="bom-table">
<tr><th>品名・規格</th><th>仕様</th><th>数量 / 位置</th></tr>
</table>
</div>
<script>
const sizes = ["NW25", "NW40", "NW50", "NW63", "NW80", "NW100", "NW125", "NW160", "NW200",
"ISO-MF25", "ISO-MF40", "ISO-MF50", "ISO-MF63", "ISO-MF80", "ISO-MF100",
"ISO-BT25", "ISO-BT40", "ISO-BT50", "ISO-BT63", "ISO-BT80", "ISO-BT100",
"25A", "40A", "50A", "80A", "100A", "150A", "200A", "250A"];
const types = [
{val: "STRAIGHT", name: "直管"},
{val: "EL", name: "エルボー(EL)"},
{val: "CR", name: "レデューサー(CR)"},
{val: "TEE", name: "チーズ(TEE)"},
{val: "FLEX", name: "NWフレキ"}
];
const dirs = [
{val: "EAST", name: "東(+X)"},
{val: "WEST", name: "西(-X)"},
{val: "NORTH", name: "北(+Y)"},
{val: "SOUTH", name: "南(-Y)"},
{val: "UP", name: "天(+Z)"},
{val: "DOWN", name: "地(-Z)"}
];
// 初期データ
let steps = [
{type: "STRAIGHT", size: "NW100", dir: "UP", length: 1000},
{type: "EL", size: "NW100", dir: "EAST", length: 500},
{type: "CR", size: "NW100->NW80", dir: "EAST", length: 800}
];
function renderSteps() {
const container = document.getElementById('steps-container');
container.innerHTML = '';
steps.forEach((step, idx) => {
let row = document.createElement('div');
row.className = 'step-row';
// タイプ選択
let typeSel = `<select onchange="updateStep(${idx}, 'type', this.value)">`;
types.forEach(t => { typeSel += `<option value="${t.val}" ${step.type===t.val?'selected':''}>${t.name}</option>`; });
typeSel += `</select>`;
// サイズ選択
let sizeSel = `<select onchange="updateStep(${idx}, 'size', this.value)">`;
sizes.forEach(s => { sizeSel += `<option value="${s}" ${step.size===s?'selected':''}>${s}</option>`; });
sizeSel += `</select>`;
// 方向選択
let dirSel = `<select onchange="updateStep(${idx}, 'dir', this.value)">`;
dirs.forEach(d => { dirSel += `<option value="${d.val}" ${step.dir===d.val?'selected':''}>${d.name}</option>`; });
dirSel += `</select>`;
// 長さ入力
let lenInput = `<input type="number" value="${step.length}" style="width: 70px;" onchange="updateStep(${idx}, 'length', Number(this.value))">mm`;
// 削除ボタン
let delBtn = `<button class="delete" onclick="removeStep(${idx})">×</button>`;
row.innerHTML = typeSel + sizeSel + dirSel + lenInput + delBtn;
container.appendChild(row);
});
}
function addStep() {
steps.push({type: "STRAIGHT", size: "NW100", dir: "EAST", length: 500});
renderSteps();
generate();
}
function removeStep(idx) {
steps.splice(idx, 1);
renderSteps();
generate();
}
function updateStep(idx, key, val) {
steps[idx][key] = val;
}
renderSteps();
function generate() {
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 簡易アイソメ描画計算
let cx = canvas.width / 2;
let cy = canvas.height / 2 + 50;
let currX = cx, currY = cy;
let points = [{x: currX, y: currY, z: 0}];
let bom = {};
let supportList = [];
let totalLength = 0;
steps.forEach((s, i) => {
let dx = 0, dy = 0, dz = 0;
let l = s.length || 0;
totalLength += l;
if (s.dir === 'EAST') dx = l * 0.3;
if (s.dir === 'WEST') dx = -l * 0.3;
if (s.dir === 'NORTH') dy = -l * 0.2;
if (s.dir === 'SOUTH') dy = l * 0.2;
if (s.dir === 'UP') dz = -l * 0.3;
if (s.dir === 'DOWN') dz = l * 0.3;
// アイソメ投影 (Xは右下、Yは左下、Zは上)
let nextX = currX + dx - dy;
let nextY = currY + (dx + dy) * 0.5 + dz;
// 配管描画
ctx.beginPath();
ctx.moveTo(currX, currY);
ctx.lineTo(nextX, nextY);
ctx.lineWidth = s.size.includes('50') ? 4 : 6;
ctx.strokeStyle = '#007aff';
ctx.stroke();
currX = nextX;
currY = nextY;
points.push({x: currX, y: currY});
// BOM集計
if(!bom[s.size]) bom[s.size] = {straight: 0, el: 0, cr: 0};
if(s.type === 'STRAIGHT') bom[s.size].straight += l;
if(s.type === 'EL') bom[s.size].el += 1;
if(s.type === 'CR') bom[s.size].cr += 1;
// サポート目安(配管が1000mm超えたら仮置き)
if (totalLength >= 1000) {
supportList.push(`位置: 座標付近 (${Math.round(currX)}, ${Math.round(currY)})`);
totalLength = 0;
}
});
// テーブル更新
const bomTable = document.getElementById('bom-table');
bomTable.innerHTML = `<tr><th>品名・規格</th><th>仕様・種別</th><th>数量 / 位置</th></tr>`;
for (let [size, data] of Object.entries(bom)) {
if(data.straight > 0) {
bomTable.innerHTML += `<tr><td>直管 (${size})</td><td>ストレート</td><td>${data.straight} mm</td></tr>`;
}
if(data.el > 0) {
bomTable.innerHTML += `<tr><td>エルボー (${size})</td><td>EL継手</td><td>${data.el} 個</td></tr>`;
}
if(data.cr > 0) {
bomTable.innerHTML += `<tr><td>レデューサー</td><td>CR変換</td><td>${data.cr} 基</td></tr>`;
}
}
supportList.forEach((sup, idx) => {
bomTable.innerHTML += `<tr><td>配管サポート #${idx+1}</td><td>ハンガー/Lアングル</td><td>${sup}</td></tr>`;
});
}
generate();
</script>
</body>
</html>
スマホで直接動かすのはファイルの保存とかの壁があるから、もし今手元にパソコンがあったらそこにペーストして試してみてね!
Gemini 3.5 Flash Lite
あ、ごめん!iPhoneだもんね、スマホからでも一発でコピーできるように、余計な省略なしでちゃんと完全なコードを書き直すね。 下のコードブロックの右上にあるコピーボタン(またはコードを長押しして全選択)で、そのままコピーしてみて。 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>真空配管ジェネレータ(部材リスト対応版)</title> <style> body { font-family: sans-serif; padding: 15px; background: #f0f2f5; color: #333; } .container { max-width: 700px; margin: 0 auto; background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); } h2 { font-size: 1.2rem; margin-bottom: 15px; text-align: center; } .step-row { display: flex; gap: 5px; margin-bottom: 8px; align-items: center; background: #f8f9fa; padding: 8px; border-radius: 8px; } select, input { padding: 6px; font-size: 0.9rem; border: 1px solid #ccc; border-radius: 4px; } button { padding: 6px 12px; background: #007aff; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; } button.delete { background: #ff3b30; } .btn-container { text-align: center; margin: 15px 0; } canvas { border: 1px solid #ddd; background: #fafafa; width: 100%; max-height: 300px; border-radius: 8px; display: block; margin: 10px auto; } table { width: 100%; border-collapse: collapse; margin-top: 15px; font-size: 0.85rem; } th, td { border: 1px solid #ddd; padding: 6px; text-align: left; } th { background: #f1f3f5; } </style> </head> <body> <div class="container"> <h2>真空配管アイソメ・部材ジェネレータ</h2> <div id="steps-container"> <!-- 動的に行が追加されます --> </div> <div class="btn-container"> <button onclick="addStep()">+ 配管ルートを追加</button> <button onclick="generate()" style="background: #34c759;">更新・計算</button> </div> <canvas id="canvas" width="400" height="300"></canvas> <h3>部材リスト (BOM) & サポート</h3> <table id="bom-table"> <tr><th>品名・規格</th><th>仕様</th><th>数量 / 位置</th></tr> </table> </div> <script> const sizes = ["NW25", "NW40", "NW50", "NW63", "NW80", "NW100", "NW125", "NW160", "NW200", "ISO-MF25", "ISO-MF40", "ISO-MF50", "ISO-MF63", "ISO-MF80", "ISO-MF100", "ISO-BT25", "ISO-BT40", "ISO-BT50", "ISO-BT63", "ISO-BT80", "ISO-BT100", "25A", "40A", "50A", "80A", "100A", "150A", "200A", "250A"]; const types = [ {val: "STRAIGHT", name: "直管"}, {val: "EL", name: "エルボー(EL)"}, {val: "CR", name: "レデューサー(CR)"}, {val: "TEE", name: "チーズ(TEE)"}, {val: "FLEX", name: "NWフレキ"} ]; const dirs = [ {val: "EAST", name: "東(+X)"}, {val: "WEST", name: "西(-X)"}, {val: "NORTH", name: "北(+Y)"}, {val: "SOUTH", name: "南(-Y)"}, {val: "UP", name: "天(+Z)"}, {val: "DOWN", name: "地(-Z)"} ]; // 初期データ let steps = [ {type: "STRAIGHT", size: "NW100", dir: "UP", length: 1000}, {type: "EL", size: "NW100", dir: "EAST", length: 500}, {type: "CR", size: "NW100->NW80", dir: "EAST", length: 800} ]; function renderSteps() { const container = document.getElementById('steps-container'); container.innerHTML = ''; steps.forEach((step, idx) => { let row = document.createElement('div'); row.className = 'step-row'; // タイプ選択 let typeSel = <select onchange="updateStep(${idx}, 'type', this.value)">; types.forEach(t => { typeSel += <option value="${t.val}" ${step.type===t.val?'selected':''}>${t.name}</option>; }); typeSel += </select>; // サイズ選択 let sizeSel = <select onchange="updateStep(${idx}, 'size', this.value)">; sizes.forEach(s => { sizeSel += <option value="${s}" ${step.size===s?'selected':''}>${s}</option>; }); sizeSel += </select>; // 方向選択 let dirSel = <select onchange="updateStep(${idx}, 'dir', this.value)">; dirs.forEach(d => { dirSel += <option value="${d.val}" ${step.dir===d.val?'selected':''}>${d.name}</option>; }); dirSel += </select>; // 長さ入力 let lenInput = <input type="number" value="${step.length}" style="width: 70px;" onchange="updateStep(${idx}, 'length', Number(this.value))">mm; // 削除ボタン let delBtn = <button class="delete" onclick="removeStep(${idx})">×</button>; row.innerHTML = typeSel + sizeSel + dirSel + lenInput + delBtn; container.appendChild(row); }); } function addStep() { steps.push({type: "STRAIGHT", size: "NW100", dir: "EAST", length: 500}); renderSteps(); generate(); } function removeStep(idx) { steps.splice(idx, 1); renderSteps(); generate(); } function updateStep(idx, key, val) { steps[idx][key] = val; } renderSteps(); function generate() { const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvas.width, canvas.height); // 簡易アイソメ描画計算 let cx = canvas.width / 2; let cy = canvas.height / 2 + 50; let currX = cx, currY = cy; let points = [{x: currX, y: currY, z: 0}]; let bom = {}; let supportList = []; let totalLength = 0; steps.forEach((s, i) => { let dx = 0, dy = 0, dz = 0; let l = s.length || 0; totalLength += l; if (s.dir === 'EAST') dx = l 0.3; if (s.dir === 'WEST') dx = -l 0.3; if (s.dir === 'NORTH') dy = -l 0.2; if (s.dir === 'SOUTH') dy = l 0.2; if (s.dir === 'UP') dz = -l 0.3; if (s.dir === 'DOWN') dz = l 0.3; // アイソメ投影 (Xは右下、Yは左下、Zは上) let nextX = currX + dx - dy; let nextY = currY + (dx + dy) * 0.5 + dz; // 配管描画 ctx.beginPath(); ctx.moveTo(currX, currY); ctx.lineTo(nextX, nextY); ctx.lineWidth = s.size.includes('50') ? 4 : 6; ctx.strokeStyle = '#007aff'; ctx.stroke(); currX = nextX; currY = nextY; points.push({x: currX, y: currY}); // BOM集計 if(!bom[s.size]) bom[s.size] = {straight: 0, el: 0, cr: 0}; if(s.type === 'STRAIGHT') bom[s.size].straight += l; if(s.type === 'EL') bom[s.size].el += 1; if(s.type === 'CR') bom[s.size].cr += 1; // サポート目安(配管が1000mm超えたら仮置き) if (totalLength >= 1000) { supportList.push(位置: 座標付近 (${Math.round(currX)}, ${Math.round(currY)})); totalLength = 0; } }); // テーブル更新 const bomTable = document.getElementById('bom-table'); bomTable.innerHTML = <tr><th>品名・規格</th><th>仕様・種別</th><th>数量 / 位置</th></tr>; for (let [size, data] of Object.entries(bom)) { if(data.straight > 0) { bomTable.innerHTML += <tr><td>直管 (${size})</td><td>ストレート</td><td>${data.straight} mm</td></tr>; } if(data.el > 0) { bomTable.innerHTML += <tr><td>エルボー (${size})</td><td>EL継手</td><td>${data.el} 個</td></tr>; } if(data.cr > 0) { bomTable.innerHTML += <tr><td>レデューサー</td><td>CR変換</td><td>${data.cr} 基</td></tr>; } } supportList.forEach((sup, idx) => { bomTable.innerHTML += <tr><td>配管サポート #${idx+1}</td><td>ハンガー/Lアングル</td><td>${sup}</td></tr>; }); } generate(); </script> </body> </html> スマホで直接動かすのはファイルの保存とかの壁があるから、もし今手元にパソコンがあったらそこにペーストして試してみてね!