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.
Update the naming of your variables.
JavaScript
let moveInterval = 1.8; // Formerly playSpeed
let moveSpeed = 0.3; // New variable for animation duration (dur)
Update the IDs in your HTML for the interval button and add the new speed button logic.
HTML Changes:
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';
});
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);
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);
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?