Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 11 additions & 39 deletions TODOS.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,11 @@
- add cube orientation translation support

```ts
export type Color = "white" | "yellow" | "blue" | "green" | "orange" | "red";
export type CubeOrientation = { top: Color; front: Color };
type Rotation = "x" | "x2" | "x'" | "y" | "y2" | "y'" | "z" | "z2" | "z'";
type Side = "front" | "top" | "left" | "right" | "bottom" | "back";
type Cube = { [s in Side]: Color };

const rotations: { [rotation in Rotation]: { [side in Side]?: Side } } = {
x: { top: "front", front: "bottom", bottom: "back", back: "top" },
x2: { top: "bottom", front: "back", bottom: "top", back: "front" },
"x'": { top: "back", front: "top", bottom: "front", back: "bottom" },
y: { front: "right", right: "back", back: "left", left: "front" },
y2: { front: "back", right: "left", back: "front", left: "right" },
"y'": { front: "left", right: "front", back: "right", left: "back" },
z: { top: "left", left: "bottom", bottom: "right", right: "top" },
z2: { top: "bottom", left: "right", bottom: "top", right: "left" },
"z'": { top: "right", left: "top", bottom: "left", right: "bottom" },
};

const solvedCube: Cube = {
top: "white",
front: "green",
left: "orange",
right: "red",
bottom: "yellow",
back: "blue",
};

function rotateCube(cube: Cube, rotation: Rotation): Cube {
const transform = rotations[rotation];
const newCube: Cube = { ...cube };
Object.entries(transform).forEach(([src, dst]: [Side, Side]) => {
newCube[src] = cube[dst];
});
return newCube;
}
```
- beginner section
- roux section
- cfop section
- method development section
- homepage
- add theme colours to tailwind css config

