@saluzi/saluzi-edu 0.2.34 → 0.2.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +42 -42
- package/dist/guide/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/dist/guide/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/dist/guide/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/dist/guide/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/dist/guide/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/dist/guide/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/dist/guide/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/dist/guide/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/dist/guide/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/dist/guide/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/dist/guide/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/dist/guide/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/dist/guide/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/dist/guide/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/dist/guide/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/dist/guide/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/dist/guide/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/dist/guide/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/dist/guide/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/dist/guide/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/dist/guide/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/dist/guide/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/dist/guide/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/dist/guide/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/dist/guide/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/dist/guide/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/dist/guide/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/dist/guide/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/dist/guide/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/dist/guide/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/dist/guide/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/dist/guide/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/dist/guide/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/dist/guide/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/dist/guide/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/dist/guide/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/dist/guide/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/dist/guide/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/dist/guide/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/dist/guide/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/dist/guide/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/dist/guide/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/dist/guide/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/dist/guide/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/dist/guide/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/dist/guide/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/dist/guide/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/dist/guide/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/dist/guide/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/dist/guide/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/dist/guide/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/dist/guide/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/dist/guide/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/dist/guide/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/dist/guide/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/dist/guide/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/dist/guide/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/dist/guide/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/dist/guide/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/dist/guide/assets/arc-BHMVz_y5.js +1 -0
- package/dist/guide/assets/architecture-7EHR7CIX-CbSBUcb5.js +1 -0
- package/dist/guide/assets/architectureDiagram-3BPJPVTR-wcJB5ouf.js +36 -0
- package/dist/guide/assets/array-BrnE8AWd.js +1 -0
- package/dist/guide/assets/blockDiagram-GPEHLZMM-CkYrVwzx.js +132 -0
- package/dist/guide/assets/c4Diagram-AAUBKEIU-DiD9rsNe.js +10 -0
- package/dist/guide/assets/channel-Ci3DSJxv.js +1 -0
- package/dist/guide/assets/chunk-2J33WTMH-BtCG5Mgz.js +1 -0
- package/dist/guide/assets/chunk-3OPIFGDE-ByO7Sl21.js +62 -0
- package/dist/guide/assets/chunk-4BX2VUAB-BSS9lLPG.js +1 -0
- package/dist/guide/assets/chunk-55IACEB6-CeGwUs-Y.js +1 -0
- package/dist/guide/assets/chunk-5ZQYHXKU-lfQPlpWw.js +2 -0
- package/dist/guide/assets/chunk-727SXJPM-Dk7csXo-.js +206 -0
- package/dist/guide/assets/chunk-AQP2D5EJ-DxgPzCop.js +231 -0
- package/dist/guide/assets/chunk-BSJP7CBP-DkaucuU0.js +1 -0
- package/dist/guide/assets/chunk-CSCIHK7Q-CqC2wNLF.js +125 -0
- package/dist/guide/assets/chunk-FMBD7UC4-CJdpjMF6.js +15 -0
- package/dist/guide/assets/chunk-KSCS5N6A-BzmG2SKB.js +10 -0
- package/dist/guide/assets/chunk-L5ZTLDWV-DLULHpQl.js +1 -0
- package/dist/guide/assets/chunk-LZXEDZCA-DeAieGL_.js +2 -0
- package/dist/guide/assets/chunk-ND2GUHAM-CYoheonW.js +1 -0
- package/dist/guide/assets/chunk-NNHCCRGN-CZB-V-Gv.js +159 -0
- package/dist/guide/assets/chunk-NZK2D7GU-tj0TiDjG.js +1 -0
- package/dist/guide/assets/chunk-O5CBEL6O-XqfyC6rf.js +11 -0
- package/dist/guide/assets/chunk-QZHKN3VN-B4pSqT8x.js +1 -0
- package/dist/guide/assets/chunk-WU5MYG2G-BTp4jVLR.js +1 -0
- package/dist/guide/assets/chunk-XPW4576I-BNAjqPW9.js +32 -0
- package/dist/guide/assets/classDiagram-4FO5ZUOK-DvnG1hC8.js +1 -0
- package/dist/guide/assets/classDiagram-v2-Q7XG4LA2-CDSfRrXS.js +1 -0
- package/dist/guide/assets/cose-bilkent-S5V4N54A-BGtpG2nc.js +1 -0
- package/dist/guide/assets/cytoscape.esm-Da9oojO7.js +321 -0
- package/dist/guide/assets/dagre-BM42HDAG-CsDPkQZd.js +4 -0
- package/dist/guide/assets/dagre-YawDugTX.js +1 -0
- package/dist/guide/assets/defaultLocale-CzQOUpbn.js +1 -0
- package/dist/guide/assets/diagram-2AECGRRQ-Bi0iesIB.js +43 -0
- package/dist/guide/assets/diagram-5GNKFQAL-B0mUsXMY.js +10 -0
- package/dist/guide/assets/diagram-KO2AKTUF-gJ2w08DO.js +3 -0
- package/dist/guide/assets/diagram-LMA3HP47-Bfz-mntY.js +24 -0
- package/dist/guide/assets/diagram-OG6HWLK6-c0LfJUmp.js +24 -0
- package/dist/guide/assets/dist-BkwaIA-w.js +1 -0
- package/dist/guide/assets/erDiagram-TEJ5UH35-tNIVvJVS.js +85 -0
- package/dist/guide/assets/eventmodeling-FCH6USID-Cf2rgrFX.js +1 -0
- package/dist/guide/assets/flowDiagram-I6XJVG4X-DZ7ZJ9gs.js +162 -0
- package/dist/guide/assets/ganttDiagram-6RSMTGT7-7fvvO2ap.js +292 -0
- package/dist/guide/assets/gitGraph-WXDBUCRP-zBiwTp6u.js +1 -0
- package/dist/guide/assets/gitGraphDiagram-PVQCEYII-BDpfxO9f.js +106 -0
- package/dist/guide/assets/graphlib-D2mVfvC0.js +1 -0
- package/dist/guide/assets/info-J43DQDTF-BxLwAY8v.js +1 -0
- package/dist/guide/assets/infoDiagram-5YYISTIA-Db_bmyIO.js +2 -0
- package/dist/guide/assets/init-BIStumxp.js +1 -0
- package/dist/guide/assets/ishikawaDiagram-YF4QCWOH-BwCoYf2Y.js +70 -0
- package/dist/guide/assets/journeyDiagram-JHISSGLW-Bou7oOC_.js +139 -0
- package/dist/guide/assets/kanban-definition-UN3LZRKU-lAKeBcZd.js +89 -0
- package/dist/guide/assets/katex-DEcVZfaU.css +1 -0
- package/dist/guide/assets/line-D9OadBQf.js +1 -0
- package/dist/guide/assets/linear-Dby1tqT1.js +1 -0
- package/dist/guide/assets/main-ByIvcCOw.css +1 -0
- package/dist/guide/assets/main-KHtjEkbM.js +166 -0
- package/dist/guide/assets/mermaid-parser.core-Bqq5x6kF.js +4 -0
- package/dist/guide/assets/mermaid.core-BS0Z4ePg.js +9 -0
- package/dist/guide/assets/mindmap-definition-RKZ34NQL-DKTUw-mh.js +96 -0
- package/dist/guide/assets/ordinal-D5SYTrjO.js +1 -0
- package/dist/guide/assets/packet-YPE3B663-CEHi_Cah.js +1 -0
- package/dist/guide/assets/path-CzCUKGLF.js +1 -0
- package/dist/guide/assets/pie-LRSECV5Y-CA6TRlP8.js +1 -0
- package/dist/guide/assets/pieDiagram-4H26LBE5-C4BywgU2.js +30 -0
- package/dist/guide/assets/quadrantDiagram-W4KKPZXB-xXGhs_Tm.js +7 -0
- package/dist/guide/assets/radar-GUYGQ44K-pPRQHVkl.js +1 -0
- package/dist/guide/assets/requirementDiagram-4Y6WPE33-B6FgrKWS.js +84 -0
- package/dist/guide/assets/rolldown-runtime-S-ySWqyJ.js +1 -0
- package/dist/guide/assets/rough.esm-l7pwdmc9.js +1 -0
- package/dist/guide/assets/sankeyDiagram-5OEKKPKP-BF9GbLlk.js +40 -0
- package/dist/guide/assets/sequenceDiagram-3UESZ5HK-C0Fx8lZi.js +162 -0
- package/dist/guide/assets/shiki-CMaUdEs0.js +152 -0
- package/dist/guide/assets/src-f-bswMtJ.js +1 -0
- package/dist/guide/assets/stateDiagram-AJRCARHV-DTwo-pNm.js +1 -0
- package/dist/guide/assets/stateDiagram-v2-BHNVJYJU-D7jALaef.js +1 -0
- package/dist/guide/assets/streamdown-nMT_aKRc.js +373 -0
- package/dist/guide/assets/timeline-definition-PNZ67QCA-C5CSLNZx.js +120 -0
- package/dist/guide/assets/treeView-BLDUP644-Dw8zVUOA.js +1 -0
- package/dist/guide/assets/treemap-LRROVOQU-DZnNSrx4.js +1 -0
- package/dist/guide/assets/vendor-BU1MXatO.js +9 -0
- package/dist/guide/assets/vennDiagram-CIIHVFJN-DyvIDEhj.js +34 -0
- package/dist/guide/assets/wardley-L42UT6IY-DghZA76R.js +1 -0
- package/dist/guide/assets/wardleyDiagram-YWT4CUSO-CtwyUs6q.js +78 -0
- package/dist/guide/assets/xychartDiagram-2RQKCTM6-TQgHZmKB.js +7 -0
- package/dist/guide/guide-data.json +3237 -0
- package/dist/guide/index.html +24 -0
- package/dist/parade/web/cube.js +20 -290
- package/dist/parade/web/index.html +41 -6
- package/package.json +1 -1
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-CN" class="light">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Saluzi Guide · 使用指南</title>
|
|
7
|
+
<meta name="description" content="Saluzi CLI 使用指南 — 新手入门、命令字典、环境变量、Saluzi 特色" />
|
|
8
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
9
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
10
|
+
<link
|
|
11
|
+
href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap"
|
|
12
|
+
rel="stylesheet"
|
|
13
|
+
/>
|
|
14
|
+
<script type="module" crossorigin src="/assets/main-KHtjEkbM.js"></script>
|
|
15
|
+
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-S-ySWqyJ.js">
|
|
16
|
+
<link rel="modulepreload" crossorigin href="/assets/shiki-CMaUdEs0.js">
|
|
17
|
+
<link rel="modulepreload" crossorigin href="/assets/streamdown-nMT_aKRc.js">
|
|
18
|
+
<link rel="modulepreload" crossorigin href="/assets/vendor-BU1MXatO.js">
|
|
19
|
+
<link rel="stylesheet" crossorigin href="/assets/main-ByIvcCOw.css">
|
|
20
|
+
</head>
|
|
21
|
+
<body>
|
|
22
|
+
<div id="root"></div>
|
|
23
|
+
</body>
|
|
24
|
+
</html>
|
package/dist/parade/web/cube.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Parade overlay cube renderer and session info bar controller.
|
|
3
3
|
*
|
|
4
4
|
* Responsibilities:
|
|
5
|
-
* 1. Render a purple 3D cube via
|
|
5
|
+
* 1. Render a purple 3D cube via CSS 3D transforms in the left stage area.
|
|
6
6
|
* 2. Animate the cube with gyroscope-style rotation when runningCount > 0.
|
|
7
7
|
* 3. Update the info bar (right side) with running/waiting counts and
|
|
8
8
|
* per-session prompt text from WebSocket pushes.
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
// Configuration
|
|
16
16
|
// ---------------------------------------------------------------------------
|
|
17
17
|
|
|
18
|
-
const PURPLE = [0.545, 0.361, 0.965] // #8B5CF6
|
|
19
18
|
const MAX_PROMPT_LENGTH = 30
|
|
20
19
|
const MAX_DISPLAYED_SESSIONS = 5
|
|
21
20
|
const WS_RECONNECT_MS = 2000
|
|
@@ -24,7 +23,7 @@ const WS_RECONNECT_MS = 2000
|
|
|
24
23
|
// DOM references
|
|
25
24
|
// ---------------------------------------------------------------------------
|
|
26
25
|
|
|
27
|
-
const
|
|
26
|
+
const cubeEl = document.getElementById('cube')
|
|
28
27
|
const runningCountEl = document.getElementById('running-count')
|
|
29
28
|
const waitingCountEl = document.getElementById('waiting-count')
|
|
30
29
|
const waitingPillEl = document.getElementById('waiting-pill')
|
|
@@ -267,6 +266,7 @@ function updateCounts() {
|
|
|
267
266
|
} else {
|
|
268
267
|
waitingPillEl.classList.add('zero')
|
|
269
268
|
}
|
|
269
|
+
updateCubeRotation()
|
|
270
270
|
}
|
|
271
271
|
|
|
272
272
|
function updateSessionRows() {
|
|
@@ -473,304 +473,34 @@ ctxMode.addEventListener('click', function () {
|
|
|
473
473
|
/* ignore */
|
|
474
474
|
}
|
|
475
475
|
updateModeLabel()
|
|
476
|
+
updateCubeRotation()
|
|
476
477
|
})
|
|
477
478
|
|
|
478
479
|
updateModeLabel()
|
|
479
480
|
|
|
480
481
|
// ---------------------------------------------------------------------------
|
|
481
|
-
//
|
|
482
|
+
// CSS 3D Cube rotation control
|
|
482
483
|
// ---------------------------------------------------------------------------
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
// actual display area — if the window's client height isn't exactly 160px
|
|
492
|
-
// (e.g. DPI scaling, title bar subtraction, WM overrides), the cube renders
|
|
493
|
-
// at the wrong aspect ratio and looks stretched/squished. This makes the
|
|
494
|
-
// cube correct at any window size, on any DPI/resolution/scaling setting.
|
|
495
|
-
function resizeCanvasToDisplaySize() {
|
|
496
|
-
var dpr = window.devicePixelRatio || 1
|
|
497
|
-
var rect = canvas.getBoundingClientRect()
|
|
498
|
-
var displayW = Math.max(1, Math.floor(rect.width * dpr))
|
|
499
|
-
var displayH = Math.max(1, Math.floor(rect.height * dpr))
|
|
500
|
-
if (canvas.width !== displayW || canvas.height !== displayH) {
|
|
501
|
-
canvas.width = displayW
|
|
502
|
-
canvas.height = displayH
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
window.addEventListener('resize', function () {
|
|
506
|
-
resizeCanvasToDisplaySize()
|
|
507
|
-
updateScrollbar()
|
|
508
|
-
})
|
|
509
|
-
resizeCanvasToDisplaySize()
|
|
510
|
-
|
|
511
|
-
if (gl) {
|
|
512
|
-
initCube()
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
function initCube() {
|
|
516
|
-
// -- Shaders --
|
|
517
|
-
var vsSource = [
|
|
518
|
-
'attribute vec3 aPos;',
|
|
519
|
-
'uniform mat4 uMVP;',
|
|
520
|
-
'void main() {',
|
|
521
|
-
' gl_Position = uMVP * vec4(aPos, 1.0);',
|
|
522
|
-
'}',
|
|
523
|
-
].join('\n')
|
|
524
|
-
|
|
525
|
-
var fsSource = [
|
|
526
|
-
'precision mediump float;',
|
|
527
|
-
'uniform vec3 uColor;',
|
|
528
|
-
'void main() {',
|
|
529
|
-
' gl_FragColor = vec4(uColor, 1.0);',
|
|
530
|
-
'}',
|
|
531
|
-
].join('\n')
|
|
532
|
-
|
|
533
|
-
var vs = compileShader(gl.VERTEX_SHADER, vsSource)
|
|
534
|
-
var fs = compileShader(gl.FRAGMENT_SHADER, fsSource)
|
|
535
|
-
if (!vs || !fs) return
|
|
536
|
-
|
|
537
|
-
cubeProgram = gl.createProgram()
|
|
538
|
-
gl.attachShader(cubeProgram, vs)
|
|
539
|
-
gl.attachShader(cubeProgram, fs)
|
|
540
|
-
gl.linkProgram(cubeProgram)
|
|
541
|
-
|
|
542
|
-
// -- Cube vertices (8 corners, unit cube centered at origin) --
|
|
543
|
-
var vertices = new Float32Array([
|
|
544
|
-
-0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5,
|
|
545
|
-
-0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5,
|
|
546
|
-
])
|
|
547
|
-
|
|
548
|
-
// -- Index buffer (12 triangles = 6 faces * 2 triangles) --
|
|
549
|
-
var indices = new Uint16Array([
|
|
550
|
-
// Front face
|
|
551
|
-
0, 1, 2, 0, 2, 3,
|
|
552
|
-
// Back face
|
|
553
|
-
5, 4, 7, 5, 7, 6,
|
|
554
|
-
// Top face
|
|
555
|
-
3, 2, 6, 3, 6, 7,
|
|
556
|
-
// Bottom face
|
|
557
|
-
4, 5, 1, 4, 1, 0,
|
|
558
|
-
// Right face
|
|
559
|
-
1, 5, 6, 1, 6, 2,
|
|
560
|
-
// Left face
|
|
561
|
-
4, 0, 3, 4, 3, 7,
|
|
562
|
-
])
|
|
563
|
-
|
|
564
|
-
cubeBuffer = gl.createBuffer()
|
|
565
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, cubeBuffer)
|
|
566
|
-
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)
|
|
567
|
-
|
|
568
|
-
cubeIndexBuffer = gl.createBuffer()
|
|
569
|
-
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeIndexBuffer)
|
|
570
|
-
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW)
|
|
571
|
-
|
|
572
|
-
// -- Initial render --
|
|
573
|
-
gl.enable(gl.DEPTH_TEST)
|
|
574
|
-
gl.clearColor(0.102, 0.102, 0.18, 1.0) // #1a1a2e
|
|
575
|
-
renderFrame()
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
function compileShader(type, source) {
|
|
579
|
-
var shader = gl.createShader(type)
|
|
580
|
-
gl.shaderSource(shader, source)
|
|
581
|
-
gl.compileShader(shader)
|
|
582
|
-
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
583
|
-
gl.deleteShader(shader)
|
|
584
|
-
return null
|
|
585
|
-
}
|
|
586
|
-
return shader
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
// ---------------------------------------------------------------------------
|
|
590
|
-
// Matrix math (minimal 4x4 operations for perspective + model-view)
|
|
591
|
-
// ---------------------------------------------------------------------------
|
|
592
|
-
|
|
593
|
-
function mat4Identity() {
|
|
594
|
-
var m = new Float32Array(16)
|
|
595
|
-
m[0] = 1
|
|
596
|
-
m[5] = 1
|
|
597
|
-
m[10] = 1
|
|
598
|
-
m[15] = 1
|
|
599
|
-
return m
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
function mat4Perspective(fovY, aspect, near, far) {
|
|
603
|
-
var f = 1.0 / Math.tan(fovY / 2)
|
|
604
|
-
var m = new Float32Array(16)
|
|
605
|
-
m[0] = f / aspect
|
|
606
|
-
m[5] = f
|
|
607
|
-
m[10] = (far + near) / (near - far)
|
|
608
|
-
m[11] = -1
|
|
609
|
-
m[14] = (2 * far * near) / (near - far)
|
|
610
|
-
return m
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
function mat4Translate(m, x, y, z) {
|
|
614
|
-
var r = new Float32Array(m)
|
|
615
|
-
r[12] = m[0] * x + m[4] * y + m[8] * z + m[12]
|
|
616
|
-
r[13] = m[1] * x + m[5] * y + m[9] * z + m[13]
|
|
617
|
-
r[14] = m[2] * x + m[6] * y + m[10] * z + m[14]
|
|
618
|
-
r[15] = m[3] * x + m[7] * y + m[11] * z + m[15]
|
|
619
|
-
return r
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
function mat4RotateX(m, a) {
|
|
623
|
-
var c = Math.cos(a),
|
|
624
|
-
s = Math.sin(a)
|
|
625
|
-
var r = new Float32Array(m)
|
|
626
|
-
var m4 = m[4],
|
|
627
|
-
m5 = m[5],
|
|
628
|
-
m6 = m[6],
|
|
629
|
-
m7 = m[7]
|
|
630
|
-
var m8 = m[8],
|
|
631
|
-
m9 = m[9],
|
|
632
|
-
m10 = m[10],
|
|
633
|
-
m11 = m[11]
|
|
634
|
-
r[4] = m4 * c + m8 * s
|
|
635
|
-
r[5] = m5 * c + m9 * s
|
|
636
|
-
r[6] = m6 * c + m10 * s
|
|
637
|
-
r[7] = m7 * c + m11 * s
|
|
638
|
-
r[8] = m8 * c - m4 * s
|
|
639
|
-
r[9] = m9 * c - m5 * s
|
|
640
|
-
r[10] = m10 * c - m6 * s
|
|
641
|
-
r[11] = m11 * c - m7 * s
|
|
642
|
-
return r
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
function mat4RotateY(m, a) {
|
|
646
|
-
var c = Math.cos(a),
|
|
647
|
-
s = Math.sin(a)
|
|
648
|
-
var r = new Float32Array(m)
|
|
649
|
-
var m0 = m[0],
|
|
650
|
-
m1 = m[1],
|
|
651
|
-
m2 = m[2],
|
|
652
|
-
m3 = m[3]
|
|
653
|
-
var m8 = m[8],
|
|
654
|
-
m9 = m[9],
|
|
655
|
-
m10 = m[10],
|
|
656
|
-
m11 = m[11]
|
|
657
|
-
r[0] = m0 * c - m8 * s
|
|
658
|
-
r[1] = m1 * c - m9 * s
|
|
659
|
-
r[2] = m2 * c - m10 * s
|
|
660
|
-
r[3] = m3 * c - m11 * s
|
|
661
|
-
r[8] = m0 * s + m8 * c
|
|
662
|
-
r[9] = m1 * s + m9 * c
|
|
663
|
-
r[10] = m2 * s + m10 * c
|
|
664
|
-
r[11] = m3 * s + m11 * c
|
|
665
|
-
return r
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
function mat4Scale(m, sx, sy, sz) {
|
|
669
|
-
var r = new Float32Array(m)
|
|
670
|
-
r[0] *= sx
|
|
671
|
-
r[1] *= sx
|
|
672
|
-
r[2] *= sx
|
|
673
|
-
r[3] *= sx
|
|
674
|
-
r[4] *= sy
|
|
675
|
-
r[5] *= sy
|
|
676
|
-
r[6] *= sy
|
|
677
|
-
r[7] *= sy
|
|
678
|
-
r[8] *= sz
|
|
679
|
-
r[9] *= sz
|
|
680
|
-
r[10] *= sz
|
|
681
|
-
r[11] *= sz
|
|
682
|
-
return r
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
// ---------------------------------------------------------------------------
|
|
686
|
-
// Render loop
|
|
687
|
-
// ---------------------------------------------------------------------------
|
|
688
|
-
|
|
689
|
-
var rotX = 0.4 // Initial tilt for better visual
|
|
690
|
-
var rotY = 0
|
|
691
|
-
|
|
692
|
-
function renderFrame() {
|
|
693
|
-
if (!gl || !cubeProgram) return
|
|
694
|
-
|
|
695
|
-
// Re-sync buffer to display size in case the window resized since last frame.
|
|
696
|
-
resizeCanvasToDisplaySize()
|
|
697
|
-
gl.viewport(0, 0, canvas.width, canvas.height)
|
|
698
|
-
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
|
|
699
|
-
|
|
700
|
-
gl.useProgram(cubeProgram)
|
|
701
|
-
|
|
702
|
-
// Projection: 45 degree FOV, canvas aspect ratio
|
|
703
|
-
var proj = mat4Perspective(
|
|
704
|
-
Math.PI / 4,
|
|
705
|
-
canvas.width / canvas.height,
|
|
706
|
-
0.1,
|
|
707
|
-
100,
|
|
708
|
-
)
|
|
709
|
-
|
|
710
|
-
// View: camera pulled back along Z
|
|
711
|
-
var view = mat4Translate(proj, 0, 0, -4)
|
|
712
|
-
|
|
713
|
-
// Model: rotate then scale
|
|
714
|
-
var model = mat4Identity()
|
|
715
|
-
model = mat4RotateX(model, rotX)
|
|
716
|
-
model = mat4RotateY(model, rotY)
|
|
717
|
-
model = mat4Scale(model, 1.2, 1.2, 1.2)
|
|
718
|
-
|
|
719
|
-
// MVP = projection * view * model (already combined above)
|
|
720
|
-
var mvp = view
|
|
721
|
-
// Multiply view * model
|
|
722
|
-
var mvpFinal = mat4Multiply(mvp, model)
|
|
723
|
-
|
|
724
|
-
// Set uniforms
|
|
725
|
-
var uMVP = gl.getUniformLocation(cubeProgram, 'uMVP')
|
|
726
|
-
var uColor = gl.getUniformLocation(cubeProgram, 'uColor')
|
|
727
|
-
gl.uniformMatrix4fv(uMVP, false, mvpFinal)
|
|
728
|
-
gl.uniform3fv(uColor, PURPLE)
|
|
729
|
-
|
|
730
|
-
// Bind vertex buffer
|
|
731
|
-
var aPos = gl.getAttribLocation(cubeProgram, 'aPos')
|
|
732
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, cubeBuffer)
|
|
733
|
-
gl.enableVertexAttribArray(aPos)
|
|
734
|
-
gl.vertexAttribPointer(aPos, 3, gl.FLOAT, false, 0, 0)
|
|
735
|
-
|
|
736
|
-
// Draw indexed triangles
|
|
737
|
-
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeIndexBuffer)
|
|
738
|
-
gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0)
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
function mat4Multiply(a, b) {
|
|
742
|
-
var r = new Float32Array(16)
|
|
743
|
-
var i, j
|
|
744
|
-
for (i = 0; i < 4; i++) {
|
|
745
|
-
for (j = 0; j < 4; j++) {
|
|
746
|
-
r[j * 4 + i] =
|
|
747
|
-
a[i] * b[j * 4] +
|
|
748
|
-
a[4 + i] * b[j * 4 + 1] +
|
|
749
|
-
a[8 + i] * b[j * 4 + 2] +
|
|
750
|
-
a[12 + i] * b[j * 4 + 3]
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
return r
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
/**
|
|
757
|
-
* Animation loop. Rotates the cube on X and Y axes (gyroscope-style)
|
|
758
|
-
* based on the current cube mode:
|
|
759
|
-
* Dynamic: rotate when runningCount > 0
|
|
760
|
-
* Static: rotate when runningCount === 0 (inverse)
|
|
761
|
-
*/
|
|
762
|
-
function animate() {
|
|
484
|
+
// The cube is a CSS 3D transform element (see index.html <style>). Rotation
|
|
485
|
+
// is driven by applying/removing the .rotating class, which toggles the
|
|
486
|
+
// cube-spin @keyframes animation. Logic mirrors the previous WebGL loop:
|
|
487
|
+
// Dynamic: rotate when runningCount > 0
|
|
488
|
+
// Static: rotate when runningCount === 0 (inverse)
|
|
489
|
+
|
|
490
|
+
function updateCubeRotation() {
|
|
491
|
+
if (!cubeEl) return
|
|
763
492
|
var shouldRotate =
|
|
764
493
|
cubeMode === 'dynamic' ? runningCount > 0 : runningCount === 0
|
|
765
494
|
if (shouldRotate) {
|
|
766
|
-
|
|
767
|
-
|
|
495
|
+
cubeEl.classList.add('rotating')
|
|
496
|
+
} else {
|
|
497
|
+
cubeEl.classList.remove('rotating')
|
|
768
498
|
}
|
|
769
|
-
renderFrame()
|
|
770
|
-
requestAnimationFrame(animate)
|
|
771
499
|
}
|
|
772
500
|
|
|
773
|
-
//
|
|
501
|
+
// Apply initial state — re-evaluated on each WS message via updateCounts
|
|
502
|
+
updateCubeRotation()
|
|
503
|
+
|
|
504
|
+
// Start the WebSocket connection
|
|
774
505
|
setWsStatus('connecting')
|
|
775
|
-
requestAnimationFrame(animate)
|
|
776
506
|
connectWebSocket()
|
|
@@ -34,8 +34,9 @@
|
|
|
34
34
|
|
|
35
35
|
/* ---- Left: cube stage ----
|
|
36
36
|
Use flex-basis instead of fixed px so the stage scales with the window.
|
|
37
|
-
The cube
|
|
38
|
-
|
|
37
|
+
The cube is a CSS 3D transform element — three faces (body + ::before
|
|
38
|
+
+ ::after) form a visible cube. Rotates when .rotating class is applied
|
|
39
|
+
(driven by runningCount + cubeMode in cube.js). */
|
|
39
40
|
#cube-stage {
|
|
40
41
|
flex: 0 0 43%; /* ~95px of 220px, but proportional so it scales */
|
|
41
42
|
height: 100%;
|
|
@@ -47,10 +48,44 @@
|
|
|
47
48
|
align-items: center;
|
|
48
49
|
justify-content: center;
|
|
49
50
|
border-right: 1px solid var(--border);
|
|
51
|
+
perspective: 200px;
|
|
50
52
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
/* CSS 3D cube: body is the front face, ::before is the right face,
|
|
54
|
+
::after is the top face. Half-size translates position them at 90°. */
|
|
55
|
+
.cube {
|
|
56
|
+
width: 22px;
|
|
57
|
+
height: 22px;
|
|
58
|
+
position: relative;
|
|
59
|
+
transform-style: preserve-3d;
|
|
60
|
+
transform: rotateX(-28deg) rotateY(45deg);
|
|
61
|
+
background: rgba(139, 92, 246, 0.45);
|
|
62
|
+
border: 1px solid #8B5CF6;
|
|
63
|
+
}
|
|
64
|
+
.cube.rotating {
|
|
65
|
+
animation: cube-spin 8s linear infinite;
|
|
66
|
+
}
|
|
67
|
+
.cube::before,
|
|
68
|
+
.cube::after {
|
|
69
|
+
content: '';
|
|
70
|
+
position: absolute;
|
|
71
|
+
inset: 0;
|
|
72
|
+
}
|
|
73
|
+
.cube::before {
|
|
74
|
+
transform: rotateY(90deg) translateZ(11px);
|
|
75
|
+
background: rgba(167, 139, 250, 0.55);
|
|
76
|
+
border: 1px solid #a78bfa;
|
|
77
|
+
}
|
|
78
|
+
.cube::after {
|
|
79
|
+
transform: rotateX(90deg) translateZ(11px);
|
|
80
|
+
background: rgba(109, 40, 217, 0.4);
|
|
81
|
+
border: 1px solid #6d28d9;
|
|
82
|
+
}
|
|
83
|
+
@keyframes cube-spin {
|
|
84
|
+
from { transform: rotateX(-28deg) rotateY(0deg); }
|
|
85
|
+
to { transform: rotateX(-28deg) rotateY(360deg); }
|
|
86
|
+
}
|
|
87
|
+
@media (prefers-reduced-motion: reduce) {
|
|
88
|
+
.cube.rotating { animation: none; }
|
|
54
89
|
}
|
|
55
90
|
/* Subtle ring frame around the cube */
|
|
56
91
|
#cube-stage::after {
|
|
@@ -355,7 +390,7 @@
|
|
|
355
390
|
</head>
|
|
356
391
|
<body>
|
|
357
392
|
<div id="cube-stage">
|
|
358
|
-
<
|
|
393
|
+
<div class="cube" id="cube"></div>
|
|
359
394
|
</div>
|
|
360
395
|
<div id="panel">
|
|
361
396
|
<div id="counts-row">
|