feat: TurboSu initial release - racing telemetry dashboard

This commit is contained in:
Yei.J. (AskaEth)
2026-07-25 15:23:40 +08:00
commit d61bb61a83
61 changed files with 5270 additions and 0 deletions
+13
View File
@@ -0,0 +1,13 @@
{
"id": "gear_indicator",
"name": "档位指示器",
"category": "basic",
"description": "醒目大圆档位显示,适合竖屏手机副屏",
"author": "Yei.J. (AskaEth)",
"version": "1.0.0",
"config": {
"icon": "⚙️",
"aspect_ratio": "1:1",
"render_mode": "contain"
}
}
+35
View File
@@ -0,0 +1,35 @@
<div style="display:flex;align-items:center;justify-content:center;height:100%;font-family:'Segoe UI',system-ui,sans-serif;background:linear-gradient(135deg,#0a0a14,#1a1a30);gap:20px;">
<div style="width:100px;height:100px;border-radius:50%;background:rgba(102,126,234,0.15);border:3px solid rgba(102,126,234,0.5);display:flex;align-items:center;justify-content:center;box-shadow:0 0 30px rgba(102,126,234,0.2);">
<span style="font-size:56px;font-weight:900;color:#fff;" data-bind="gear">N</span>
</div>
<div style="display:flex;flex-direction:column;gap:6px;">
<div style="display:flex;align-items:center;gap:8px;">
<span style="font-size:12px;color:rgba(255,255,255,0.5);width:24px;">R</span>
<div style="width:80px;height:6px;background:rgba(255,255,255,0.1);border-radius:3px;"></div>
</div>
<div style="display:flex;align-items:center;gap:8px;">
<span style="font-size:12px;color:rgba(255,255,255,0.5);width:24px;">1</span>
<div style="width:80px;height:6px;background:rgba(255,255,255,0.1);border-radius:3px;"></div>
</div>
<div style="display:flex;align-items:center;gap:8px;">
<span style="font-size:12px;color:rgba(255,255,255,0.5);width:24px;">2</span>
<div style="width:80px;height:6px;background:rgba(255,255,255,0.1);border-radius:3px;"></div>
</div>
<div style="display:flex;align-items:center;gap:8px;">
<span style="font-size:12px;color:rgba(255,255,255,0.5);width:24px;">3</span>
<div style="width:80px;height:6px;background:rgba(255,255,255,0.1);border-radius:3px;"></div>
</div>
<div style="display:flex;align-items:center;gap:8px;">
<span style="font-size:12px;color:rgba(255,255,255,0.5);width:24px;">4</span>
<div style="width:80px;height:6px;background:rgba(255,255,255,0.1);border-radius:3px;"></div>
</div>
<div style="display:flex;align-items:center;gap:8px;">
<span style="font-size:12px;color:rgba(255,255,255,0.5);width:24px;">5</span>
<div style="width:80px;height:6px;background:rgba(255,255,255,0.1);border-radius:3px;"></div>
</div>
<div style="display:flex;align-items:center;gap:8px;">
<span style="font-size:12px;color:rgba(255,255,255,0.5);width:24px;">6</span>
<div style="width:80px;height:6px;background:rgba(255,255,255,0.1);border-radius:3px;"></div>
</div>
</div>
</div>
+13
View File
@@ -0,0 +1,13 @@
{
"id": "lap_timer",
"name": "圈速计时器",
"category": "timing",
"description": "当前圈速、最佳圈和上圈时间对比显示",
"author": "Yei.J. (AskaEth)",
"version": "1.0.0",
"config": {
"icon": "⏱️",
"aspect_ratio": "4:3",
"render_mode": "contain"
}
}
+20
View File
@@ -0,0 +1,20 @@
<div style="display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;font-family:'Segoe UI',system-ui,sans-serif;background:linear-gradient(135deg,#0a0a14,#1a1a30);gap:16px;">
<div style="text-align:center;">
<div style="font-size:12px;color:rgba(255,255,255,0.4);letter-spacing:2px;margin-bottom:4px;">LAP</div>
<div style="font-size:14px;color:rgba(255,255,255,0.3);" data-bind="lap_number">0</div>
</div>
<div style="text-align:center;">
<div style="font-size:11px;color:rgba(255,255,255,0.4);letter-spacing:2px;margin-bottom:4px;">CURRENT</div>
<div style="font-size:48px;font-weight:900;color:#667eea;font-variant-numeric:tabular-nums;" data-bind="lap_time">00:00.000</div>
</div>
<div style="display:flex;gap:40px;">
<div style="text-align:center;">
<div style="font-size:11px;color:rgba(255,255,255,0.4);letter-spacing:1px;margin-bottom:4px;">LAST</div>
<div style="font-size:24px;font-weight:700;color:rgba(255,255,255,0.6);font-variant-numeric:tabular-nums;" data-bind="last_lap">00:00.000</div>
</div>
<div style="text-align:center;">
<div style="font-size:11px;color:rgba(255,255,255,0.4);letter-spacing:1px;margin-bottom:4px;">BEST</div>
<div style="font-size:24px;font-weight:700;color:#2ecc71;font-variant-numeric:tabular-nums;" data-bind="best_lap">00:00.000</div>
</div>
</div>
</div>
+15
View File
@@ -0,0 +1,15 @@
{
"id": "speedometer",
"name": "极速仪表 - 速度表",
"category": "speed",
"description": "大字号实时速度显示,支持km/h和mph,适合横屏全屏显示",
"author": "Yei.J. (AskaEth)",
"version": "1.0.0",
"config": {
"icon": "🏎️",
"unit": "kmh",
"show_unit": true,
"aspect_ratio": "auto",
"render_mode": "contain"
}
}
+7
View File
@@ -0,0 +1,7 @@
<div style="display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;font-family:'Segoe UI',system-ui,sans-serif;background:linear-gradient(135deg,#0a0a14 0%,#1a1a30 100%);">
<div style="font-size:120px;font-weight:900;line-height:1;color:#fff;text-shadow:0 0 40px rgba(102,126,234,0.5);" data-bind="speed_kmh">0</div>
<div style="font-size:24px;color:rgba(255,255,255,0.6);margin-top:8px;letter-spacing:4px;">KM/H</div>
<div style="margin-top:20px;width:300px;height:6px;background:rgba(255,255,255,0.1);border-radius:3px;overflow:hidden;">
<div data-bind-speed style="height:100%;background:linear-gradient(90deg,#667eea,#764ba2);border-radius:3px;transition:width 0.1s ease;width:calc(var(--speed,0) / 400 * 100%);"></div>
</div>
</div>
+15
View File
@@ -0,0 +1,15 @@
{
"id": "tachometer",
"name": "转速仪表 - 转速表",
"category": "rpm",
"description": "赛车风格弧形转速表,支持红区换档提示,推荐横屏",
"author": "Yei.J. (AskaEth)",
"version": "1.0.0",
"config": {
"icon": "⏱️",
"max_rpm": 8000,
"redline": 7000,
"aspect_ratio": "16:9",
"render_mode": "contain"
}
}
+35
View File
@@ -0,0 +1,35 @@
<div style="display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;font-family:'Segoe UI',system-ui,sans-serif;background:linear-gradient(135deg,#0a0a14,#1a1a30);">
<svg viewBox="0 0 300 200" width="90%" style="max-width:500px;">
<defs>
<linearGradient id="rpmGrad" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="#667eea"/>
<stop offset="40%" stop-color="#667eea"/>
<stop offset="70%" stop-color="#f39c12"/>
<stop offset="100%" stop-color="#e74c3c"/>
</linearGradient>
</defs>
<path d="M 50,170 A 100,100 0 0,1 250,170" fill="none" stroke="rgba(255,255,255,0.08)" stroke-width="18" stroke-linecap="round"/>
<path id="rpm-arc" d="M 50,170 A 100,100 0 0,1 250,170" fill="none" stroke="url(#rpmGrad)" stroke-width="18" stroke-linecap="round"
stroke-dasharray="314" stroke-dashoffset="314" style="transition:stroke-dashoffset 0.1s ease;"/>
<text x="150" y="150" text-anchor="middle" fill="#fff" font-size="48" font-weight="900" data-bind="rpm">0</text>
<text x="150" y="180" text-anchor="middle" fill="rgba(255,255,255,0.5)" font-size="14">RPM</text>
<text x="42" y="185" text-anchor="middle" fill="rgba(255,255,255,0.3)" font-size="10">0</text>
<text x="258" y="185" text-anchor="middle" fill="rgba(255,255,255,0.3)" font-size="10">8k</text>
</svg>
<div data-bind-rpm style="display:none;">
<script>
(function() {
const arc = document.getElementById('rpm-arc');
const observer = new MutationObserver(() => {
const rpm = parseFloat(getComputedStyle(document.querySelector('[data-bind-rpm]')).getPropertyValue('--rpm')) || 0;
const max = parseFloat(getComputedStyle(document.querySelector('[data-bind-rpm]')).getPropertyValue('--rpm-max')) || 8000;
if (!isNaN(rpm) && arc) {
const pct = Math.min(rpm / max, 1);
arc.setAttribute('stroke-dashoffset', 314 - (314 * pct));
}
});
observer.observe(document.querySelector('[data-bind-rpm]'), { attributes: true, attributeFilter: ['style'] });
})();
</script>
</div>
</div>