印刷面付シュミレータ.html × Claude 3.5 Sonnet
for 印刷営業 & 生産管理 2024_10_10
Claude 3.5 Sonnetが熱い
ついこないだまでChatGPT4oとPerplexityがコーディングにはベストチョイスだと思ってたのに、今Claude 3.5 Sonnetにハマってます。はじめて課金しちゃおうかなと思い始めてます。
毎日使ってるんだけどすぐ文字数オーバーになっちゃう。
最近使ったのはvbaとhtml+CSS+javascriptで、部分的に修正箇所を示してくれるんだけど、もうずーーとやってると、めんどくさくなってきて、内容も理解せず、全コード出させてただコピペして動作確認。
良く見ると修正箇所は1行だけなのに全コード出させるもんだから、そりゃ、すぐMAXに達しちゃうわな(泣)
印刷面付シュミレータ.html
で、何かhtmlで作れそうなのないかなと考えてるうちに、そうだ面付シュミレータできるんかな?と急に思いついたってわけ。
簡単なプロンプトでかなり完成度高いコードを書いてくれたんでホント感動で、しかもClaude 3.5 Sonnetは右ペインでリアルタイムプレビューしてくれるからブラウザのウィンドウ1つで済むのが地味にGoodです。
プロンプト
1回目
html+javascriptで作りたい
1)用紙サイズ A全、A判半裁、菊全、菊半裁、四六全、四六半裁、四六4裁の7バリエーションの用紙サイズをプルダウンで選ぶと右側に罫線で表示
2)任意の製品仕上がりサイズを入力。但し縦向きと横向きをプルダウン等で選択可能とする
3)面付ボタンを押すと1)の用紙サイズの中に2)がいくつ並ぶか罫線を描画して表示
まとめると※1)用紙サイズを罫線で表示し、その中に納まるよう2)のサイズの罫線を面付し、敷き詰めて表示するウェブアプリを作りたい
2回目
1)上にクワエとして15mm、下にクワエ尻10mm取り、表示はクワエ15mm、クワエ尻10mm
2)製品サイズの天地左右すべてにドブ3mm加えてプレビューしてください。
3回目とつづく...
驚いたのは1回目のプロンプトだけで、求めていたレイアウトがもうほぼ完成してたし、用紙サイズも勝手に調べてくれちゃってるし。
これは完成度高いです。すばらい
で、Claudeが文字数オーバーになると続きを他のPerplexityとかでやろうとするんだけど、壊されちゃうんだよね。まぁたまたまかも知れないけど。
という訳で、現在の為替レートで円換算2980円くらい。悩むなホント、もっといいのが出てくるかも知れんし。
普段は毎日ばりばり使う訳じゃないし。。悩ましいです。
下記が文字オーバーする前の最終版 自前サーバに上げました。http://printnet.droppages.net/imposition_simulator.html
dropbox内にpublicフォルダを作ってホスティングしてくれるサービス。
月1000円。これも契約しちゃいました。以前は自宅サーバ立ててたんですけど、今の自宅賃貸は固定ipできない契約なんで。
htmlはこちら
※社内公開するので、今後もう少し手を加えると思います。
update2024_10_11
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>印刷面付シミュレーター</title>
<style>
.container {
display: flex;
gap: 20px;
padding: 20px;
}
.controls {
width: 300px;
}
.preview {
flex-grow: 1;
}
.canvas-container {
border: 1px solid #ccc;
margin-top: 10px;
overflow: auto;
position: relative;
}
select, input, button {
width: 100%;
margin-bottom: 10px;
padding: 5px;
box-sizing: border-box;
}
.input-group {
display: flex;
gap: 10px;
}
.input-group input {
width: calc(50% - 5px);
}
button {
padding: 10px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<div class="container">
<div class="controls">
<h2>設定</h2>
<label for="paperSize">用紙サイズ:</label>
<select id="paperSize" onchange="calculateImposition()">
<option value="a_full">A全判 (625×880mm)</option>
<option value="a_half">A半裁 (625×440mm)</option>
<option value="a_quarter">A判4裁 (438×310mm)</option>
<option value="kiku_full">菊全判 (636×939mm)</option>
<option value="kiku_half">菊半裁 (469×636mm)</option>
<option value="kiku_quarter">菊判4裁 (467×316mm)</option>
<option value="shiroku_full">四六全判 (788×1091mm)</option>
<option value="shiroku_half">四六半裁 (788×545mm)</option>
<option value="shiroku_quarter">四六4裁 (394×545mm)</option>
<option value="shiroku_third">四六全三つ切り (364×788mm)</option>
</select>
<label for="productWidth">製品サイズ (mm):</label>
<div class="input-group">
<input type="number" id="productWidth" placeholder="幅" min="1" value="210">
<input type="number" id="productHeight" placeholder="高さ" min="1" value="297">
</div>
<label for="orientation">製品方向:</label>
<select id="orientation">
<option value="portrait">縦向き</option>
<option value="landscape">横向き</option>
</select>
<label for="kuwae">上クワエ (mm):</label>
<input type="number" id="kuwae" min="0" value="15">
<label for="bleed">断裁余白(ドブ) (mm):</label>
<input type="number" id="bleed" min="0" value="3">
<button id="calculateButton" onclick="calculateImposition()">面付計算</button>
</div>
<div class="preview">
<h2>プレビュー</h2>
<div class="canvas-container">
<canvas id="previewCanvas"></canvas>
</div>
</div>
</div>
<script>
const paperSizes = {
a_full: { width: 880, height: 625 },
a_half: { width: 440, height: 625 },
a_quarter: { width: 438, height: 310 },
kiku_full: { width: 939, height: 636 },
kiku_half: { width: 636, height: 469 },
kiku_quarter: { width: 467, height: 316 },
shiroku_full: { width: 1091, height: 788 },
shiroku_half: { width: 545, height: 788 },
shiroku_quarter: { width: 545, height: 394 },
shiroku_third: { width: 788, height: 364 }
};
const canvas = document.getElementById('previewCanvas');
const ctx = canvas.getContext('2d');
const SCALE = 0.5;
const MARGIN = 20;
function calculateImposition() {
const paperSizeSelect = document.getElementById('paperSize');
const productWidth = Number(document.getElementById('productWidth').value);
const productHeight = Number(document.getElementById('productHeight').value);
const orientation = document.getElementById('orientation').value;
const kuwae = Number(document.getElementById('kuwae').value);
const bleed = Number(document.getElementById('bleed').value);
if (!productWidth || !productHeight) {
alert('製品サイズを入力してください');
return;
}
const paper = paperSizes[paperSizeSelect.value];
canvas.width = paper.width * SCALE + (MARGIN * 2);
canvas.height = paper.height * SCALE + (MARGIN * 2);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.strokeStyle = '#000';
ctx.lineWidth = 2;
ctx.strokeRect(MARGIN, MARGIN, paper.width * SCALE, paper.height * SCALE);
// 用紙サイズを表示
ctx.fillStyle = 'red';
ctx.font = '12px Arial';
ctx.fillText(`${paper.width}×${paper.height}mm`, MARGIN + 5, MARGIN + 15);
ctx.strokeStyle = '#888';
ctx.lineWidth = 1;
ctx.setLineDash([5, 5]);
const topMarginLine = MARGIN + (kuwae * SCALE);
ctx.beginPath();
ctx.moveTo(MARGIN, topMarginLine);
ctx.lineTo(MARGIN + paper.width * SCALE, topMarginLine);
ctx.stroke();
ctx.setLineDash([]);
let finalProductWidth = orientation === 'portrait' ? productWidth : productHeight;
let finalProductHeight = orientation === 'portrait' ? productHeight : productWidth;
finalProductWidth += (bleed * 2);
finalProductHeight += (bleed * 2);
const usableHeight = paper.height - kuwae;
const cols = Math.floor(paper.width / finalProductWidth);
const rows = Math.floor(usableHeight / finalProductHeight);
const totalWidth = cols * finalProductWidth;
const totalHeight = rows * finalProductHeight;
const xOffset = (paper.width - totalWidth) / 2;
const yOffset = (usableHeight - totalHeight) / 2;
ctx.strokeStyle = '#0066ff';
ctx.lineWidth = 1;
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
const x = (col * finalProductWidth * SCALE) + MARGIN + (xOffset * SCALE);
const y = (row * finalProductHeight * SCALE) + MARGIN + (kuwae * SCALE) + (yOffset * SCALE);
ctx.setLineDash([5, 5]);
ctx.strokeStyle = '#0066ff';
ctx.strokeRect(x, y, finalProductWidth * SCALE, finalProductHeight * SCALE);
ctx.setLineDash([]);
ctx.strokeStyle = '#000';
ctx.strokeRect(
x + (bleed * SCALE),
y + (bleed * SCALE),
(finalProductWidth - (bleed * 2)) * SCALE,
(finalProductHeight - (bleed * 2)) * SCALE
);
}
}
const total = rows * cols;
ctx.fillStyle = '#000';
ctx.font = '14px Arial';
ctx.fillText(`面付数: ${total}面`, MARGIN, canvas.height - 5);
}
document.getElementById('productWidth').addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
document.getElementById('productHeight').focus();
}
});
document.getElementById('productHeight').addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
document.getElementById('orientation').focus();
}
});
document.getElementById('orientation').addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
document.getElementById('kuwae').focus();
}
});
document.getElementById('kuwae').addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
document.getElementById('bleed').focus();
}
});
document.getElementById('bleed').addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
document.getElementById('calculateButton').focus();
}
});
// 初期表示
calculateImposition();
</script>
</body>
</html>
この記事が気に入ったらサポートをしてみませんか?