cubing / AnimCubeJS

▶️ Play around with a Rubik's Cube simulator.
https://animcubejs.cubing.net/animcubejs.html
MIT License
25 stars 8 forks source link

Steps Feature #36

Open mjstraughan opened 3 months ago

mjstraughan commented 3 months ago

Would it be possible to implement a steps feature? The user can define a series of facelet definitions and a step rate. Then the cube applet will automatically cycle through each facelet definition every second or based on the user determined step rate. Upon reaching the end step, the applet cycles back to step 1 and continues to repeat. This would be useful for displaying the steps of a cube solving method in a single cube, cycling through interesting patterns, etc.

Example parameters of the idea:

"step1=ddddydddddwdwwwdwdddddbbdddddddggdddddddoddodddddrrddd&step2=ddddyddddwwwwwwwwwdbbdbbdbbdggdggdggdddoooooodrrdrrdrr&step3=yyyyyyyyywwwwwwwwwdbbdbbdbbdggdggdggdddoooooodrrdrrdrr&step4=yyyyyyyyywwwwwwwwwbbbbbbbbbgggggggggooooooooorrrrrrrrr&steprate=1"

mfeather1 commented 3 months ago

It can be done using method described in Enhancement section in AnimCubeJS Doc, here is an example of how to do it:

<!doctype html>
<html>
<head>
  <script src=AnimCube3.js></script>
</head>
<body>
<center>
<br>
<div id=c1 style=width:200px;height:200px></div>
<script>
var acjs_removeListeners = [];
var arr = [
  'ddddydddddwdwwwdwdddddbbdddddddggdddddddoddodddddrrddd',
  'ddddyddddwwwwwwwwwdbbdbbdbbdggdggdggdddoooooodrrdrrdrr',
  'yyyyyyyyywwwwwwwwwdbbdbbdbbdggdggdggdddoooooodrrdrrdrr',
  'yyyyyyyyywwwwwwwwwbbbbbbbbbgggggggggooooooooorrrrrrrrr'
];
var rate = 1;
var n = 0;
AnimCube3('id=c1');
f();
function f() {
  acjs_removeListeners['c1']();
  var params = 'id=c1&facelets=' + arr[n++%4];
  AnimCube3(params);
  setTimeout(f, rate*1000);
}
</script>
</center>
</body>
</html>
mjstraughan commented 3 months ago

Thank you. I'll try to get this working on my site.

mfeather1 commented 3 months ago

Here is a slightly modified version that shows how to do multiple cubes, if needed.

<!doctype html>
<html>
<head>
  <script src=AnimCube3.js></script>
</head>
<body>
<center>
<br>
<table>
 <tr>
  <td><div id=c1 style=width:200px;height:200px></div></td>
  <td width=40>
  <td><div id=c2 style=width:200px;height:200px></div></td>
 </tr>
</table>
<script>
var acjs_removeListeners = [];
var arr1 = [
  'ddddydddddwdwwwdwdddddbbdddddddggdddddddoddodddddrrddd',
  'ddddyddddwwwwwwwwwdbbdbbdbbdggdggdggdddoooooodrrdrrdrr',
  'yyyyyyyyywwwwwwwwwdbbdbbdbbdggdggdggdddoooooodrrdrrdrr',
  'yyyyyyyyywwwwwwwwwbbbbbbbbbgggggggggooooooooorrrrrrrrr'
];
var arr2 = [
  'rlrlrlrlrrlrlrlrlrllllllllllllllllllllllllllllllllllll',
  'rlrlrlrlrrlrlrlrlrylylylylyylylylylyblblblblbblblblblb',
  'lrlrrrlrllrlrrrlrllylyyylyllylyyylyllblbbblbllblbbblbl',
  'rrrrrrrrrrrrrrrrrryyyyyyyyyyyyyyyyyybbbbbbbbbbbbbbbbbb'
];
var rate = 1;
AnimCube3('id=c1');
AnimCube3('id=c2');
demo('c1', arr1, 0);
demo('c2', arr2, 0);
function demo(id, arr, n) {
  acjs_removeListeners[id]();
  var params = 'id=' + id + '&facelets=' + arr[n++%arr.length];
  AnimCube3(params);
  setTimeout(demo, rate*1000, id, arr, n);
}
</script>
</center>
</body>
</html>
mfeather1 commented 2 months ago

I implemented a local copy of your website and got a demo working by doing the following:

In dir src/components, copy AnimCube dir to AnimCubeDemo and modify index.js as shown:

export default function AnimCubeDemo({
  params,
  facelets,
  width = "200px",
  height = "219px",
}) {
  const id = "animcube_" + useId();
  const divRef = useRef();
  useEffect(() => {
    if (typeof acjs_removeListeners == 'undefined')
      window.acjs_removeListeners = [];
    var n = 0;
    var arr = facelets.split(',');
    var p = `id=${id}&${params}`;
    demo();
    function demo() {
      if (acjs_removeListeners[id])
        acjs_removeListeners[id]();
      AnimCube3(`${p}&facelets=${arr[n++%arr.length]}`);
      if (n < 3*arr.length)      // # of iterations
        setTimeout(demo, 1000);  // delay in milliseconds
    }
    const canvas = divRef.current?.childNodes[0];
    if (canvas) {
      canvas.style.maxWidth = "100%";
    }
  }, [params]);

  return <div ref={divRef} style={{ width, height, maxWidth: "100%" }} id={id} />;
}

Modify .md file in docs/3x3/Methods as shown, facelets is passed as a separate parameter with multiple strings separated by commas.

import AnimCubeDemo from "@site/src/components/AnimCubeDemo";

<AnimCubeDemo params="buttonbar=0&position=lluuu&scale=6&hint=10&hintborder=1&borderwidth=10" width="400px" height="400px" facelets="ddddydddddwdwwwdwdddddbbdddddddggdddddddoddodddddrrddd,ddddyddddwwwwwwwwwdbbdbbdbbdggdggdggdddoooooodrrdrrdrr,yyyyyyyyywwwwwwwwwdbbdbbdbbdggdggdggdddoooooodrrdrrdrr,yyyyyyyyywwwwwwwwwbbbbbbbbbgggggggggooooooooorrrrrrrrr"/>
mjstraughan commented 2 months ago

This works very well. Thank you!

mfeather1 commented 2 months ago

:)