goo blog サービス終了のお知らせ 

CyberChaos(さいばかおす)

プログラミング言語、トランスパイラ、RPA、ChatGPT、データマイニング、リバースエンジニアリングのための忘備録

HTMLファイルに電気回路図を描くJavascript

2025-05-22 06:25:16 | アイデア起業・アイデア売買



はい、HTMLファイル内でJavaScriptを使って電気回路図を描く基本的な例を示します。ここでは、HTML5のcanvas要素を使って図形を描画します。
簡単な抵抗回路図を描く例
この例では、電圧源、抵抗、およびグランドのシンボルを描画し、それらを線で接続します。
<!DOCTYPE html>
<html lang="ja">
<head>
<title>電気回路図の例</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
background-color: #f0f0f0;
}
canvas {
border: 1px solid #ccc;
background-color: white;
}
</style>
</head>
<body>
<canvas id="circuitCanvas" width="600" height="400"></canvas>

<script>
const canvas = document.getElementById('circuitCanvas');
const ctx = canvas.getContext('2d');

// 回路図の描画設定
const componentColor = '#333';
const lineColor = '#000';
const lineWidth = 2;
const fontSize = 14;
const font = `${fontSize}px Arial`;

// 描画関数
function drawLine(x1, y1, x2, y2) {
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.strokeStyle = lineColor;
ctx.lineWidth = lineWidth;
ctx.stroke();
}

function drawText(text, x, y, align = 'center', baseline = 'middle') {
ctx.font = font;
ctx.fillStyle = componentColor;
ctx.textAlign = align;
ctx.textBaseline = baseline;
ctx.fillText(text, x, y);
}

// 電圧源の描画 (直流電源シンボル)
function drawVoltageSource(x, y, size = 30) {
ctx.strokeStyle = componentColor;
ctx.lineWidth = lineWidth;

// 円
ctx.beginPath();
ctx.arc(x, y, size / 2, 0, Math.PI * 2);
ctx.stroke();

// プラスとマイナス
ctx.fillText('+', x - size / 4, y - size / 4);
ctx.fillText('-', x + size / 4, y + size / 4);
}

// 抵抗の描画 (ギザギザの線)
function drawResistor(x1, y1, x2, y2, segments = 5, size = 15) {
ctx.strokeStyle = componentColor;
ctx.lineWidth = lineWidth;

const dx = x2 - x1;
const dy = y2 - y1;
const len = Math.sqrt(dx * dx + dy * dy);

// 線の向きを計算
const angle = Math.atan2(dy, dx);
const perpAngle = angle + Math.PI / 2; // 垂直な方向

ctx.beginPath();
ctx.moveTo(x1, y1);

for (let i = 0; i
const ratio = (i + 0.5) / segments;
const midX = x1 + dx * ratio;
const midY = y1 + dy * ratio;

const offset = (i % 2 === 0 ? 1 : -1) * size / 2;
const zigzagX = midX + offset * Math.cos(perpAngle);
const zigzagY = midY + offset * Math.sin(perpAngle);

ctx.lineTo(zigzagX, zigzagY);
}
ctx.lineTo(x2, y2);
ctx.stroke();
}

// グランドの描画
function drawGround(x, y, size = 20) {
ctx.strokeStyle = componentColor;
ctx.lineWidth = lineWidth;

ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x, y + size);
ctx.stroke();

ctx.beginPath();
ctx.moveTo(x - size / 2, y + size);
ctx.lineTo(x + size / 2, y + size);
ctx.stroke();

ctx.beginPath();
ctx.moveTo(x - size / 4, y + size + size / 4);
ctx.lineTo(x + size / 4, y + size + size / 4);
ctx.stroke();
}

