+
-
+
+
@@ -185,7 +170,7 @@
Feedback
-
+
diff --git a/script.js b/script.js
index 56eb20d..8a7abdf 100644
--- a/script.js
+++ b/script.js
@@ -37,13 +37,12 @@ window.onload = () => {
const dials = [];
const frameSlider = document.getElementById('frameSlider');
const frameDisplay = document.getElementById('frameDisplay');
- const canvas = document.getElementById('timelineCanvas');
- const ctx = canvas.getContext('2d');
- const totalFrames = 500;
+
+
const curveCanvas = document.getElementById('curveCanvas');
- const curveEditor = new CurveEditor(curveCanvas, 10);
+ const curveEditor = new CurveEditor(curveCanvas, 10, frameSlider);
// Animation File List
@@ -74,8 +73,10 @@ window.onload = () => {
for (let i = 0; i < 5; i++) {
let motor = new ServoMotor(0, 10 + i, "SCS009")
robot.assignMotor(positions[i], motor);
- }
+ addDial(motor.ID);
+ }
+ // addDial(123);
// Retrieve motor by position
//console.log(robot.getMotor('eyelids'));
@@ -176,78 +177,80 @@ window.onload = () => {
frameSlider.oninput = () => {
currentFrame = parseInt(frameSlider.value);
frameDisplay.textContent = currentFrame;
- isInterpolating = true;
-
- for (let ch = 0; ch < 5; ch++) {
- const keyframes = dialKeyframes[ch];
- let prevFrame = null, nextFrame = null;
-
- for (let f = currentFrame; f >= 0; f--) {
- if (keyframes[f] !== undefined) {
- prevFrame = f;
- break;
- }
- }
- for (let f = currentFrame; f <= totalFrames; f++) {
- if (keyframes[f] !== undefined) {
- nextFrame = f;
- break;
- }
- }
-
- let value;
- if (prevFrame !== null && nextFrame !== null && prevFrame !== nextFrame) {
- const prevVal = keyframes[prevFrame];
- const nextVal = keyframes[nextFrame];
- const t = (currentFrame - prevFrame) / (nextFrame - prevFrame);
- value = Math.round(prevVal + (nextVal - prevVal) * t);
- } else if (prevFrame !== null) {
- value = keyframes[prevFrame];
- } else if (nextFrame !== null) {
- value = keyframes[nextFrame];
- } else {
- value = 512;
- }
-
- dials[ch].value = value;
- document.getElementById(`value${ch}`).textContent = value;
- }
-
- drawTimelineMarkers();
- isInterpolating = false;
-
+ //console.log(currentFrame);
+ syncDialsWithCurveEditor();
syncMotorsWithTimeline();
};
- for (let i = 0; i < 5; i++) {
- dials[i] = new Nexus.Dial(`#dial${i}`, {
+ function addDial(motorID) {
+ const index = dials.length;
+
+ // Create dial wrapper
+ const dialWrapper = document.createElement('div');
+ dialWrapper.className = 'dial';
+ dialWrapper.dataset.index = index;
+
+ // Create label
+ const label = document.createElement('label');
+ label.textContent = "Motor " + motorID;
+ console.log(motorID);
+
+ // Create dial container
+ const dialDiv = document.createElement('div');
+ dialDiv.id = `dial${index}`;
+
+ // Create value display
+ const valueSpan = document.createElement('span');
+ valueSpan.id = `value${index}`;
+ valueSpan.textContent = '2048';
+
+ // Assemble and append
+ dialWrapper.appendChild(label);
+ dialWrapper.appendChild(dialDiv);
+ dialWrapper.appendChild(valueSpan);
+ document.getElementById('dialArea').appendChild(dialWrapper);
+
+ // Create Nexus dial
+ const dial = new Nexus.Dial(`#dial${index}`, {
size: [80, 80],
min: 0,
- max: 1023,
- value: 512
+ max: 4095,
+ value: 4095 / 2
});
- dials[i].colorize("accent", dialColors[i]);
+ dial.motorID = motorID;
+ dial.colorize("accent", dialColors[index]);
- dials[i].on('change', (v) => {
+ dial.on('change', (v) => {
if (isInterpolating) return;
const val = Math.round(v);
- document.getElementById(`value${i}`).textContent = val;
- dialKeyframes[i][currentFrame] = val;
- drawTimelineMarkers();
-
+ document.getElementById(`value${index}`).textContent = val;
+ //dialKeyframes[index][currentFrame] = val;
syncMotorsWithTimeline();
-
});
-
+ dials.push(dial);
}
+ function syncDialsWithCurveEditor() {
+ //let pos = curveEditor.getMotorPositionAtTime(11, currentFrame);
+ for (let ch = 0; ch < dials.length; ch++) {
+ console.log(dials[ch].motorID);
+ dials[ch].value = curveEditor.getMotorPositionAtTime(dials[ch].motorID, currentFrame);
+ //const value = dials[ch].value;
+ //motorPayloads.push({ motorId: ch, position: value });
+ }
+ //console.log(pos);
+ }
+
+
+
function syncMotorsWithTimeline() {
+
const now = Date.now();
if (syncCheckbox.checked && now - lastSyncTime >= syncIntervalMs) {
lastSyncTime = now;
@@ -281,7 +284,6 @@ window.onload = () => {
document.querySelectorAll('.dial').forEach(d => d.classList.remove('selected'));
el.classList.add('selected');
- drawTimelineMarkers();
};
});
@@ -517,7 +519,7 @@ window.onload = () => {
document.getElementById("filenameInput").value = selectedFile.replace(/\.anim$/i, "");
- drawTimelineMarkers();
+
}
@@ -660,7 +662,6 @@ window.onload = () => {
clearBtn.addEventListener('click', () => {
currentFrame = 0;
dialKeyframes = Array.from({ length: 5 }, () => ({}));
- drawTimelineMarkers();
});
@@ -671,73 +672,6 @@ window.onload = () => {
document.getElementById('input').value = '';
};
- function drawTimelineMarkers() {
- ctx.clearRect(0, 0, canvas.width, canvas.height);
- const width = canvas.width;
- const height = canvas.height;
-
- // Draw tick marks every 50 frames
- ctx.strokeStyle = '#aaa';
- ctx.lineWidth = 1;
- for (let f = 0; f <= totalFrames; f += 25) {
- const x = (f / totalFrames) * width;
- ctx.beginPath();
- ctx.moveTo(x, height * 0.75); // small tick at bottom
- ctx.lineTo(x, height);
- ctx.stroke();
- }
- for (let f = 0; f <= totalFrames; f += 50) {
- const x = (f / totalFrames) * width;
- ctx.beginPath();
- ctx.moveTo(x, height * 0.65); // small tick at bottom
- ctx.lineTo(x, height);
- ctx.stroke();
- }
-
- // Draw label on tick marks
- ctx.fillStyle = '#666';
- ctx.font = '10px sans-serif';
- ctx.textAlign = 'center';
-
- for (let f = 0; f <= totalFrames; f += 50) {
- const x = (f / totalFrames) * width;
- const seconds = f / 50;
- ctx.fillText(seconds.toString() + "s", x, height - 12);
- }
-
-
- if (selectedDial !== null) {
- for (let frame in dialKeyframes[selectedDial]) {
- const x = (frame / totalFrames) * width;
- ctx.beginPath();
- ctx.moveTo(x, 0);
- ctx.lineTo(x, height);
- ctx.strokeStyle = dialColors[selectedDial];
- ctx.lineWidth = 2;
- ctx.stroke();
- }
- } else {
- for (let ch = 0; ch < 5; ch++) {
- for (let frame in dialKeyframes[ch]) {
- const x = (frame / totalFrames) * width;
- ctx.beginPath();
- ctx.moveTo(x, 0);
- ctx.lineTo(x, height);
- ctx.strokeStyle = dialColors[ch];
- ctx.lineWidth = 1;
- ctx.stroke();
- }
- }
- }
-
- const currentX = (currentFrame / totalFrames) * width;
- ctx.beginPath();
- ctx.moveTo(currentX, 0);
- ctx.lineTo(currentX, height);
- ctx.strokeStyle = 'black';
- ctx.lineWidth = 2;
- ctx.stroke();
- }
document.addEventListener('click', (e) => {
const ignoredTags = ['BUTTON', 'INPUT', 'TEXTAREA', 'CANVAS'];
@@ -747,66 +681,11 @@ window.onload = () => {
if (!clickedInsideDial && !clickedControl && selectedDial !== null) {
selectedDial = null;
document.querySelectorAll('.dial').forEach(el => el.classList.remove('selected'));
- drawTimelineMarkers();
+
}
});
- canvas.addEventListener('mousedown', (e) => {
- const x = e.offsetX;
- const dialIndices = selectedDial !== null ? [selectedDial] : [0, 1, 2, 3, 4];
-
- for (let ch of dialIndices) {
- for (let f in dialKeyframes[ch]) {
- const frameNum = parseInt(f);
- const fx = (frameNum / totalFrames) * canvas.width;
-
- if (Math.abs(fx - x) < 15) {
- draggingKeyframe = { dialIndex: ch, originalFrame: frameNum };
- isDragging = true;
- return;
- }
- }
- }
- });
-
-
- canvas.addEventListener('mousemove', (e) => {
- if (!isDragging || !draggingKeyframe) return;
-
- const x = e.offsetX;
- const newFrame = Math.max(0, Math.min(totalFrames - 1, Math.round((x / canvas.width) * totalFrames)));
-
- const { dialIndex, originalFrame } = draggingKeyframe;
- const value = dialKeyframes[dialIndex][originalFrame];
-
- if (newFrame !== originalFrame) {
- delete dialKeyframes[dialIndex][originalFrame];
- dialKeyframes[dialIndex][newFrame] = value;
- draggingKeyframe.originalFrame = newFrame;
- drawTimelineMarkers();
- }
- });
-
-
- canvas.addEventListener('mouseup', () => {
- isDragging = false;
- draggingKeyframe = null;
- syncMotorsWithTimeline();
- });
-
- canvas.addEventListener('dblclick', (e) => {
- const x = e.offsetX;
- const frame = Math.round((x / canvas.width) * totalFrames);
- const dialIndices = selectedDial !== null ? [selectedDial] : [0, 1, 2, 3, 4];
-
- for (let ch of dialIndices) {
- if (dialKeyframes[ch][frame] !== undefined) {
- delete dialKeyframes[ch][frame];
- drawTimelineMarkers();
- }
- }
- });
@@ -815,8 +694,6 @@ window.onload = () => {
};
- drawTimelineMarkers();
-