Skip to content
This repository has been archived by the owner on Aug 7, 2024. It is now read-only.

Commit

Permalink
feat: map zoom
Browse files Browse the repository at this point in the history
  • Loading branch information
jwcub committed May 2, 2024
1 parent d4f2a44 commit 78a802c
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 97 deletions.
81 changes: 63 additions & 18 deletions app/game/view/baseRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Application, Graphics } from "pixi.js";
import type { Gm } from "../gm/gm";
import type { Pos } from "../gm/matrix";

const DEFAULT_RADIUS = 25;
import { R } from "./constants";

/**
* Basic renderer without mode support.
Expand All @@ -15,11 +15,6 @@ export default abstract class BaseRenderer {
graphics = new Graphics();
gm: Gm;

/**
* Radius of the circumscribed circle of a polygon.
*/
radius: number = DEFAULT_RADIUS;

protected constructor(gm: Gm) {
this.gm = gm;
}
Expand All @@ -28,36 +23,91 @@ export default abstract class BaseRenderer {
* Initializes the Renderer with the given canvas.
*/
async init(canvas: HTMLCanvasElement) {
const height = canvas.parentElement?.clientHeight;
const width = canvas.parentElement?.clientWidth;

await this.app.init({
antialias: true,
powerPreference: "high-performance",
canvas,
height: canvas.parentElement?.clientHeight,
width: canvas.parentElement?.clientWidth
height,
width
});

this.app.stage.addChild(this.graphics);

// Zoom support.
canvas.onwheel = event => {
event.preventDefault();

const newScale = this.app.stage.scale.x + (event.deltaY > 0 ? -0.1 : 0.1);

if (newScale >= 0.5 && newScale <= 2) {
this.app.stage.scale.set(newScale);
}
};

// Move support.
canvas.onpointerdown = event => {
const startX = event.pageX,
startY = event.pageY;

const initialStartX = this.app.stage.x,
initialStartY = this.app.stage.y;

let flag = false;

document.onpointermove = event => {
const deltaX = event.pageX - startX;
const deltaY = event.pageY - startY;

if (!flag && (Math.abs(deltaX) > 20 || Math.abs(deltaY) > 20)) {
flag = true;
document.body.setAttribute("style", "user-select: none");
}

if (!flag) {
return;
}

this.app.stage.x = initialStartX + deltaX;
this.app.stage.y = initialStartY + deltaY;
};

document.onpointerup = event => {
event.preventDefault();
document.body.removeAttribute("style");
document.onpointermove = document.onpointerup = null;
};
};
}

/**
* Gets the base shape of the polygon at the given pos. (radius = 1)
* Gets the base shape of the polygon at the given pos. (R = 1)
*/
abstract shape(pos: Pos): PointData[];

/**
* Gets the top-left position of the polygon at the given pos.
* Gets the top-left position of the polygon at the given pos. (R = 1)
*/
abstract topLeft(pos: Pos): PointData;

/**
* Destroys the renderer and its resources.
*/
destroy() {
this.app.destroy(false, true);
}

/**
* Gets the piles of the polygon at the given pos.
*/
poly(pos: Pos): PointData[] {
const { x: startX, y: startY } = this.topLeft(pos);

return this.shape(pos).map(({ x, y }) => ({
x: x * this.radius + startX,
y: y * this.radius + startY
x: (x + startX) * R,
y: (y + startY) * R
}));
}

Expand All @@ -66,13 +116,8 @@ export default abstract class BaseRenderer {
*/
updateGraphics(pos: Pos) {
const fillColor = _.random(0, 0xffffff);
const borderColor = 0xffffff;
const lineWidth = 1;

this.graphics.poly(this.poly(pos)).fill(fillColor).stroke({
width: lineWidth,
color: borderColor
});
this.graphics.poly(this.poly(pos)).fill(fillColor);
}

/**
Expand Down
1 change: 1 addition & 0 deletions app/game/view/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const R = 30;
14 changes: 7 additions & 7 deletions app/game/view/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,23 +51,23 @@ export default class Renderer extends BaseRenderer {
switch (this.gm.mode) {
case Gm.Mode.Hexagon: {
return {
x: (j - 1) * 1.5 * this.radius,
x: (j - 1) * 1.5,
y:
j % 2 === 0
? (Math.sqrt(3) / 2 + (i - 1) * Math.sqrt(3)) * this.radius
: (i - 1) * Math.sqrt(3) * this.radius
? Math.sqrt(3) / 2 + (i - 1) * Math.sqrt(3)
: (i - 1) * Math.sqrt(3)
};
}
case Gm.Mode.Square: {
return {
x: (j - 1) * Math.sqrt(2) * this.radius,
y: (i - 1) * Math.sqrt(2) * this.radius
x: (j - 1) * Math.sqrt(2),
y: (i - 1) * Math.sqrt(2)
};
}
case Gm.Mode.Triangle: {
return {
x: (Math.sqrt(3) / 2) * (j - 1) * this.radius,
y: 1.5 * (i - 1) * this.radius
x: (Math.sqrt(3) / 2) * (j - 1),
y: 1.5 * (i - 1)
};
}
}
Expand Down
8 changes: 4 additions & 4 deletions app/routes/map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ export default function Map() {
function generateGm() {
return Gm.empty(
_.sample(Object.values(Gm.Mode))!,
_.random(4, 6),
_.random(8, 10)
_.random(2, 5) * 10,
_.random(2, 5) * 10
);
}

Expand All @@ -38,7 +38,7 @@ export default function Map() {

return () => {
try {
_renderer.app.destroy(false, true);
_renderer.destroy();
} catch {
return;
}
Expand All @@ -47,7 +47,7 @@ export default function Map() {

return (
<Center flexDir="column" gap={2} w="100%">
<Box w="500px" h="300px">
<Box w="60vw" h="70vh">
<chakra.canvas ref={canvas} />
</Box>

Expand Down
Loading

0 comments on commit 78a802c

Please sign in to comment.