Throw looking OK-ish
This commit is contained in:
BIN
img/beer.png
Normal file
BIN
img/beer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
BIN
img/grass.png
Normal file
BIN
img/grass.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
19
index.html
19
index.html
@@ -5,14 +5,27 @@
|
|||||||
<link rel="stylesheet" href="site.css">
|
<link rel="stylesheet" href="site.css">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<script type="module" src="index.js"></script>
|
<script type="module">
|
||||||
|
import { startApp } from "./modules/index.js";
|
||||||
|
window.addEventListener("load", startApp);
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<h1>Snappa</h1>
|
<h1>Snappa</h1>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main id="game">
|
||||||
<div id="main"></div>
|
<div class="Table" id="Table">
|
||||||
|
<div class="Cup" id="Cup-0"></div>
|
||||||
|
<div class="Cup" id="Cup-1"></div>
|
||||||
|
<div class="Cup" id="Cup-2"></div>
|
||||||
|
<div class="Cup" id="Cup-3"></div>
|
||||||
|
</div>
|
||||||
|
<div class="Toss" id="Toss">
|
||||||
|
Touch and drag the die to throw
|
||||||
|
<div class="Power" id="Power"></div>
|
||||||
|
</div>
|
||||||
|
<div class="Die" id="Die"></div>
|
||||||
<noscript>It's a Gentleman's Game</noscript>
|
<noscript>It's a Gentleman's Game</noscript>
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
103
site.css
103
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;
|
||||||
|
}
|
||||||
|
|||||||
122
src/die.ts
Normal file
122
src/die.ts
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,5 @@
|
|||||||
|
import { Die } from "./die.js";
|
||||||
|
|
||||||
export const startApp = () => {
|
export const startApp = () => {
|
||||||
const root = <HTMLDivElement>document.getElementById("main");
|
const die = new Die();
|
||||||
|
|
||||||
const div = document.createElement("div");
|
|
||||||
div.innerHTML = "Sup bro";
|
|
||||||
|
|
||||||
root.appendChild(div);
|
|
||||||
};
|
};
|
||||||
|
|||||||
16
src/power.ts
Normal file
16
src/power.ts
Normal file
@@ -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 + "%";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,13 +2,8 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "es2015",
|
"module": "es2015",
|
||||||
"outDir": "modules",
|
"outDir": "modules",
|
||||||
"strictNullChecks": true,
|
"rootDir": "src",
|
||||||
|
"strict": true,
|
||||||
"target": "es2018"
|
"target": "es2018"
|
||||||
},
|
}
|
||||||
"include": [
|
|
||||||
"src/**/*/"
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"node_modules"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user