// 回路図の描画実行
function drawCircuit() {
ctx.clearRect(0, 0, canvas.width, canvas.height); // キャンバスをクリア

// コンポーネントの位置
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;

const voltageSourcePos = { x: centerX - 150, y: centerY };
const resistor1Pos1 = { x: voltageSourcePos.x + 50, y: voltageSourcePos.y };
const resistor1Pos2 = { x: resistor1Pos1.x + 100, y: resistor1Pos1.y };
const resistor2Pos1 = { x: resistor1Pos2.x + 50, y: resistor1Pos2.y };
const resistor2Pos2 = { x: resistor2Pos1.x + 100, y: resistor2Pos1.y };
const groundPos = { x: resistor2Pos2.x, y: resistor2Pos2.y + 70 };

// 電圧源
drawVoltageSource(voltageSourcePos.x, voltageSourcePos.y, 40);
drawText('Vs', voltageSourcePos.x, voltageSourcePos.y - 30);

// 抵抗1
drawResistor(resistor1Pos1.x, resistor1Pos1.y, resistor1Pos2.x, resistor1Pos2.y, 7, 10);
drawText('R1', (resistor1Pos1.x + resistor1Pos2.x) / 2, resistor1Pos1.y - 20);

// 抵抗2
drawResistor(resistor2Pos1.x, resistor2Pos1.y, resistor2Pos2.x, resistor2Pos2.y, 7, 10);
drawText('R2', (resistor2Pos1.x + resistor2Pos2.x) / 2, resistor2Pos1.y - 20);

// グランド
drawGround(groundPos.x, groundPos.y);

// 配線
drawLine(voltageSourcePos.x + 20, voltageSourcePos.y, resistor1Pos1.x, resistor1Pos1.y); // 電圧源からR1へ
drawLine(resistor1Pos2.x, resistor1Pos2.y, resistor2Pos1.x, resistor2Pos1.y); // R1からR2へ
drawLine(resistor2Pos2.x, resistor2Pos2.y, groundPos.x, groundPos.y - 20); // R2からグランドへ

// グランドの上の電圧源の負極から配線
drawLine(voltageSourcePos.x, voltageSourcePos.y + 20, voltageSourcePos.x, groundPos.y - 20);
drawLine(voltageSourcePos.x, groundPos.y - 20, groundPos.x, groundPos.y - 20);
}

// ページロード時に回路図を描画
window.addEventListener('load', drawCircuit);

// ウィンドウサイズが変更されたら再描画 (レスポンシブ対応)
window.addEventListener('resize', () => {
// ここでキャンバスのサイズを動的に変更することもできます
// canvas.width = window.innerWidth * 0.8;
// canvas.height = window.innerHeight * 0.7;
drawCircuit();
});

</script>
</body>
</html>

