Skip to content
Open
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
210 changes: 201 additions & 9 deletions script.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,68 @@ const resolvePeekX = () => {
PEEK.x = Math.sign(percY) * Math.pow(Math.abs(percY), 3) * MAX_TILT;
};

const DEFAULT_POS = {
top: {
x: -0.5,
y: -1,
z: -0.5,
rot: "1, 0, 0, 90deg",
perpendicularAxis: "y",
},
front: {
x: -0.5,
y: -0.5,
z: 1,
rot: "0, 1, 0, 0deg",
perpendicularAxis: "z",
},
left: {
x: -1,
y: -0.5,
z: -0.5,
rot: "0, 1, 0, -90deg",
perpendicularAxis: "x",
},
right: {
x: 1,
y: -0.5,
z: 0.5,
rot: "0, 1, 0, 90deg",
perpendicularAxis: "x",
},
bottom: {
x: -0.5,
y: 1,
z: 0.5,
rot: "1, 0, 0, -90deg",
perpendicularAxis: "y",
},
back: {
x: -0.5,
y: 0.5,
z: -1,
rot: "0, 1, 0, 180deg",
perpendicularAxis: "z",
},
};

const OFFSET = 0.01;

const getAxisTranslation = (axis, face, posValue) => {
const isPerpendicular = DEFAULT_POS[face].perpendicularAxis === axis;
return `calc(${isPerpendicular ? "var(--half-size)" : "var(--size)"} * ${
DEFAULT_POS[face][axis] * (1 + (isPerpendicular ? OFFSET : 0)) +
(posValue || 0)
})`;
};

const PLAYER = {
element: document.getElementById("player"),
x: 256,
y: 256,
w: 16,
h: 32,
customPos: undefined,

get midX() {
return this.x + this.w * 0.5;
Expand All @@ -136,15 +192,26 @@ const PLAYER = {
//

place() {
const xOffset = Math.floor(this.x / 512);
const yOffset = Math.floor(this.y / 512);
const transX =
((this.x - (256 + 512 * xOffset)) / 512) * 100 * (512 / this.w);
const transY =
((this.y - (256 + 512 * yOffset)) / 512) * 100 * (512 / this.h);
const YAxisRotations = xOffset * 90;
const XAxisRotations = yOffset * -90;
this.element.style.transform = `rotateY(${YAxisRotations}deg) rotateX(${XAxisRotations}deg) translate3d(${transX}%, ${transY}%, var(--half-size))`;
if (this.customPos) {
const { face, x, y, rot } = this.customPos;

const tX = getAxisTranslation("x", face, x);
const tY = getAxisTranslation("y", face, y);
const tZ = getAxisTranslation("z", face);

this.element.style.transform = `translate3d(${tX}, ${tY}, ${tZ}) rotate3d(${DEFAULT_POS[face].rot}) rotateX(${rot}deg)`;
} else {
const xOffset = Math.floor(this.x / 512);
const yOffset = Math.floor(this.y / 512);
const transX =
((this.x - (256 + 512 * xOffset)) / 512) * 100 * (512 / this.w);
const transY =
((this.y - (256 + 512 * yOffset)) / 512) * 100 * (512 / this.h);
const YAxisRotations = xOffset * 90;
const XAxisRotations = yOffset * -90;

this.element.style.transform = `rotateY(${YAxisRotations}deg) rotateX(${XAxisRotations}deg) translate3d(${transX}%, ${transY}%, var(--half-size))`;
}
},
};

Expand Down Expand Up @@ -174,3 +241,128 @@ const step = (timeStamp, then) => {
};

step(performance.now(), 0);

/*
grid square size = ∆

x-axis ->
x = 0 x = ∆ x = 2∆ x = 3∆
---------------------------------- y = 0
| | | | y
| R0C0 | T | R0C2 | -
| | | | a
---------------------------------- x y = ∆
| | | | i
| L | F | R | s
| | | |
---------------------------------- | y = 2∆
| | | | v
| R2C0 | Bo | R2C2 |
| | | |
---------------------------------- y = 3∆
| | | |
| R3C0 | Ba | R3C2 |
| | | |
---------------------------------- y = 4∆
*/

const getGridCellIndex = (gridSquareSize, axis, axisPos) => {
let indexes;
if (axis === "row") {
indexes = [0, 1, 2, 3];
} else if (axis === "col") {
indexes = [0, 1, 2];
}

if (!indexes) {
throw new Error(
`getGridCellIndex: Invalid param value for 'axis' (${axis}), must be 'row' or 'col'`
);
}

return indexes.find(
(index) =>
axisPos >= gridSquareSize * index &&
axisPos < gridSquareSize * (index + 1)
);
};

const getCurrentFace = (gridSquareSize, xPos, yPos) => {
const col = getGridCellIndex(gridSquareSize, "col", xPos);
const row = getGridCellIndex(gridSquareSize, "row", yPos);

// invalid grid squares
if (
(row === 0 && col === 0) ||
(row === 0 && col === 2) ||
(row === 2 && col === 0) ||
(row === 2 && col === 2) ||
(row === 3 && col === 0) ||
(row === 3 && col === 2)
) {
return undefined;
}

if (row === 0 && col === 1) {
return "top";
}

if (row === 1 && col === 0) {
return "left";
}

if (row === 1 && col === 1) {
return "front";
}

if (row === 1 && col === 2) {
return "right";
}

if (row === 2 && col === 1) {
return "bottom";
}

if (row === 3 && col === 1) {
return "back";
}
};

const convertPosition2dTo3d = (gridSquareSize, xPos, yPos, rotation) => {
const face = getCurrentFace(gridSquareSize, xPos, yPos);

if (!face) {
throw new Error(
`Player position (${xPos}, ${yPos}) results in an invalid face`
);
}

let startPos;
if (face === "top") {
startPos = { col: 1, row: 0 };
} else if (face === "left") {
startPos = { col: 0, row: 1 };
} else if (face === "front") {
startPos = { col: 1, row: 1 };
} else if (face === "right") {
startPos = { col: 2, row: 1 };
} else if (face === "bottom") {
startPos = { col: 1, row: 2 };
} else if (face === "back") {
startPos = { col: 1, row: 3 };
}

const endPos = { col: startPos.col + 1, row: startPos.row + 1 };

// x and y are percentages for how far along that value is on the given axis for the current face

const colStart = startPos.col * gridSquareSize;
const colEnd = endPos.col * gridSquareSize;
const x = (xPos - colStart) / (colEnd - colStart);

const rowStart = startPos.row * gridSquareSize;
const rowEnd = endPos.row * gridSquareSize;
const y = (yPos - rowStart) / (rowEnd - rowStart);

PLAYER.customPos = { face, x, y, rot: rotation };
};