nodeskini 1.0.6 → 1.0.9
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/blocklySkini/blocklySkini.html +5 -1
- package/blocklySkini/scripts/hiphop_blocks.js +5 -6
- package/client/controleurHH/controleurHH.html +4 -0
- package/client/queueViewer/queue.html +34 -0
- package/client/queueViewer/queue.js +187 -0
- package/client/queueViewer/style.css +26 -0
- package/client/score/parto1.js +11 -11
- package/client/score/parto1bundle.js +11 -11
- package/client/score/score.html +8 -7
- package/doc/Mode d'emploi Skini Node.pdf +0 -0
- package/myReact/orchestrationHH.hh.js +147 -1858
- package/myReact/orchestrationHH.mjs +50 -231
- package/myReact/orchestrationHH.mjs.map +1 -1
- package/package.json +1 -1
- package/pieces/tutos/tutoTestAll.hh.js +401 -0
- package/pieces/tutos/tutoTestAll.xml +18 -11
- package/serveur/OSCandMidi.mjs +27 -3
- package/serveur/controleDAW.mjs +2 -1
- package/serveur/groupeClientsSons.mjs +27 -3
- package/serveur/ipConfig.json +2 -2
- package/serveur/skiniParametres.js +56 -104
- package/serveur/utilsSkini.mjs +1 -1
- package/serveur/websocketServer.mjs +14 -4
- package/skini.mjs +4 -0
|
@@ -53,7 +53,11 @@
|
|
|
53
53
|
'height=400, width=600, top=200, left=300, toolbar=no, menubar=no, directories=no, location=no, resizable=yes, scrollbars=yes, status=no');
|
|
54
54
|
return false;">Parameters</button>
|
|
55
55
|
|
|
56
|
-
<button class="small button"
|
|
56
|
+
<button type="button" class="small button" onclick="window.open('http://' + window.location.hostname + ':' + window.location.port + '/queueViewer','Queue Viewer',
|
|
57
|
+
'height=600, width=1200, top=200, left=300, toolbar=no, menubar=no, directories=no, location=no, resizable=yes, scrollbars=yes, status=no');
|
|
58
|
+
return false;">Queue Viewer</button>
|
|
59
|
+
|
|
60
|
+
<button class="small button" id="launchSimulator"
|
|
57
61
|
onclick="launchSimulator()">Start Simulator</button>
|
|
58
62
|
<button id="stopSimulator" class="small button red" style="display:none"
|
|
59
63
|
onclick="stopSimulator();">Stop Simulator</button>
|
|
@@ -2797,12 +2797,11 @@ export function setServ(ser, daw, groupeCS, oscMidi, mix){
|
|
|
2797
2797
|
|
|
2798
2798
|
function setTempo(value, param){
|
|
2799
2799
|
tempoGlobal = value;
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
// }
|
|
2800
|
+
if(midimix.getAbletonLinkStatus()) {
|
|
2801
|
+
if(debug) console.log("ORCHESTRATION: set tempo Link:", value);
|
|
2802
|
+
midimix.setTempoLink(value);
|
|
2803
|
+
return;
|
|
2804
|
+
}
|
|
2806
2805
|
|
|
2807
2806
|
if ( value > tempoMax || value < tempoMin) {
|
|
2808
2807
|
console.log("ERR: Tempo set out of range:", value, "Should be between:", tempoMin, "and", tempoMax);
|
|
@@ -53,6 +53,10 @@
|
|
|
53
53
|
'height=400, width=600, top=200, left=300, toolbar=no, menubar=no, directories=no, location=no, resizable=yes, scrollbars=yes, status=no');
|
|
54
54
|
return false;">Parameters</button>
|
|
55
55
|
|
|
56
|
+
<button type="button" class="button" onclick="window.open('http://' + window.location.hostname + ':' + window.location.port + '/queueViewer','Queue Viewer',
|
|
57
|
+
'height=400, width=1200, top=200, left=300, toolbar=no, menubar=no, directories=no, location=no, resizable=yes, scrollbars=yes, status=no');
|
|
58
|
+
return false;">Queue Viewer</button>
|
|
59
|
+
|
|
56
60
|
<button class="button" id="launchSimulator" onclick="launchSimulator()">Start Simulator</button>
|
|
57
61
|
<button id="stopSimulator" class="small button red" style="display:none" onclick="stopSimulator();">Stop
|
|
58
62
|
Simulator</button>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="fr">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
6
|
+
<title>Files d'attente - Queue Viewer</title>
|
|
7
|
+
<link rel="stylesheet" href="/client/queueViewer/style.css" />
|
|
8
|
+
<meta name="robots" content="noindex" />
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<header>
|
|
12
|
+
<h1>Files d'attente (dynamique)</h1>
|
|
13
|
+
<p id="status">Connexion : en attente...</p>
|
|
14
|
+
<div class="controls">
|
|
15
|
+
<button id="pauseButton" type="button">Arrêt sur image</button>
|
|
16
|
+
<span id="pauseState">En direct</span>
|
|
17
|
+
</div>
|
|
18
|
+
<p id="tickInfo">Tick : 0</p>
|
|
19
|
+
</header>
|
|
20
|
+
|
|
21
|
+
<main>
|
|
22
|
+
<div id="queuesContainer">
|
|
23
|
+
<table id="queuesTable">
|
|
24
|
+
<thead>
|
|
25
|
+
<tr><th>File</th><th>Longueur</th><th>Contenu</th></tr>
|
|
26
|
+
</thead>
|
|
27
|
+
<tbody></tbody>
|
|
28
|
+
</table>
|
|
29
|
+
</div>
|
|
30
|
+
</main>
|
|
31
|
+
|
|
32
|
+
<script src="/client/queueViewer/queue.js"></script>
|
|
33
|
+
</body>
|
|
34
|
+
</html>
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
// Client minimal pour afficher dynamiquement les files d'attente
|
|
2
|
+
(async function(){
|
|
3
|
+
const statusEl = () => document.getElementById('status');
|
|
4
|
+
const tickInfoEl = () => document.getElementById('tickInfo');
|
|
5
|
+
const pauseStateEl = () => document.getElementById('pauseState');
|
|
6
|
+
const pauseButtonEl = () => document.getElementById('pauseButton');
|
|
7
|
+
let paused = false;
|
|
8
|
+
let queuedQueues = null;
|
|
9
|
+
|
|
10
|
+
// Récupère la config du serveur pour le port websocket
|
|
11
|
+
let ipConfig = { websocketServeurPort: 8383 };
|
|
12
|
+
try {
|
|
13
|
+
const r = await fetch('/serveur/ipConfig.json');
|
|
14
|
+
if (r.ok) ipConfig = await r.json();
|
|
15
|
+
} catch(e) {
|
|
16
|
+
console.warn('Impossible de charger /serveur/ipConfig.json, port par défaut utilisé');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const host = window.location.hostname || 'localhost';
|
|
20
|
+
const port = ipConfig.websocketServeurPort || 8383;
|
|
21
|
+
let ws;
|
|
22
|
+
|
|
23
|
+
// Ce visionneur est proche du controleur fonctionnellement
|
|
24
|
+
function connect(){
|
|
25
|
+
statusEl().textContent = `Connexion : ws://${host}:${port}`;
|
|
26
|
+
ws = new WebSocket(`ws://${host}:${port}`);
|
|
27
|
+
|
|
28
|
+
ws.onopen = function(){
|
|
29
|
+
statusEl().textContent = `Connecté à ${host}:${port}`;
|
|
30
|
+
const msg = { type: 'startSpectateur', text: 'queueViewer', id: Date.now() };
|
|
31
|
+
ws.send(JSON.stringify(msg));
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
ws.onclose = function(){
|
|
35
|
+
statusEl().textContent = 'Déconnecté, reconnexion dans 2s...';
|
|
36
|
+
setTimeout(connect, 2000);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
ws.onerror = function(e){
|
|
40
|
+
console.error('WebSocket error', e);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
ws.onmessage = function(event){
|
|
44
|
+
try {
|
|
45
|
+
const msg = JSON.parse(event.data);
|
|
46
|
+
if (msg.type === 'etatDeLaFileAttente') {
|
|
47
|
+
if (paused) {
|
|
48
|
+
queuedQueues = msg.value || [];
|
|
49
|
+
statusEl().textContent = `Pause activée - frame figée`;
|
|
50
|
+
} else {
|
|
51
|
+
renderQueues(msg.value || []);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else if (msg.type === 'setTickAutomate') {
|
|
55
|
+
tickInfoEl().textContent = `Tick : ${msg.tick}`;
|
|
56
|
+
}
|
|
57
|
+
} catch(e){
|
|
58
|
+
console.warn('Erreur parsing message', e);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function renderQueues(queues){
|
|
64
|
+
const tbody = document.querySelector('#queuesTable tbody');
|
|
65
|
+
tbody.innerHTML = '';
|
|
66
|
+
|
|
67
|
+
// First pass: compute durations for all clips and per-queue totals
|
|
68
|
+
const queuesInfo = [];
|
|
69
|
+
for (let i = 0; i < queues.length; i++){
|
|
70
|
+
const q = queues[i];
|
|
71
|
+
const index = q && q[0] !== undefined ? q[0] : i;
|
|
72
|
+
const content = (q && q[2]) ? q[2] : [];
|
|
73
|
+
const clips = content.map(it => {
|
|
74
|
+
if (it && typeof it === 'object') return it;
|
|
75
|
+
return { name: String(it) };
|
|
76
|
+
});
|
|
77
|
+
const durations = clips.map(c => {
|
|
78
|
+
if (Array.isArray(c) && c[2] && typeof c[2] === 'number') return c[2];
|
|
79
|
+
if (c.duration && typeof c.duration === 'number') return c.duration;
|
|
80
|
+
return 1;
|
|
81
|
+
});
|
|
82
|
+
const total = durations.reduce((s, v) => s + v, 0) || clips.length;
|
|
83
|
+
queuesInfo.push({ index, clips, durations, total });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Global timeline length = max of queue totals (so longest queue spans full timeline)
|
|
87
|
+
const globalMaxTotal = queuesInfo.reduce((m, q) => Math.max(m, q.total || 0), 0);
|
|
88
|
+
const displayTicks = globalMaxTotal || 0;
|
|
89
|
+
const effectiveMaxTotal = globalMaxTotal || 1;
|
|
90
|
+
//tickInfoEl().textContent = `Tick : ${displayTicks}`;
|
|
91
|
+
|
|
92
|
+
// Fixed width for all timelines (same scale across all files)
|
|
93
|
+
const FIXED_TIMELINE_WIDTH = 920;
|
|
94
|
+
|
|
95
|
+
// Build map of queues by index so missing indices can be rendered empty
|
|
96
|
+
const queueMap = new Map();
|
|
97
|
+
let maxIndex = -1;
|
|
98
|
+
queuesInfo.forEach(info => {
|
|
99
|
+
queueMap.set(info.index, info);
|
|
100
|
+
if (info.index > maxIndex) maxIndex = info.index;
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Second pass: render rows using a fixed timeline width so proportions match across rows
|
|
104
|
+
for (let idx = 0; idx <= maxIndex; idx++){
|
|
105
|
+
const info = queueMap.get(idx) || { index: idx, clips: [], durations: [], total: 0 };
|
|
106
|
+
const tr = document.createElement('tr');
|
|
107
|
+
const tdIndex = document.createElement('td'); tdIndex.textContent = info.index;
|
|
108
|
+
const tdLength = document.createElement('td'); tdLength.textContent = info.clips.length;
|
|
109
|
+
const tdContent = document.createElement('td');
|
|
110
|
+
|
|
111
|
+
const timeline = document.createElement('div');
|
|
112
|
+
timeline.className = 'timeline';
|
|
113
|
+
timeline.style.width = FIXED_TIMELINE_WIDTH + 'px';
|
|
114
|
+
|
|
115
|
+
if (info.clips.length === 0) {
|
|
116
|
+
timeline.classList.add('timelineEmpty');
|
|
117
|
+
const emptyEl = document.createElement('div');
|
|
118
|
+
emptyEl.className = 'emptySlot';
|
|
119
|
+
emptyEl.textContent = 'vide';
|
|
120
|
+
timeline.appendChild(emptyEl);
|
|
121
|
+
} else {
|
|
122
|
+
for (let j = 0; j < info.clips.length; j++){
|
|
123
|
+
const c = info.clips[j];
|
|
124
|
+
const dur = info.durations[j] || 1;
|
|
125
|
+
const widthPx = Math.max(24, Math.round((dur / effectiveMaxTotal) * FIXED_TIMELINE_WIDTH));
|
|
126
|
+
const label = (Array.isArray(c) && c[1]) ? c[1] : (c.name || c.label || 'clip');
|
|
127
|
+
const clipEl = document.createElement('div');
|
|
128
|
+
clipEl.className = label === 'clip' ? 'clip clipPlaceholder' : 'clip';
|
|
129
|
+
clipEl.style.flex = 'none';
|
|
130
|
+
clipEl.style.width = widthPx + 'px';
|
|
131
|
+
clipEl.title = label;
|
|
132
|
+
if (label !== 'clip') {
|
|
133
|
+
// Use queue index (vertical type) for color instead of clip name
|
|
134
|
+
clipEl.style.backgroundColor = colorFromQueueIndex(info.index);
|
|
135
|
+
}
|
|
136
|
+
const span = document.createElement('span'); span.textContent = label;
|
|
137
|
+
clipEl.appendChild(span);
|
|
138
|
+
timeline.appendChild(clipEl);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
tdContent.appendChild(timeline);
|
|
143
|
+
tr.appendChild(tdIndex);
|
|
144
|
+
tr.appendChild(tdLength);
|
|
145
|
+
tr.appendChild(tdContent);
|
|
146
|
+
tbody.appendChild(tr);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Simple color hash from string
|
|
151
|
+
function colorFromString(s){
|
|
152
|
+
let h = 0;
|
|
153
|
+
for (let i = 0; i < s.length; i++) h = (h<<5) - h + s.charCodeAt(i);
|
|
154
|
+
h = Math.abs(h) % 360;
|
|
155
|
+
return `hsl(${h}, 65%, 45%)`;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Color from queue index (vertical type)
|
|
159
|
+
function colorFromQueueIndex(idx){
|
|
160
|
+
const hue = (idx * 45) % 360;
|
|
161
|
+
return `hsl(${hue}, 70%, 50%)`;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function initControls(){
|
|
165
|
+
const button = pauseButtonEl();
|
|
166
|
+
button.addEventListener('click', () => {
|
|
167
|
+
paused = !paused;
|
|
168
|
+
if (paused) {
|
|
169
|
+
pauseStateEl().textContent = 'Figé';
|
|
170
|
+
button.textContent = 'Reprendre';
|
|
171
|
+
statusEl().textContent = 'Arrêt sur image activé';
|
|
172
|
+
} else {
|
|
173
|
+
pauseStateEl().textContent = 'En direct';
|
|
174
|
+
button.textContent = 'Arrêt sur image';
|
|
175
|
+
statusEl().textContent = `Connecté à ${host}:${port}`;
|
|
176
|
+
if (queuedQueues !== null) {
|
|
177
|
+
renderQueues(queuedQueues);
|
|
178
|
+
queuedQueues = null;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
connect();
|
|
185
|
+
initControls();
|
|
186
|
+
|
|
187
|
+
})();
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
body{font-family: Arial, Helvetica, sans-serif; margin:16px; color:#222}
|
|
2
|
+
header h1{margin:0 0 6px 0}
|
|
3
|
+
#status{font-size:0.9rem; color:#666}
|
|
4
|
+
.controls{margin:8px 0; display:flex; gap:10px; align-items:center;}
|
|
5
|
+
#pauseButton{padding:6px 12px; border:1px solid #888; border-radius:4px; background:#f8f8f8; cursor:pointer;}
|
|
6
|
+
#pauseButton:hover{background:#eee}
|
|
7
|
+
#pauseState{font-size:0.9rem; color:#444}
|
|
8
|
+
#tickInfo{font-size:0.9rem; color:#444; margin:4px 0 0 0}
|
|
9
|
+
#queuesContainer{margin-top:12px; overflow-x:auto}
|
|
10
|
+
table{border-collapse:collapse; width:100%; max-width:100%}
|
|
11
|
+
th,td{border:1px solid #ddd; padding:8px; text-align:left}
|
|
12
|
+
th{background:#f3f3f3}
|
|
13
|
+
th:nth-child(2), td:nth-child(2){width:90px; white-space:nowrap}
|
|
14
|
+
body{background:#fff}
|
|
15
|
+
tbody tr:nth-child(odd){background:#fafafa}
|
|
16
|
+
tbody tr:nth-child(odd) td:last-child,
|
|
17
|
+
tbody tr:nth-child(even) td:last-child{background:#fff}
|
|
18
|
+
|
|
19
|
+
.timeline{display:flex; gap:6px; align-items:center; height:28px; background:transparent; border-radius:4px;}
|
|
20
|
+
.timeline.timelineEmpty{background:rgba(0,0,0,0.06); border:1px dashed rgba(0,0,0,0.15);}
|
|
21
|
+
.emptySlot{flex:1; min-height:24px; display:flex; align-items:center; justify-content:center; color:#666; font-size:12px; font-style:italic;}
|
|
22
|
+
.clip{height:24px; border-radius:3px; box-shadow:0 1px 0 rgba(0,0,0,0.15) inset; overflow:hidden; display:inline-flex; align-items:center; justify-content:center; color:rgba(255,255,255,0.95); font-size:12px; padding:0 8px; white-space:nowrap; text-overflow:ellipsis}
|
|
23
|
+
.clipPlaceholder{background:rgba(255,255,255,0.15); color:rgba(0,0,0,0.6); border:1px dashed rgba(0,0,0,0.12);}
|
|
24
|
+
.clip span{display:inline-block; overflow:hidden; text-overflow:ellipsis}
|
|
25
|
+
.clip:hover{transform:translateY(-2px); box-shadow:0 4px 8px rgba(0,0,0,0.15)}
|
|
26
|
+
|
package/client/score/parto1.js
CHANGED
|
@@ -77,7 +77,7 @@ var textSize = 20 * screenY / Ybase;
|
|
|
77
77
|
|
|
78
78
|
// La version processing.min.js ne sais pas gérer les couleur en hexa.
|
|
79
79
|
function hex_to_RGB(hex) {
|
|
80
|
-
console.log("hex_to_RGB:", typeof hex, hex);
|
|
80
|
+
if (debug) console.log("hex_to_RGB:", typeof hex, hex);
|
|
81
81
|
if(hex == '') return [0,0,0];
|
|
82
82
|
|
|
83
83
|
let m = hex.match(/^#?([\da-f]{2})([\da-f]{2})([\da-f]{2})$/i);
|
|
@@ -608,6 +608,8 @@ function isInOngoingGraphicScene(scene){
|
|
|
608
608
|
}
|
|
609
609
|
|
|
610
610
|
function addSceneScore(scene){
|
|
611
|
+
if(debug1) console.log("addSceneScore:", scene, ongoingGraphicScene);
|
|
612
|
+
|
|
611
613
|
// Déjà là
|
|
612
614
|
for (var i=0; i < ongoingGraphicScene.length; i++){
|
|
613
615
|
if ( ongoingGraphicScene[i] === scene){
|
|
@@ -626,17 +628,15 @@ function addSceneScore(scene){
|
|
|
626
628
|
}
|
|
627
629
|
|
|
628
630
|
function removeSceneScore(scene){
|
|
629
|
-
if(
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
ongoingGraphicScene[i] = -1;
|
|
636
|
-
return true;
|
|
637
|
-
}
|
|
631
|
+
if(debug1) console.log("removeSceneScore:", scene, ongoingGraphicScene);
|
|
632
|
+
|
|
633
|
+
for (var i = ongoingGraphicScene.length - 1; i >= 0; i--){
|
|
634
|
+
if ( ongoingGraphicScene[i] === scene){
|
|
635
|
+
ongoingGraphicScene.splice(i, 1);
|
|
636
|
+
return true;
|
|
638
637
|
}
|
|
639
638
|
}
|
|
639
|
+
return false;
|
|
640
640
|
}
|
|
641
641
|
|
|
642
642
|
/**************************
|
|
@@ -716,7 +716,7 @@ function sketchProc(processing) {
|
|
|
716
716
|
groupsCounter++;
|
|
717
717
|
}else if(patternGroups[i][2] == "tank"){
|
|
718
718
|
if (debug) console.log("This one is the tank:", patternGroups[i][0]);
|
|
719
|
-
if (
|
|
719
|
+
if (groupsCounter > 0){
|
|
720
720
|
// C'est ici que l'on gére les tanks de façon séquentielle
|
|
721
721
|
// On regarde si le prédécesseur est dans le même tank.
|
|
722
722
|
// Cela pose une contrainte sur le fichier de configuration graphique.
|
|
@@ -78,7 +78,7 @@ var textSize = 20 * screenY / Ybase;
|
|
|
78
78
|
|
|
79
79
|
// La version processing.min.js ne sais pas gérer les couleur en hexa.
|
|
80
80
|
function hex_to_RGB(hex) {
|
|
81
|
-
console.log("hex_to_RGB:", typeof hex, hex);
|
|
81
|
+
if (debug) console.log("hex_to_RGB:", typeof hex, hex);
|
|
82
82
|
if(hex == '') return [0,0,0];
|
|
83
83
|
|
|
84
84
|
let m = hex.match(/^#?([\da-f]{2})([\da-f]{2})([\da-f]{2})$/i);
|
|
@@ -609,6 +609,8 @@ function isInOngoingGraphicScene(scene){
|
|
|
609
609
|
}
|
|
610
610
|
|
|
611
611
|
function addSceneScore(scene){
|
|
612
|
+
if(debug1) console.log("addSceneScore:", scene, ongoingGraphicScene);
|
|
613
|
+
|
|
612
614
|
// Déjà là
|
|
613
615
|
for (var i=0; i < ongoingGraphicScene.length; i++){
|
|
614
616
|
if ( ongoingGraphicScene[i] === scene){
|
|
@@ -627,17 +629,15 @@ function addSceneScore(scene){
|
|
|
627
629
|
}
|
|
628
630
|
|
|
629
631
|
function removeSceneScore(scene){
|
|
630
|
-
if(
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
ongoingGraphicScene[i] = -1;
|
|
637
|
-
return true;
|
|
638
|
-
}
|
|
632
|
+
if(debug1) console.log("removeSceneScore:", scene, ongoingGraphicScene);
|
|
633
|
+
|
|
634
|
+
for (var i = ongoingGraphicScene.length - 1; i >= 0; i--){
|
|
635
|
+
if ( ongoingGraphicScene[i] === scene){
|
|
636
|
+
ongoingGraphicScene.splice(i, 1);
|
|
637
|
+
return true;
|
|
639
638
|
}
|
|
640
639
|
}
|
|
640
|
+
return false;
|
|
641
641
|
}
|
|
642
642
|
|
|
643
643
|
/**************************
|
|
@@ -717,7 +717,7 @@ function sketchProc(processing) {
|
|
|
717
717
|
groupsCounter++;
|
|
718
718
|
}else if(patternGroups[i][2] == "tank"){
|
|
719
719
|
if (debug) console.log("This one is the tank:", patternGroups[i][0]);
|
|
720
|
-
if (
|
|
720
|
+
if (groupsCounter > 0){
|
|
721
721
|
// C'est ici que l'on gére les tanks de façon séquentielle
|
|
722
722
|
// On regarde si le prédécesseur est dans le même tank.
|
|
723
723
|
// Cela pose une contrainte sur le fichier de configuration graphique.
|
package/client/score/score.html
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
+
<!doctype html>
|
|
1
2
|
<html>
|
|
2
3
|
<head>
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title>Score</title>
|
|
6
|
+
<script src="/client/score/processing.min.js"></script>
|
|
7
|
+
<script src="/client/score/parto1bundle.js"></script>
|
|
8
|
+
</head>
|
|
9
|
+
<body onload="initWSSocket(window.location.hostname);">
|
|
8
10
|
<h1>Score</h1>
|
|
9
11
|
<input id="buttonUpdate" class="button" type="button" value="Update" onclick="getPatternGroups();">
|
|
10
|
-
|
|
11
12
|
<p><canvas id="canvas1" width="200" height="200"></canvas></p>
|
|
12
|
-
|
|
13
|
+
</body>
|
|
13
14
|
</html>
|
|
14
15
|
|
|
15
16
|
|
|
Binary file
|