コードの説明
* HTML構造:
* <!DOCTYPE html>: HTML5文書であることを宣言します。
* <html lang="ja">: 言語を日本語に設定します。
* <head>:
* : 文字コードをUTF-8に設定します。
* : モバイルデバイスでの表示を最適化します。
* <title>電気回路図の例</title>: ブラウザタブに表示されるタイトルです。
* <style>: CSSでキャンバスの基本的なスタイル(枠線、背景色、中央寄せなど)を設定しています。
* <body>:
* <canvas id="circuitCanvas" width="600" height="400"></canvas>: 回路図を描画するためのcanvas要素です。id属性でJavaScriptから参照できるようにし、widthとheightでキャンバスの初期サイズを設定します。
* JavaScript (<script>タグ内):
* const canvas = document.getElementById('circuitCanvas');: idがcircuitCanvasの要素(つまりcanvas要素)を取得します。
* const ctx = canvas.getContext('2d');: canvas要素の2D描画コンテキストを取得します。このctxオブジェクトを通じて、線、図形、テキストなどを描画します。
* 描画設定:
* componentColor, lineColor, lineWidth, fontSize, font: 描画に使用する色、線の太さ、フォントなどの定数を定義します。これにより、見た目を簡単に変更できます。
* 汎用描画関数:
* drawLine(x1, y1, x2, y2): 指定された座標間に線を描画する関数です。
* ctx.beginPath(): 新しいパスの描画を開始します。
* ctx.moveTo(x1, y1): パスの開始点を設定します。
* ctx.lineTo(x2, y2): パスの現在の点から指定された点まで線を描画します。
* ctx.strokeStyle = lineColor;: 線の色を設定します。
* ctx.lineWidth = lineWidth;: 線の太さを設定します。
* ctx.stroke();: 現在のパスを線として描画します。
* drawText(text, x, y, align, baseline): テキストを描画する関数です。
* ctx.font, ctx.fillStyle, ctx.textAlign, ctx.textBaseline: テキストのフォント、色、配置などを設定します。
* ctx.fillText(text, x, y);: 指定されたテキストを指定された座標に描画します。
* 回路部品の描画関数:
* drawVoltageSource(x, y, size): 直流電圧源のシンボル(円とプラス・マイナス記号)を描画します。
* drawResistor(x1, y1, x2, y2, segments, size): 抵抗のギザギザのシンボルを描画します。線の両端の座標とギザギザの数、大きさを指定できます。これは少し複雑な幾何学計算を含んでいます。
* drawGround(x, y, size): グランドのシンボル(複数の横線)を描画します。
* drawCircuit()関数:
* ctx.clearRect(0, 0, canvas.width, canvas.height);: 新しい回路図を描画する前に、キャンバス全体をクリアします。
* 各部品の描画関数を呼び出して、それぞれの部品をキャンバス上の特定の位置に配置します。
* drawLine関数を使って、部品間を配線します。
* イベントリスナー:
* window.addEventListener('load', drawCircuit);: HTMLが完全に読み込まれた後(すべての画像なども)、drawCircuit関数を実行して回路図を描画します。
* window.addEventListener('resize', ...);: ウィンドウのサイズが変更されたときにdrawCircuitを再度呼び出すことで、簡易的なレスポンシブ対応を行います。
実行方法
* 上記のコードをcircuit.htmlなどの名前で保存します。
* このHTMLファイルをWebブラウザ(Chrome, Firefox, Edgeなど)で開きます。
すると、指定したサイズのキャンバス上に、簡単な抵抗回路図が表示されるはずです。
拡張のアイデア
* より多くの部品: キャパシタ、インダクタ、ダイオード、トランジスタなどのシンボルを追加する関数を作成します。
* 部品のプロパティ: 抵抗値(R1 = 1kΩ)、電圧値(Vs = 5V)などを表示する機能を追加します。
* イベント処理:
* 部品をクリックするとプロパティを表示する。
* ドラッグ&ドロップで部品を移動できるようにする。
* 新しい部品をキャンバスにドロップする。
* ズームとパン: 回路図を拡大・縮小したり、キャンバス内を移動したりする機能。
* データ構造: 回路図の部品と接続をオブジェクトの配列として管理し、それらを元に描画する。これにより、回路図の保存や読み込みが容易になります。
* グリッド: 部品を配置しやすくするために、キャンバス上にグリッド線を表示します。
* SVGの使用: canvasの代わりにSVG(Scalable Vector Graphics)を使用することも検討できます。SVGはDOM要素として扱えるため、各部品が独立した要素になり、インタラクティブな操作がしやすくなります。
* ライブラリ: より高度な回路図描画には、既存のJavaScriptライブラリ(例: JointJS, mxGraphなど、ただし回路図に特化したものは少ないかもしれません)を検討するのも良いでしょう。
これはあくまで基本的なスタート地点です。複雑な回路図描画アプリケーションを作成するには、さらに多くの機能とロジックが必要になります。

<!DOCTYPE html>
<html lang="ja">
<head>
<title>RLC並列回路図の例</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
background-color: #f0f0f0;
}
canvas {
border: 1px solid #ccc;
background-color: white;
}
</style>
</head>
<body>
<canvas id="circuitCanvas" width="700" height="450"></canvas>