- prepare for launch
- remove ZZMethod.com from articles
- verify no broken links within the website
- redirect all old URLs to their new locations with vercel
8 changes: 3 additions & 5 deletions components/AlgSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,15 @@ export default function AlgSheet({ algSet }: AlgSheetProps) {
<strong className={styles.mobileName}>{algCase.name}</strong>
<TwistyPlayer
alg={algCase.algs[0]}
stickeringSetup="x2"
experimentalSetupAlg="x2"
experimentalSetupAnchor="end"
rotateStickering="x2"
experimentalSetupAnchor="end"
visualization={
algSet.visualization === "3D" ? "3D" : "experimental-2D-LL"
}
experimentalStickering={algSet.stickering}
experimentalStickeringMaskOrbits={algSet.customStickering}
controlPanel="none"
background="none"
className={styles.algImage}
className={styles.algImage}
rootClassName={styles.algImage}
/>
<p className={styles.mobileCategory}>{algCase.category}</p>
Expand Down
22 changes: 22 additions & 0 deletions components/LinkButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { cn } from "@/utils/classnames";
import Link from "next/link";
import { type ReactNode } from "react";

export interface LinkButtonProps {
href: string;
children: ReactNode;
id?: string;
className?: string;
}

// TODO
export const LinkButton = ({
href,
children,
id,
className,
}: LinkButtonProps) => (
<Link href={href} id={id} className={cn("nextra-focus", className)}>
{children}
</Link>
);
136 changes: 97 additions & 39 deletions components/TwistyPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,44 @@ export interface TwistyPlayerExtendedConfig extends TwistyPlayerConfig {
className?: string;
rootClassName?: string;
onTwistyInit?: (twisty: TP) => void;
stickeringSetup?: Alg | string;
rotateStickering?: Alg | string;
}

/**
* A React wrapper for the cubing.js `<twisty-player>` element.
*/
/**
* A React wrapper for the cubing.js `<twisty-player>` element.
* See all supported props: https://experiments.cubing.net/cubing.js/twisty/twisty-player-props/
* Please note: in React, these props are written in "camel case", for example controlPanel instead of control-panel.
* There are three additional props added for convenience:
* 1. `className`: CSS class to customize the Twisty Player itself
* 2. `rootClassName`: CSS class to customize the `<span>` element that wraps the Twisty Player
* 3. `rotateStickering`: a cube rotation that translates the stickering
*
* See the end of the file for documentation about the `experimentalStickeringMaskOrbits` prop.
*
* @example
* import TwistyPlayer from "@site/src/components/TwistyPlayer";
* // Roux FB+SS with custom stickering.
* // The blocks have orange on bottom due to rotateStickering="z".
* <TwistyPlayer
* experimentalStickeringMaskOrbits="EDGES:IIIII-I-I---,CORNERS:IIIII---,CENTERS:I-I-II"
* rotateStickering="z"
* alg="R"
* />
* // 5x5 with example cross scramble + solution.
* // Uses a preset stickering from cubing.js.
* <TwistyPlayer
* puzzle="5x5x5"
* experimentalSetupAlg="R D' L R2 B U' R' D R D F'"
* alg="y' R2 F R' L' D L'"
* />
*/
const TwistyPlayer = forwardRef(
(
{
className,
rootClassName,
onTwistyInit,
stickeringSetup,
rotateStickering,
...props
}: TwistyPlayerExtendedConfig,
ref
Expand All @@ -35,13 +60,23 @@ const TwistyPlayer = forwardRef(
const spanRef = useRef<HTMLSpanElement | null>(null);

useEffect(() => {
const newTwisty = new TP(props);
// If `rotateStickering` is defined, prefix the alg setup with the inverse of `rotateStickering`.
const setupAlgOverride = rotateStickering
? new Alg(rotateStickering)
.invert()
.concat(props.experimentalSetupAlg ?? [])
: undefined;
const newTwisty = new TP({
background: "none", // override default style
...props,
...(setupAlgOverride && { experimentalSetupAlg: setupAlgOverride }),
});
if (className) {
newTwisty.className = className;
}

if (stickeringSetup) {
transformTPMask(newTwisty, stickeringSetup)
if (rotateStickering) {
transformTPMask(newTwisty, rotateStickering)
}

newTwisty.style.maxWidth = "100%";
Expand Down Expand Up @@ -69,36 +104,59 @@ const TwistyPlayer = forwardRef(
export default TwistyPlayer;

/* Documentation for the experimentalStickeringMaskOrbits prop/attribute:
This prop is used to customize the way pieces are highlighted on the cube,
if it's beyond the default supported stickerings such as OCLL or EOCross.
It's an experimental feature that is subject to change.

Pass in a string in the format "EDGES:xxxxxxxxxxxx,CORNERS:xxxxxxxx,CENTERS:xxxxxx"
where each "x" is one of the following characters:
"-": regular
"D": dim
"I": ignored
"X": invisible
"O": ignore non-primary (ignore the non-primary stickers)
"P": permute non-primary (dim the primary stickers, useful for PLL and other stickerings where just the permutation of pieces matters)
"o": ignoriented (same as O, except the primary sticker is also dimmed)
"?": orientation without permutation (useful for EO and CO on the entire cube! Primary stickers are replaced with turquoise)
This is defined in https://github.com/cubing/cubing.js/blob/36c57c2dadc889b1321d05d8cfc005cef8a9bffd/src/cubing/twisty/model/props/puzzle/display/parseSerializedStickeringMask.ts

"Primary stickers" are stickers that belong on the U and D faces, and FL, FR, BL, BR positions.
They're relevant for edge orientation and corner orientation.

Here is the order of the pieces for 3x3:
EDGES:
UF, UR, UB, UL,
DF, DR, DB, DL,
FR, FL, BR, BL

CORNERS:
UFR, UBR, UBL, UFL,
DFR, DFL, DBL, DBR

CENTERS: U, L, F, R, B, D
This prop is used to create custom stickerings for puzzles, letting you show/dim/hide specific pieces.
It's an experimental feature that is subject to change.

# ---------- 3x3 ----------

Set `experimentalStickeringMaskorbits` to a string in the format "EDGES:xxxxxxxxxxxx,CORNERS:xxxxxxxx,CENTERS:xxxxxx"
where each "x" is one of the following characters:
(table taken from https://github.com/cubing/cubing.js/commit/668179c8bb116b24775e5450a5d949c38068d3a0)
| Character | Primary | Other | Meaning |
|-----------|----------|--------|------------------------------------------------------|
| `-` | bright | bright | piece to solve |
| `D` | dim | dim | dim |
| `I` | gray | gray | ignored |
| `P` | bright | gray | to permute (e.g. PLL) |
| `O` | dim | bright | to orient (e.g. OLL) |
| `o` | dim | gray | oriented, primary sticker known (e.g. OLL completed) |
| `?` | oriented | gray | oriented, primary sticker unknown (e.g. EO) |
| `X` | N/A | N/A | invisible |

This is defined in https://github.com/cubing/cubing.js/blob/36c57c2dadc889b1321d05d8cfc005cef8a9bffd/src/cubing/twisty/model/props/puzzle/display/parseSerializedStickeringMask.ts

"Primary stickers" are stickers that belong on the U and D faces, and FL, FR, BL, BR positions.
They're relevant for edge orientation and corner orientation.

Here is the order of the pieces for 3x3:
EDGES:
UF, UR, UB, UL,
DF, DR, DB, DL,
FR, FL, BR, BL

CORNERS:
UFR, UBR, UBL, UFL,
DFR, DFL, DBL, DBR

CENTERS: U, L, F, R, B, D

For example,
<TwistyPlayer
puzzle="3x3x3"
experimentalStickeringMaskOrbits="EDGES:-I----------,CORNERS:--------,CENTERS:------"
/>
will have the UR edge invisible.

# ---------- Other puzzles ----------
Very similar, except we generalize the format "EDGES:xxxxxxxxxxxx,CORNERS:xxxxxxxx,CENTERS:xxxxxx"
Replace EDGES, CORNERS, and CENTERS with the names of the piece orbits as defined in cubing.js.
- pyra: EDGES, CORNERS, CORNERS2
- 5x5: EDGES, EDGES2, CORNERS, CENTERS, CENTERS2, CENTERS3
To find the names of these orbits for any puzzle, go to https://experiments.cubing.net/cubing.js/twisty/twisty-player-props/
Look at the kpuzzle box, and try to copy the entire contents of that box. orbitNames is what you need.

Then, each orbit name is followed with characters from the table above, to sticker the pieces of that orbit.
Please ensure the number of characters matches the number of pieces in that orbit, otherwise you may get errors.
*/

// adapted from https://github.com/cubing/cubing.js/issues/224#issuecomment-1275928713
Expand Down Expand Up @@ -130,4 +188,4 @@ async function transformTPMask(twisty: TP, transformationSource: Alg | string) {
}

twisty.experimentalStickeringMaskOrbits = newMask;
}
}
Empty file.
11 changes: 11 additions & 0 deletions components/index-page/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import styles from "./index-page.module.css"
import { Link } from 'nextra-theme-docs'

// Usage in MDX: export { IndexPage as default } from '@components/index-page'
export const IndexPage = () => (
<div>
<h1>hello there!</h1>
<Link href="/roux">Roux Method</Link>
<Link href="/zz">ZZ Method</Link>
</div>
)
1 change: 1 addition & 0 deletions lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./simplifyRotations";
export * from "./stickerings";

export type Rotation =
| "x"
Expand Down
10 changes: 10 additions & 0 deletions lib/stickerings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { type TwistyPlayerConfig } from "cubing/twisty";

type Stickering = TwistyPlayerConfig["experimentalStickeringMaskOrbits"];

export const STICKERINGS: Record<string, Stickering> = {
FB: "EDGES:IIIIIII-I-I-,CORNERS:IIIII--I,CENTERS:I-IIII",
SB: "EDGES:IIIII-ID-D-D,CORNERS:IIII-DD-,CENTERS:IDI-II",
CMLL: "EDGES:IIIIIDIDDDDD,CORNERS:----DDDD,CENTERS:IDIDII",
LSE: "EDGES:-----D-DDDDD,CORNERS:DDDDDDDD,CENTERS:-D-D--"
};
2 changes: 1 addition & 1 deletion next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const withNextra = nextra({

export default withNextra({
i18n: {
locales: ["en", "fr", "he", "zh"],
locales: ["en", "fr", "zh"],
defaultLocale: "en",
},
});
Loading