• Welcome to the Speedsolving.com, home of the web's largest puzzle community!
    You are currently viewing our forum as a guest which gives you limited access to join discussions and access our other features.

    Registration is fast, simple and absolutely free so please, join our community of 40,000+ people from around the world today!

    If you are already a member, simply login to hide this message and begin participating in the community!

Javascript port of visualcube

SolvingRubik

Member
Joined
Jan 24, 2019
Messages
16
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:

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.
JavaScript:
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'
});
scramble.png

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
JavaScript:
cubePNG(element, "visualcube.php?size=150&pzl=3&stage=f2l&case=U(RU'R')&fmt=png&sch=ygrwbo")
7829-2c6b4e58769face6dca43873dcd2f3da.png

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.
 
Last edited:
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:
JavaScript:
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:
scramble.png
 

Attachments

  • scramble.png
    scramble.png
    29 KB · Views: 0
Last edited:
  • Like
Reactions: pjk
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)
 
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)

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

Code:
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.
 
Great news! I was able to do what I was suggesting no problem.

The following examples you provided renders the following images
Code:
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")

download.pngdownload-1.png

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.
 
  • Like
Reactions: pjk
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)

JavaScript:
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(' ');
}
 
Last edited:
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

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)

JavaScript:
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(' ');
}
 
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! :)
 
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 :D
 
Back
Top