<script>
const canvas = document.getElementById('circuitCanvas');
const ctx = canvas.getContext('2d');

// 回路図の描画設定
const componentColor = '#333';
const lineColor = '#000';
const lineWidth = 2;
const fontSize = 14;
const font = `${fontSize}px Arial`;

// 描画関数
function drawLine(x1, y1, x2, y2) {
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.strokeStyle = lineColor;
ctx.lineWidth = lineWidth;
ctx.stroke();
}

function drawText(text, x, y, align = 'center', baseline = 'middle') {
ctx.font = font;
ctx.fillStyle = componentColor;
ctx.textAlign = align;
ctx.textBaseline = baseline;
ctx.fillText(text, x, y);
}

// 交流電圧源の描画 (正弦波シンボル)
function drawACVoltageSource(x, y, size = 40) {
ctx.strokeStyle = componentColor;
ctx.lineWidth = lineWidth;

// 円
ctx.beginPath();
ctx.arc(x, y, size / 2, 0, Math.PI * 2);
ctx.stroke();

// 正弦波
ctx.beginPath();
ctx.moveTo(x - size / 4, y);
ctx.quadraticCurveTo(x - size / 8, y - size / 4, x, y);
ctx.quadraticCurveTo(x + size / 8, y + size / 4, x + size / 4, y);
ctx.stroke();
}

// 抵抗の描画 (ギザギザの線)
function drawResistor(x1, y1, x2, y2, segments = 5, size = 15) {
ctx.strokeStyle = componentColor;
ctx.lineWidth = lineWidth;

const dx = x2 - x1;
const dy = y2 - y1;
const len = Math.sqrt(dx * dx + dy * dy);

// 線の向きを計算
const angle = Math.atan2(dy, dx);
const perpAngle = angle + Math.PI / 2; // 垂直な方向

ctx.beginPath();
ctx.moveTo(x1, y1);

for (let i = 0; i
const ratio = (i + 0.5) / segments;
const midX = x1 + dx * ratio;
const midY = y1 + dy * ratio;

const offset = (i % 2 === 0 ? 1 : -1) * size / 2;
const zigzagX = midX + offset * Math.cos(perpAngle);
const zigzagY = midY + offset * Math.sin(perpAngle);

ctx.lineTo(zigzagX, zigzagY);
}
ctx.lineTo(x2, y2);
ctx.stroke();
}

// インダクタの描画 (コイル)
function drawInductor(x1, y1, x2, y2, coils = 4, radius = 8) {
ctx.strokeStyle = componentColor;
ctx.lineWidth = lineWidth;

const dx = x2 - x1;
const dy = y2 - y1;
const len = Math.sqrt(dx * dx + dy * dy);
const angle = Math.atan2(dy, dx);

ctx.save();
ctx.translate(x1, y1);
ctx.rotate(angle);

ctx.beginPath();
ctx.moveTo(0, 0);

const coilLength = len / coils;
for (let i = 0; i
const startX = i * coilLength;
const endX = (i + 1) * coilLength;
const midX = (startX + endX) / 2;

const sign = (i % 2 === 0) ? 1 : -1;
ctx.arc(midX, sign * radius, radius, Math.PI / 2 + Math.PI * sign, Math.PI / 2 - Math.PI * sign, sign < 0);
}
ctx.lineTo(len, 0);
ctx.stroke();

ctx.restore();
}

