import QtQuick Canvas { id: canvas width: 100; height: 160 // 入力プロパティ property int value: 0 property bool showDot: false property real reading: 0 // 現在のセンサー数値 property real threshold1: 0 // アンバーになる値 property real threshold2: 0 // 赤になる値 // デザイン設定 property real skewAngle: 8 property real gap: 4 property real thickness: 16 // 状態に基づいた色の自動判定 readonly property color activeColor: { if (reading >= threshold2) return "#CC0000"; // やや暗めの赤 if (reading >= threshold1) return "#FFBF00"; // アンバー return "#006622"; // 通常時の暗めの緑 } readonly property color inactiveColor: "#051505" // 消灯時(背景に馴染ませる) // 再描画トリガー onActiveColorChanged: requestPaint() onValueChanged: requestPaint() onShowDotChanged: requestPaint() antialiasing: true onPaint: { var ctx = getContext("2d"); ctx.reset(); ctx.clearRect(0, 0, width, height); var angleRad = skewAngle * Math.PI / 180; ctx.transform(1, 0, -Math.tan(angleRad), 1, height * Math.tan(angleRad), 0); var p = [ 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x27, 0x7F, 0x6F ][value % 10] || 0; function drawShape(points, on) { ctx.beginPath(); ctx.moveTo(points[0].x, points[0].y); for (var i = 1; i < points.length; i++) ctx.lineTo(points[i].x, points[i].y); ctx.closePath(); ctx.fillStyle = on ? activeColor : inactiveColor; // 閾値を超えた時だけ少し光らせる演出 ctx.shadowBlur = (on && reading >= threshold1) ? 10 : 0; ctx.shadowColor = activeColor; ctx.fill(); } var w = width * 0.75; var h = height; var t = thickness; var g = gap; // セグメント座標計算 (六角形) drawShape([{x:t+g, y:0}, {x:w-t-g, y:0}, {x:w-t*1.5-g, y:t}, {x:t*1.5+g, y:t}], p & 0x01); // A drawShape([{x:w-t, y:t+g}, {x:w, y:t*1.5+g}, {x:w, y:h/2-t/2-g}, {x:w-t, y:h/2-g}], p & 0x02); // B drawShape([{x:w-t, y:h/2+g}, {x:w, y:h/2+t/2+g}, {x:w, y:h-t*1.5-g}, {x:w-t, y:h-t-g}], p & 0x04); // C drawShape([{x:t*1.5+g, y:h-t}, {x:w-t*1.5-g, y:h-t}, {x:w-t-g, y:h}, {x:t+g, y:h}], p & 0x08); // D drawShape([{x:0, y:h/2+t/2+g}, {x:t, y:h/2+g}, {x:t, y:h-t-g}, {x:0, y:h-t*1.5-g}], p & 0x10); // E drawShape([{x:0, y:t*1.5+g}, {x:t, y:t+g}, {x:t, y:h/2-g}, {x:0, y:h/2-t/2-g}], p & 0x20); // F drawShape([{x:t+g, y:h/2}, {x:t*1.5+g, y:h/2-t/2}, {x:w-t*1.5-g, y:h/2-t/2}, {x:w-t-g, y:h/2}, {x:w-t*1.5-g, y:h/2+t/2}, {x:t*1.5+g, y:h/2+t/2}], p & 0x40); // G // ドット ctx.beginPath(); ctx.arc(w + t/2, h - t/2, t/2.5, 0, Math.PI * 2); ctx.fillStyle = showDot ? activeColor : inactiveColor; ctx.fill(); } }