調整動畫速度與間隔變數

To implement these changes, we need to rename the interval logic, introduce the new speed variable, and update the SVG export logic to use this dynamic duration.

1. Global Variables & Initialization

Update the naming of your variables.

JavaScript

let moveInterval = 1.8; // Formerly playSpeed
let moveSpeed = 0.3;    // New variable for animation duration (dur)

2. UI Elements & Event Listeners

Update the IDs in your HTML for the interval button and add the new speed button logic.

HTML Changes:

  • Rename btn-speed to btn-interval.
  • Add a new button btn-speed after btn-interval.

JavaScript Changes:

JavaScript

// Interval Button (formerly playSpeed)
const btnInterval = document.getElementById('btn-interval');
btnInterval.addEventListener('click', () => {
   moveInterval = parseFloat((moveInterval + 0.2).toFixed(1));
   if (moveInterval > 4.0) moveInterval = 0.6;
   btnInterval.textContent = moveInterval.toFixed(1) + 's';
});

// Speed Button (Animation Duration)
const btnSpeed = document.getElementById('btn-speed');
btnSpeed.addEventListener('click', () => {
   // Cycle through 0.3, 0.5, 0.7
   if (moveSpeed === 0.3) moveSpeed = 0.5;
   else if (moveSpeed === 0.5) moveSpeed = 0.7;
   else moveSpeed = 0.3;

   // Safety check: moveSpeed cannot exceed moveInterval
   if (moveSpeed > moveInterval) moveSpeed = moveInterval;
   
   btnSpeed.textContent = moveSpeed.toFixed(1) + 's';
});

3. Update Auto-Play Logic

Update the reference in your playNextAnimated function (or wherever the interval is used).

JavaScript

// Inside playNextAnimated or similar auto-play loop
setTimeout(playNextAnimated, moveInterval * 1000);


4. Updated SVG Export Logic

Modify the tool-exp-svg listener to use moveInterval for delays and moveSpeed for the animation duration. I have also included the cleanup for the a14 namespaces you mentioned earlier.

JavaScript

// Inside the tool-exp-svg click listener
const delayStr = moveInterval + 's';
const durationStr = moveSpeed + 's'; // Replace 0.12s

pathNodes.forEach((node, i) => {
   let stepNum = i + 1;
   // ... coordinates logic ...

   let beginStr = (stepNum === 1)
       ? `${delayStr};step0.end+${delayStr}`
       : `step${stepNum - 1}.begin+${delayStr}`;

   // Step 4: Use durationStr (moveSpeed) instead of 0.12s
   if (boardPiece) {
       const animT = document.createElementNS('http://www.w3.org/2000/svg', 'animateTransform');
       animT.setAttribute('id', `step${stepNum}`);
       animT.setAttribute('begin', beginStr);
       animT.setAttribute('attributeName', 'transform');
       animT.setAttribute('attributeType', 'XML');
       animT.setAttribute('type', 'translate');
       animT.setAttribute('from', fromStr);
       animT.setAttribute('to', toStr);
       animT.setAttribute('dur', durationStr); // Updated
       animT.setAttribute('fill', 'freeze');
       boardPiece.appendChild(animT);
   }
   
   // ... repeat for other elements using dur ...
});

// Final Serialization and Namespace Cleanup
let svgString = new XMLSerializer().serializeToString(cloneSvg);
svgString = svgString
   .replace(/a\d+:href/g, 'href')
   .replace(/\s?xmlns:a\d+="[^"]*"/g, '')
   .replace(/xlink:href/g, 'href')
   .replace(/\s?xmlns:xlink="[^"]*"/g, '');

showSvgExportModal(svgString, true);

5. Final Move Reset Timing

In Step 8 of the export, ensure the reset also aligns with the new intervals.

JavaScript

// Inside Step 8 logic
const step0 = document.createElementNS('http://www.w3.org/2000/svg', 'animate');
step0.setAttribute('id', 'step0');
// Trigger reset 4 seconds after the last piece finishes its move
step0.setAttribute('begin', `step${finalStepNum}.end+4s`);
step0.setAttribute('attributeName', 'opacity');
step0.setAttribute('values', '1;0;0;1');
step0.setAttribute('dur', '3s');
step0.setAttribute('fill', 'freeze');

Would you like me to help you format the CSS for the new btn-speed button to ensure it matches the layout?