|
10 | 10 | background-color: #fff; |
11 | 11 | margin: 0; |
12 | 12 | padding: 0; |
| 13 | + font-size: 75%; |
13 | 14 | } |
14 | 15 | .container { |
15 | 16 | width: 96vw; |
|
31 | 32 | display: flex; |
32 | 33 | gap: 20px; |
33 | 34 | margin-bottom: 30px; |
| 35 | + flex-wrap: wrap; |
34 | 36 | } |
35 | | - .controls-left { |
36 | | - flex: 1 1 380px; |
37 | | - min-width: 320px; |
| 37 | + .controls-left, |
| 38 | + .controls-right { |
| 39 | + flex: 1 1 500px; |
| 40 | + min-width: 500px; |
38 | 41 | display: flex; |
39 | 42 | flex-direction: column; |
| 43 | + } |
| 44 | + .controls-left { |
40 | 45 | gap: 0; |
41 | 46 | } |
42 | 47 | .controls-right { |
43 | | - flex: 2 2 440px; |
44 | | - min-width: 340px; |
45 | | - display: flex; |
46 | | - flex-direction: column; |
47 | 48 | gap: 20px; |
48 | 49 | } |
49 | 50 | .control-group { |
50 | 51 | background-color: #f8f8f8; |
51 | | - padding: 15px; |
| 52 | + padding: 8px; |
52 | 53 | border-radius: 8px; |
53 | 54 | border: 1px solid #ddd; |
54 | 55 | } |
|
61 | 62 | .slider-container { |
62 | 63 | display: flex; |
63 | 64 | align-items: center; |
64 | | - gap: 10px; |
| 65 | + gap: 6px; |
| 66 | + flex-wrap: wrap; |
| 67 | + min-height: 24px; |
65 | 68 | } |
66 | 69 | input[type="range"] { |
67 | 70 | flex: 1; |
68 | | - height: 6px; |
| 71 | + height: 4px; |
69 | 72 | background: #ddd; |
70 | | - border-radius: 3px; |
| 73 | + border-radius: 2px; |
71 | 74 | outline: none; |
72 | 75 | -webkit-appearance: none; |
73 | 76 | } |
|
88 | 91 | border: none; |
89 | 92 | } |
90 | 93 | .value-display { |
91 | | - min-width: 50px; |
| 94 | + min-width: 40px; |
92 | 95 | text-align: center; |
93 | 96 | background-color: white; |
94 | | - padding: 4px 8px; |
| 97 | + padding: 1px 4px; |
95 | 98 | border-radius: 4px; |
96 | 99 | border: 1px solid #ccc; |
97 | | - font-size: 14px; |
| 100 | + font-size: 10px; |
98 | 101 | } |
99 | 102 | .density-inputs { |
100 | 103 | display: flex; |
101 | 104 | flex-direction: column; |
102 | | - gap: 18px; |
| 105 | + gap: 8px; |
103 | 106 | } |
104 | 107 | .density-box { |
105 | 108 | width: 30px; |
|
112 | 115 | vertical-align: middle; |
113 | 116 | } |
114 | 117 | .density-input { |
115 | | - display: flex; |
| 118 | + display: grid; |
| 119 | + grid-template-columns: 72px 1fr auto auto; |
116 | 120 | align-items: center; |
117 | | - gap: 10px; |
| 121 | + gap: 8px; |
| 122 | + } |
| 123 | + .density-input label { |
| 124 | + text-align: right; |
| 125 | + } |
| 126 | + .density-input input[type="range"] { |
| 127 | + min-width: 120px; |
118 | 128 | } |
119 | 129 | .density-input input[type="number"] { |
120 | 130 | width: 60px; |
121 | | - padding: 8px; |
| 131 | + padding: 4px; |
122 | 132 | border: 1px solid #ccc; |
123 | 133 | border-radius: 4px; |
124 | 134 | text-align: center; |
| 135 | + font-size: 10px; |
125 | 136 | } |
126 | 137 | .canvas-container { |
127 | 138 | text-align: center; |
@@ -225,21 +236,21 @@ <h1>USM簡易シミュレーター</h1> |
225 | 236 | <label>強さ (Amount)</label> |
226 | 237 | <div class="slider-container"> |
227 | 238 | <input type="range" id="amount" min="0" max="500" value="100" step="1"> |
228 | | - <div class="value-display" id="amountValue">100%</div> |
| 239 | + <input type="number" class="value-display" id="amountValue" min="0" max="500" value="100"> |
229 | 240 | </div> |
230 | 241 | </div> |
231 | 242 | <div class="control-group"> |
232 | 243 | <label>半径 (Radius)</label> |
233 | 244 | <div class="slider-container"> |
234 | 245 | <input type="range" id="radius" min="0.1" max="5" step="0.1" value="1"> |
235 | | - <div class="value-display" id="radiusValue">1.0</div> |
| 246 | + <input type="number" class="value-display" id="radiusValue" min="0.1" max="5" step="0.1" value="1.0"> |
236 | 247 | </div> |
237 | 248 | </div> |
238 | 249 | <div class="control-group"> |
239 | 250 | <label>閾値 (Threshold)</label> |
240 | 251 | <div class="slider-container"> |
241 | 252 | <input type="range" id="threshold" min="0" max="50" value="0"> |
242 | | - <div class="value-display" id="thresholdValue">0</div> |
| 253 | + <input type="number" class="value-display" id="thresholdValue" min="0" max="50" value="0"> |
243 | 254 | </div> |
244 | 255 | </div> |
245 | 256 | </div> |
@@ -452,9 +463,9 @@ <h1>USM簡易シミュレーター</h1> |
452 | 463 | // 値を表示 |
453 | 464 | startDensityValue.textContent = startDensity; |
454 | 465 | endDensityValue.textContent = endDensity; |
455 | | - amountValue.textContent = amount + '%'; |
456 | | - radiusValue.textContent = radius.toFixed(1); |
457 | | - thresholdValue.textContent = threshold; |
| 466 | + amountValue.value = amount; |
| 467 | + radiusValue.value = radius.toFixed(1); |
| 468 | + thresholdValue.value = threshold; |
458 | 469 | // 濃度ボックスの色を更新 |
459 | 470 | startDensityBox.style.background = `rgb(${startDensity},${startDensity},${startDensity})`; |
460 | 471 | endDensityBox.style.background = `rgb(${endDensity},${endDensity},${endDensity})`; |
@@ -585,9 +596,41 @@ <h1>USM簡易シミュレーター</h1> |
585 | 596 | // 各スライダー等の値変更時にグラフ再描画 |
586 | 597 | startDensityInput.addEventListener('input', drawGraph); |
587 | 598 | endDensityInput.addEventListener('input', drawGraph); |
588 | | - amountSlider.addEventListener('input', drawGraph); |
589 | | - radiusSlider.addEventListener('input', drawGraph); |
590 | | - thresholdSlider.addEventListener('input', drawGraph); |
| 599 | + amountSlider.addEventListener('input', () => { |
| 600 | + amountValue.value = amountSlider.value; |
| 601 | + drawGraph(); |
| 602 | + }); |
| 603 | + radiusSlider.addEventListener('input', () => { |
| 604 | + radiusValue.value = radiusSlider.value; |
| 605 | + drawGraph(); |
| 606 | + }); |
| 607 | + thresholdSlider.addEventListener('input', () => { |
| 608 | + thresholdValue.value = thresholdSlider.value; |
| 609 | + drawGraph(); |
| 610 | + }); |
| 611 | + |
| 612 | + // input[type="number"]にinputイベント追加 |
| 613 | + amountValue.addEventListener('input', () => { |
| 614 | + let v = Math.max(0, Math.min(500, parseInt(amountValue.value) || 0)); |
| 615 | + amountValue.value = v; |
| 616 | + amountSlider.value = v; |
| 617 | + drawGraph(); |
| 618 | + }); |
| 619 | + // radiusValueはinputイベントではなくchangeイベントで制御 |
| 620 | + radiusValue.addEventListener('change', () => { |
| 621 | + let v = parseFloat(radiusValue.value); |
| 622 | + if (isNaN(v)) return; |
| 623 | + v = Math.max(0.1, Math.min(5, v)); |
| 624 | + radiusValue.value = v; |
| 625 | + radiusSlider.value = v; |
| 626 | + drawGraph(); |
| 627 | + }); |
| 628 | + thresholdValue.addEventListener('input', () => { |
| 629 | + let v = Math.max(0, Math.min(50, parseInt(thresholdValue.value) || 0)); |
| 630 | + thresholdValue.value = v; |
| 631 | + thresholdSlider.value = v; |
| 632 | + drawGraph(); |
| 633 | + }); |
591 | 634 |
|
592 | 635 | // ウインドウリサイズ時にキャンバスサイズ調整と再描画 |
593 | 636 | window.addEventListener('resize', drawGraph); |
|
0 commit comments