# Javascript port of visualcube



## SolvingRubik (Jan 24, 2019)

Hey guys. Just thought I'd post this here in case anyone was interested. I'm sure most of you have heard of visualcube. I've put a little work into porting it to typescript/javascript to allow rendering images right in your page without requesting it from the old .php file. You can find my progress here https://github.com/tdecker91/visualcube

I know there are other great javascript cube visualization libraries out there, like TwistySim and RoofPig. Other libraries that have a larger variety of supported puzzles etc... But visualcube was always my favorite. It looks great. Plus sometimes you only need to generate an image and don't need a 3d interactive puzzle.

The code is pretty much spaghetti, but it seems to function almost just like the original. I left out a few minor features. Also the api is changed a bit. Calling it from javascript is completely different from the old URL parameter api.

I hope to take what I learned from doing this and build a more generic version that can render any WCA puzzle. And make the code cleaner while i'm at it. 

Anyway, enjoy! I hope someone finds it useful.
Let me know if you have any suggestions or find any issues with it. Hopefully the documentation is clear.

Edits:



Spoiler: Algorithm parsing update



Algorithm parsing has been improved. It should support any valid WCA scramble for NxN cubes. The alg can be applied to any size cube

For example, the following will scramble a 5x5 cube. The same pattern can be used for larger cubes.

```
cubePNG(element, {
  cubeSize: 5,
  algorithm: 'R U Uw2 Bw\' Dw L\' F\' Lw\' Dw Lw\' B Lw2 Bw B2 U2 L\' Fw Rw D\' Rw\' Bw D\' Rw2 L2 B L2 Bw L B\' R\' F\' R\' B\' Dw2 Lw2 D2 Dw\' B Lw L\' R\' Fw Uw2 R2 Bw\' Lw\' B R L\' Dw2 F D2 Bw\' U\' Uw F\' B R\' D2 Bw2'
});
```






Spoiler: API Update



I've updated the API so you can pass in the old style URL for the parameters so you don't have to rebuild any of your image configs to use this.
Example

```
cubePNG(element, "visualcube.php?size=150&pzl=3&stage=f2l&case=U(RU'R')&fmt=png&sch=ygrwbo")
```






Spoiler: v1.0.5



I've added support for the old "fd" parameter. This allows user to define color of sticker by color scheme. "Transparent" stickers work now as well. If the sticker color is "transparent" then it won't even be rendered.

Not much of a change, but these are just steps making it more backwards compatible with the original version.


----------



## AndyK (Jan 24, 2019)

This is fantastic. Thank you!


----------



## SolvingRubik (Jan 25, 2019)

AndyK said:


> This is fantastic. Thank you!



Thanks!

Also one improvement from the original version that I just added. It supports standard WCA algorithms passed in. And the algorithms can be applied to any size cube.

Example:

```
cubePNG(element, {
  cubeSize: 5,
  algorithm: 'R U Uw2 Bw\' Dw L\' F\' Lw\' Dw Lw\' B Lw2 Bw B2 U2 L\' Fw Rw D\' Rw\' Bw D\' Rw2 L2 B L2 Bw L B\' R\' F\' R\' B\' Dw2 Lw2 D2 Dw\' B Lw L\' R\' Fw Uw2 R2 Bw\' Lw\' B R L\' Dw2 F D2 Bw\' U\' Uw F\' B R\' D2 Bw2'
});
```

Results:


----------



## AndyK (Jan 28, 2019)

More great stuff! Certainly appreciate your work on this

I wonder if more people would utilize this if you came up with a quick program which would translate standard VisualCube notation like this: 