// コンデンサの描画 (平行な板)
function drawCapacitor(x1, y1, x2, y2, plateLength = 20, gap = 5) {
ctx.strokeStyle = componentColor;
ctx.lineWidth = lineWidth;

const dx = x2 - x1;
const dy = y2 - y1;
const len = Math.sqrt(dx * dx + dy * dy);
const angle = Math.atan2(dy, dx);

ctx.save();
ctx.translate(x1, y1);
ctx.rotate(angle);

// 接続線
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo((len - gap) / 2, 0);
ctx.moveTo((len + gap) / 2, 0);
ctx.lineTo(len, 0);
ctx.stroke();

// 平行な板
const plateX1 = (len - gap) / 2;
const plateX2 = (len + gap) / 2;
const plateY1 = -plateLength / 2;
const plateY2 = plateLength / 2;

drawLine(plateX1, plateY1, plateX1, plateY2);
drawLine(plateX2, plateY1, plateX2, plateY2);

ctx.restore();
}


// グランドの描画
function drawGround(x, y, size = 20) {
ctx.strokeStyle = componentColor;
ctx.lineWidth = lineWidth;

ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x, y + size);
ctx.stroke();

ctx.beginPath();
ctx.moveTo(x - size / 2, y + size);
ctx.lineTo(x + size / 2, y + size);
ctx.stroke();

ctx.beginPath();
ctx.moveTo(x - size / 4, y + size + size / 4);
ctx.lineTo(x + size / 4, y + size + size / 4);
ctx.stroke();
}

// 回路図の描画実行
function drawCircuit() {
ctx.clearRect(0, 0, canvas.width, canvas.height); // キャンバスをクリア

// コンポーネントの位置
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;

const sourceY = centerY - 50;
const topRailY = sourceY;
const bottomRailY = sourceY + 150; // 各部品の下端が揃うように

const sourceX = centerX - 250;
const comp1X = centerX - 100;
const comp2X = centerX;
const comp3X = centerX + 100;
const groundX = centerX + 250;

// 交流電圧源
drawACVoltageSource(sourceX, sourceY, 50);
drawText('Vs', sourceX, sourceY - 35);
drawText('AC', sourceX, sourceY + 35);

// 上部の配線 (電圧源から各部品へ分岐)
drawLine(sourceX + 25, topRailY, comp1X, topRailY);
drawLine(comp1X, topRailY, comp3X + 25, topRailY); // 各部品の接続点まで線をつなぐ

// 抵抗 (R)
drawResistor(comp1X, topRailY, comp1X, bottomRailY - 20, 7, 10);
drawText('R', comp1X, bottomRailY - 50, 'center', 'bottom');
drawText('1kΩ', comp1X, bottomRailY - 30);


// インダクタ (L)
drawInductor(comp2X, topRailY, comp2X, bottomRailY - 20, 5, 10);
drawText('L', comp2X, bottomRailY - 50, 'center', 'bottom');
drawText('10mH', comp2X, bottomRailY - 30);

// コンデンサ (C)
drawCapacitor(comp3X, topRailY, comp3X, bottomRailY - 20, 20, 10);
drawText('C', comp3X, bottomRailY - 50, 'center', 'bottom');
drawText('100nF', comp3X, bottomRailY - 30);

// 下部の配線 (各部品からグランドへ接続)
drawLine(comp1X, bottomRailY, comp2X, bottomRailY);
drawLine(comp2X, bottomRailY, comp3X, bottomRailY);
drawLine(comp3X, bottomRailY, groundX, bottomRailY);

// 電圧源の負極から下部の配線へ
drawLine(sourceX, sourceY + 25, sourceX, bottomRailY);
drawLine(sourceX, bottomRailY, comp1X, bottomRailY);


// グランド
drawGround(groundX, bottomRailY);
}

// ページロード時に回路図を描画
window.addEventListener('load', drawCircuit);

// ウィンドウサイズが変更されたら再描画 (簡易的なレスポンシブ対応)
window.addEventListener('resize', drawCircuit);

</script>
</body>
</html>

引き続きRLC並列回路図を描くJavascriptソースコードを書いてもらったが、これはうまくいかなかった。




最新の画像もっと見る

コメントを投稿

サービス終了に伴い、10月1日にコメント投稿機能を終了させていただく予定です。
ブログ作成者から承認されるまでコメントは反映されません。