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 @@ - +

Snappa

-
-
+
+
+
+
+
+
+
+
+ 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" - ] + } }