diff --git a/img/beer.png b/img/beer.png
new file mode 100644
index 0000000..29229d6
Binary files /dev/null and b/img/beer.png differ
diff --git a/img/grass.png b/img/grass.png
new file mode 100644
index 0000000..1c5ce24
Binary files /dev/null and b/img/grass.png differ
diff --git a/index.html b/index.html
index 1a81481..a275248 100644
--- a/index.html
+++ b/index.html
@@ -5,14 +5,27 @@
-
+
-
-
+
+
+
+ Touch and drag the die to throw
+
+
+
diff --git a/index.js b/index.js
deleted file mode 100644
index 895a6a5..0000000
--- a/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import { startApp } from "./modules/index.js";
-
-startApp();
diff --git a/site.css b/site.css
index e69de29..631e9d1 100644
--- a/site.css
+++ b/site.css
@@ -0,0 +1,103 @@
+html,
+body {
+ margin: 0;
+ padding: 0;
+ background: #49713e;
+ background: url('img/grass.png');
+}
+
+body {
+ display: flex;
+ flex-direction: column;
+ height: 100vh;
+}
+
+header {
+ background: #4c76b8;
+ color: #fff;
+ display: flex;
+ flex: 0;
+ justify-content: center;
+}
+
+h1 {
+ font-size: 32px;
+ line-height: 40px;
+}
+
+main {
+ display: flex;
+ flex: 1;
+ position: relative;
+}
+
+.Table {
+ background: #fff;
+ border: 10px groove #ddd;
+ box-shadow: 0px 12px rgba(0, 0, 0, 0.3);
+
+ position: fixed;
+ top: 20vh;
+ bottom: 20vh;
+ left: 10vw;
+ right: 10vw;
+
+ transform: perspective(50cm) rotateX(45deg);
+}
+
+.Cup {
+ position: absolute;
+ background: url('img/beer.png');
+ height: 64px;
+ width: 64px;
+}
+
+#Cup-0 {
+ bottom: 0;
+ left: 0;
+}
+
+#Cup-1 {
+ bottom: 0;
+ right: 0;
+}
+
+#Cup-2 {
+ top: 0;
+ left: 0;
+}
+
+#Cup-3 {
+ top: 0;
+ right: 0;
+}
+
+.Toss {
+ align-self: flex-end;
+ background: rgba(30,30,30,0.4);
+ box-sizing: border-box;
+ color: #ccc;
+ font-size: 20px;
+ height: 20vh;
+ padding-top: 8px;
+ position: relative;
+ text-align: center;
+ width: 100%;
+}
+
+.Power {
+ background: #c00;
+ bottom: 0;
+ position: absolute;
+ height: 40px;
+ width: 20%;
+}
+
+.Die {
+ background: #fff;
+ border: 1px solid #000;
+ height: 20px;
+ position: fixed;
+ transform: translate(-10px, -10px);
+ width: 20px;
+}
diff --git a/src/die.ts b/src/die.ts
new file mode 100644
index 0000000..9926705
--- /dev/null
+++ b/src/die.ts
@@ -0,0 +1,122 @@
+import { Power } from "./power.js";
+
+interface Point {
+ x: number;
+ y: number;
+}
+
+const touchLocation = (event: TouchEvent): Point => {
+ if (event.touches.length === 0) {
+ throw new Error("no touchy");
+ }
+
+ return {
+ x: event.touches[0].pageX,
+ y: event.touches[0].pageY,
+ };
+}
+
+export class Die {
+ node: HTMLDivElement;
+
+ power: Power;
+
+ x: number;
+ y: number;
+
+ offsetX: number = 0;
+ offsetY: number = 0;
+
+ startX: number | null = null;
+ startY: number | null = null;
+
+ positionRAF: number | null = null;
+
+ constructor() {
+ const node = document.getElementById("Die");
+ if (!node) {
+ throw new Error("No dice");
+ }
+
+ this.node = node as HTMLDivElement;
+
+ this.power = new Power();
+
+ this.x = this.initialX();
+ this.y = this.initilaY();
+
+ this.updatePosition();
+
+ node.onmousedown = this.dragStart;
+ node.ontouchstart = this.touchStart;
+ }
+
+ private initialX = () => window.innerWidth / 2;
+ private initilaY = () => window.innerHeight * 0.9;
+
+ private dragStart = ({ x, y }: Point) => {
+ window.addEventListener("mousemove", this.mouseMove);
+ window.addEventListener("touchmove", this.touchMove);
+
+ window.addEventListener("mouseup", this.dragEnd);
+ window.addEventListener("touchend", this.dragEnd);
+
+ this.offsetX = x - this.initialX();
+ this.offsetY = y - this.initilaY();
+
+ this.startX = x;
+ this.startY = y;
+
+ window.requestAnimationFrame(this.updatePosition);
+ }
+
+ private mouseDown = (event: MouseEvent) =>
+ this.dragStart({x: event.pageX, y: event.pageY});
+
+ private touchStart = (event: TouchEvent) =>
+ this.dragStart(touchLocation(event));
+
+ private dragMove = ({ x, y}: Point) => {
+ this.x = x - this.offsetX;
+ this.y = y - this.offsetY;
+
+ window.requestAnimationFrame(this.updatePosition);
+ }
+
+ private mouseMove = (event: MouseEvent) =>
+ this.dragMove({x: event.pageX, y: event.pageY});
+
+ private touchMove = (event: TouchEvent) =>
+ this.dragMove(touchLocation(event));
+
+ private dragEnd = () => {
+ window.removeEventListener("mousemove", this.mouseMove);
+ window.removeEventListener("touchmove", this.touchMove);
+
+ window.removeEventListener("mouseup", this.dragEnd);
+ window.removeEventListener("touchend", this.dragEnd);
+
+ console.log("TOSS!", this.startX, this.startY, this.x, this.y);
+ }
+
+ private updatePosition = () => {
+ this.node.style.left = this.x + "px";
+ this.node.style.top = this.y + "px";
+
+ this.power.setPower(this.getTossPower());
+ }
+
+ private getTossPower = () => {
+ if (this.startX && this.startY) {
+ const dx = this.x - this.startX;
+ const dy = this.y - this.startY;
+
+ const distance = Math.sqrt(dx*dx + dy*dy);
+ const scale = window.innerHeight * 0.2;
+
+ return Math.min(distance / scale, 1);
+ } else {
+ return 0;
+ }
+ }
+}
diff --git a/src/index.ts b/src/index.ts
index 1278cf7..7bd8bde 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,8 +1,5 @@
+import { Die } from "./die.js";
+
export const startApp = () => {
- const root = document.getElementById("main");
-
- const div = document.createElement("div");
- div.innerHTML = "Sup bro";
-
- root.appendChild(div);
+ const die = new Die();
};
diff --git a/src/power.ts b/src/power.ts
new file mode 100644
index 0000000..6f4fbbe
--- /dev/null
+++ b/src/power.ts
@@ -0,0 +1,16 @@
+export class Power {
+ node: HTMLDivElement;
+
+ constructor() {
+ const node = document.getElementById("Power");
+ if (!node) {
+ throw new Error("no power");
+ }
+
+ this.node = node as HTMLDivElement;
+ }
+
+ setPower = (power: number) => {
+ this.node.style.width = power * 100 + "%";
+ }
+}
diff --git a/tsconfig.json b/tsconfig.json
index 454342e..37cb294 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -2,13 +2,8 @@
"compilerOptions": {
"module": "es2015",
"outDir": "modules",
- "strictNullChecks": true,
+ "rootDir": "src",
+ "strict": true,
"target": "es2018"
- },
- "include": [
- "src/**/*/"
- ],
- "exclude": [
- "node_modules"
- ]
+ }
}