visualcube.php?size=150&pzl=3&stage=f2l&case=U(RU'R')&fmt=png&sch=ygrwbo
visualcube.php?size=150&pzl=3&stage=f2l&case=y'U'(R'UR)&fmt=png&sch=yrbwog
into your Javascript notation.

Perhaps even better, what about a program that takes plain text inputs for each VisualCube input and spits out the Javascript VisualCube notation (and even the standard VisualCube notation)


----------



## SolvingRubik (Jan 29, 2019)

AndyK said:


> More great stuff! Certainly appreciate your work on this
> 
> I wonder if more people would utilize this if you came up with a quick program which would translate standard VisualCube notation like this:
> 
> ...



Great idea! Yeah I had thought of this and have already implemented this idea for the arrows parameter. Because passing in a bunch of arrow definitions was a bit cumbersome compared to the old way. I just need to do this for all the parameter types. Or for example, when calling cubePNG if the options you pass in is a string parameter like this


```
cubePNG(element, 'size=150&pzl=3&stage=f2l&case=y'U'(R'UR)&fmt=png&sch=yrbwog')
```

It could just assume the parameters are to be parsed the old way. That's very doable. I'll see what I can come up with.


----------



## SolvingRubik (Jan 31, 2019)

Great news! I was able to do what I was suggesting no problem.

The following examples you provided renders the following images

```
cubePNG(element, "visualcube.php?size=150&pzl=3&stage=f2l&case=U(RU'R')&fmt=png&sch=ygrwbo")
cubePNG(element, "visualcube.php?size=150&pzl=3&stage=f2l&case=y'U'(R'UR)&fmt=png&sch=yrbwog")
```



There's a few caveats. The "fmt" parameter is ignored, because fmt is determined by calling either cubePNG or cubeSVG. The "fd" and "ac" parameters are also ignored because I haven't programmed the functionality for those yet.

But other than that I think everything works as expected.You can just provide the old URL used for the php script.

If you want to use this functionality make sure you have version 1.0.5 installed via npm. Or just pull the recent changes in the repository.


----------



## AndyK (Feb 11, 2019)

SolvingRubik said:


> ```
> cubePNG(element, "visualcube.php?size=150&pzl=3&stage=f2l&case=U(RU'R')&fmt=png&sch=ygrwbo")
> cubePNG(element, "visualcube.php?size=150&pzl=3&stage=f2l&case=y'U'(R'UR)&fmt=png&sch=yrbwog")
> ```



I love it! This is great stuff!


----------



## bdalyanci (Feb 12, 2019)

Brilliant. Thanks. I'll make this exercise for my coding students.


----------



## Filipe Teixeira (Jul 23, 2019)

Apparently rotations (x, x', x2, y, y', y2, z, z', z2) are not supported.

I put this on my code for rotations to work (filter alg before rendering)


```
function algFilter(alg) {
    const dictionary = {
        "y": "U D' E'",
        "y'": "U' D E",
        "y2": "U2 D2 E2",
        "x": "R M' L'",
        "x'": "R' M L",
        "x2": "R2 M2 L2",
        "z": "F B' S",
        "z'": "F' B S'",
        "z2": "F2 B2 S2",
    };
 
    let final_alg = [];
 
    alg.split(/(\s+)/).forEach(move => {
        if (move in dictionary) {
            final_alg.push(dictionary[move]);
        } else {
            final_alg.push(move);
        }
    });
    return final_alg.join(' ');
}
```


----------



## SolvingRubik (Jul 25, 2019)

You're right. x y z rotation should be supported. Looks like a bug I introduced. I fixed it and pushed new version of the package. 1.0.7



Filipe Teixeira said:


> Apparently rotations (x, x', x2, y, y', y2, z, z', z2) are not supported.
> 
> I put this on my code for rotations to work (filter alg before rendering)
> 
> ...


----------



## Eelpi (Jul 31, 2019)

Great work! By the way, is there a way to disable console.log() messages?


----------



## SolvingRubik (Aug 3, 2019)

Eelpi said:


> Great work! By the way, is there a way to disable console.log() messages?



Gah! yes. of course I would accidentally leave that in there. not sure if npm lets you override an existing version. So I had to make due with updating the package version to 1.0.8

Thanks for the feeback!


----------



## Eelpi (Aug 5, 2019)

Thanks for going through the trouble of updating it!
I'm making an algorithm trainer and this was a godsend as I wanted to keep it pure js


----------

