game mode selection ui created
This commit is contained in:
+324
-59
@@ -1,112 +1,377 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
font-family: sans-serif;
|
||||||
}
|
}
|
||||||
html {
|
html {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
background-color: #161616;
|
background-color: #161616;
|
||||||
|
font-size: 24px;
|
||||||
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
}
|
}
|
||||||
#target {
|
#frame {
|
||||||
|
width: 60%;
|
||||||
|
height: 75%;
|
||||||
|
/** border: 1px solid white; */
|
||||||
|
}
|
||||||
|
#center {
|
||||||
height: 20px;
|
height: 20px;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
background-color: red;
|
background-color: red;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
#frame {
|
|
||||||
width: 75%;
|
.target {
|
||||||
height: 100vh;
|
height: 20px;
|
||||||
border: 1px solid white;
|
width: 20px;
|
||||||
|
background-color: red;
|
||||||
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
.fade {
|
||||||
|
transition: opacity 1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#text-box {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-content: end;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
color: red;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 2rem;
|
||||||
|
line-height: 2rem;
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 750px) {
|
||||||
|
html {
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
#text-box {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.text { font-size: .5rem; }
|
||||||
|
.title { font-size: 2rem; }
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="frame">
|
<div id="frame"></div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div id="text-box">
|
||||||
|
<span id="intro1" class="hidden title">QUICK</span>
|
||||||
|
<span id="intro2" class="hidden title">DRAW</span>
|
||||||
|
|
||||||
|
<span id="instructions" class="hidden fade">hover on bullseye to start</span>
|
||||||
|
|
||||||
|
|
||||||
|
<span id="countdown3" class="hidden title">3</span>
|
||||||
|
<span id="countdown2" class="hidden title">2</span>
|
||||||
|
<span id="countdown1" class="hidden title">1</span>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="game-modes" class="hidden fade">
|
||||||
|
<button id="normal" onclick="handleNormalMode">normal mode</button>
|
||||||
|
<button id="normal">infinite mode</button>
|
||||||
|
<button id="normal">countdown mode</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<span id="draw" class="hidden title">DRAW!</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
let gameBorderWidth = 1;
|
||||||
|
let targetWidth = 20;
|
||||||
|
let targetHeight = 20;
|
||||||
|
|
||||||
const gameBorderWidth = 1;
|
let pageHeight;
|
||||||
const targetWidth = 20;
|
let pageWidth;
|
||||||
const targetHeight = 20;
|
|
||||||
|
|
||||||
let pageWidth = window.innerWidth;
|
let frameElement;
|
||||||
let pageHeight = window.innerHeight;
|
let frameRect;
|
||||||
|
let frameHeight;
|
||||||
|
let frameWidth;
|
||||||
|
|
||||||
const frameElement = document.getElementById("frame");
|
let center;
|
||||||
let frameHeight = frameElement.offsetHeight;
|
let ratio;
|
||||||
let frameWidth = frameElement.offsetWidth;
|
|
||||||
|
|
||||||
let target;
|
let xFrameAdjustment;
|
||||||
|
let yFrameAdjustment;
|
||||||
|
|
||||||
|
let hovering = false;
|
||||||
|
|
||||||
window.addEventListener("resize", (e) => {
|
let hoverCount = 0;
|
||||||
this.pageWidth = window.innerWidth;
|
|
||||||
this.pageHeight = window.innerHeight;
|
|
||||||
this.frameHeight = frameElement.offsetHeight - targetHeight;
|
|
||||||
this.frameWidth = frameElement.offsetWidth - targetWidth;
|
|
||||||
console.log('page: ' + this.pageWidth + ' x ' + this.pageHeight);
|
|
||||||
console.log('frame: ' + this.frameWidth + ' x ' + this.frameHeight);
|
|
||||||
});
|
|
||||||
|
|
||||||
let k, r, x, y;
|
let currentRound = 0;
|
||||||
|
let countingDown = false;
|
||||||
|
|
||||||
|
// text elements
|
||||||
|
let intro1 = document.getElementById("intro1");
|
||||||
|
let intro2 = document.getElementById("intro2");
|
||||||
|
let instructions = document.getElementById("instructions");
|
||||||
|
|
||||||
|
let one = document.getElementById("countdown1");
|
||||||
|
let two = document.getElementById("countdown2");
|
||||||
|
let three = document.getElementById("countdown3");
|
||||||
|
|
||||||
|
let draw = document.getElementById("draw");
|
||||||
|
|
||||||
|
window.addEventListener("load", initGame);
|
||||||
|
|
||||||
|
function setParameters(event) {
|
||||||
|
pageHeight = window.innerHeight;
|
||||||
|
pageWidth = window.innerWidth;
|
||||||
|
|
||||||
|
frameElement = document.getElementById("frame");
|
||||||
|
frameRect = frameElement.getBoundingClientRect();
|
||||||
|
frameHeight = frameElement.offsetHeight;
|
||||||
|
frameWidth = frameElement.offsetWidth;
|
||||||
|
|
||||||
|
// ratio = (frameHeight - (gameBorderWidth*2)) / (frameWidth - (gameBorderWidth*2));
|
||||||
|
ratio = frameHeight / frameWidth;
|
||||||
|
|
||||||
|
// adjustments to find center of frame in absolute coords (for origin of target cirlce)
|
||||||
|
xFrameAdjustment = ((frameWidth / 2) + frameRect.left) - (targetWidth / 2);
|
||||||
|
yFrameAdjustment = ((frameHeight / 2) + frameRect.top) - (targetWidth / 2);
|
||||||
|
|
||||||
|
// init logs:
|
||||||
|
console.log('page: ' + pageWidth + ' x ' + pageHeight);
|
||||||
|
console.log('frame: ' + frameWidth + ' x ' + frameHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function initGame() {
|
||||||
|
setParameters();
|
||||||
|
|
||||||
|
center = generateTarget(xFrameAdjustment, yFrameAdjustment);
|
||||||
|
center.id = "center";
|
||||||
|
document.body.insertAdjacentElement("afterbegin", center);
|
||||||
|
|
||||||
|
await drawTargetsInCircle(true);
|
||||||
|
|
||||||
|
// insert intro elements into document flow
|
||||||
|
intro1.style.display = "inline";
|
||||||
|
intro2.style.display = "inline";
|
||||||
|
|
||||||
|
// reveal intro elements
|
||||||
|
intro1.style.opacity = "100";
|
||||||
|
await sleep(500);
|
||||||
|
intro2.style.opacity = "100";
|
||||||
|
await sleep(1500);
|
||||||
|
|
||||||
|
intro1.classList.add("fade");
|
||||||
|
intro2.classList.add("fade");
|
||||||
|
|
||||||
|
intro1.style.opacity = "0";
|
||||||
|
intro2.style.opacity = "0";
|
||||||
|
|
||||||
|
await sleep(1000);
|
||||||
|
|
||||||
|
intro1.style.display = "none";
|
||||||
|
intro2.style.display = "none";
|
||||||
|
|
||||||
|
window.addEventListener("resize", handleResize);
|
||||||
|
|
||||||
|
document.getElementById("game-modes").style.display = "inline";
|
||||||
|
await sleep(500);
|
||||||
|
document.getElementById("game-modes").style.opacity = "100";
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleNormalMode(e) {
|
||||||
|
center.addEventListener("mouseover", handleHoverStart);
|
||||||
|
center.addEventListener("mouseleave", handleHoverEnd);
|
||||||
|
|
||||||
|
// instructions.style.display = "inline";
|
||||||
|
// instructions.style.opacity = "100";
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleHoverStart(e) {
|
||||||
|
e.target.style.backgroundColor = "green";
|
||||||
|
if (currentRound == 0) return;
|
||||||
|
|
||||||
|
hovering = true;
|
||||||
|
hoverCount++;
|
||||||
|
|
||||||
|
frameElement.replaceChildren();
|
||||||
|
|
||||||
|
intro1.style.display = "none";
|
||||||
|
intro2.style.display = "none";
|
||||||
|
instructions.style.display = "none";
|
||||||
|
|
||||||
|
// if (infinityMode)
|
||||||
|
|
||||||
|
if (currentRound == 0) { startRoundOne(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
async function startRoundOne() {
|
||||||
|
if (!await startCountdown(hoverCount)) {
|
||||||
|
// if user canceled hover, don't continue round
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log('success');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function startCountdown(hoverNumber) {
|
||||||
|
instructions.style.display = "none";
|
||||||
|
|
||||||
|
countingDown = true;
|
||||||
|
await sleep(1000);
|
||||||
|
|
||||||
|
one.style.opacity = "0";
|
||||||
|
two.style.opacity = "0";
|
||||||
|
three.style.opacity = "0";
|
||||||
|
|
||||||
|
// this check prevents countdown from continuing if user removes / reapplies hover while we're sleeping
|
||||||
|
if (!hovering || hoverNumber != hoverCount) return false;
|
||||||
|
one.style.display = "inline";
|
||||||
|
two.style.display = "inline";
|
||||||
|
three.style.display = "inline";
|
||||||
|
|
||||||
|
three.style.opacity = "100";
|
||||||
|
await sleep(1000);
|
||||||
|
|
||||||
|
two.style.opacity = "100";
|
||||||
|
await sleep(1000);
|
||||||
|
|
||||||
|
one.style.opacity = "100";
|
||||||
|
await sleep(1000);
|
||||||
|
|
||||||
|
if (!hovering || hoverNumber != hoverCount) return false;
|
||||||
|
one.style.display = "none";
|
||||||
|
two.style.display = "none";
|
||||||
|
three.style.display = "none";
|
||||||
|
|
||||||
|
one.style.opacity = "0";
|
||||||
|
two.style.opacity = "0";
|
||||||
|
three.style.opacity = "0";
|
||||||
|
|
||||||
|
draw.style.display = "inline";
|
||||||
|
draw.style.opacity = "100";
|
||||||
|
|
||||||
|
countingDown = false;
|
||||||
|
setTimeout(() => {draw.style.display = "none"; draw.style.opacity = "0"; }, 1000);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleHoverEnd(e) {
|
||||||
|
hovering = false;
|
||||||
|
e.target.style.backgroundColor = "red";
|
||||||
|
|
||||||
|
if (countingDown) {
|
||||||
|
one.style.display = "none";
|
||||||
|
two.style.display = "none";
|
||||||
|
three.style.display = "none";
|
||||||
|
draw.style.display = "none";
|
||||||
|
|
||||||
|
one.style.opacity = "0";
|
||||||
|
two.style.opacity = "0";
|
||||||
|
three.style.opacity = "0";
|
||||||
|
|
||||||
|
draw.style.opacity = "0";
|
||||||
|
|
||||||
|
instructions.style.display = "inline";
|
||||||
|
countingDown = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleResize(event) {
|
||||||
|
frameElement.replaceChildren();
|
||||||
|
setParameters();
|
||||||
|
|
||||||
|
document.getElementById("center").remove();
|
||||||
|
center = generateTarget(xFrameAdjustment, yFrameAdjustment);
|
||||||
|
center.id = "center";
|
||||||
|
document.body.insertAdjacentElement("afterbegin", center);
|
||||||
|
center.addEventListener("mouseover", handleHoverStart);
|
||||||
|
center.addEventListener("mouseleave", handleHoverEnd);
|
||||||
|
|
||||||
|
if (currentRound == 0) {
|
||||||
|
drawTargetsInCircle(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('page: ' + pageWidth + ' x ' + pageHeight);
|
||||||
|
console.log('frame: ' + frameWidth + ' x ' + frameHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function drawTargetsInCircle(animate) {
|
||||||
|
let r, x, y;
|
||||||
let radians;
|
let radians;
|
||||||
|
let target;
|
||||||
let ratio = frameHeight / frameWidth;
|
for (let i = 0; i < 360; i = i + 2) {
|
||||||
|
r = (frameWidth / 2) - (targetWidth / 2) - (gameBorderWidth * 2);
|
||||||
let xFrameAdjustment = ((pageWidth - frameWidth) * 2) - (targetWidth / 2);
|
// r = (frameWidth / 2) - (targetWidth / 2);
|
||||||
let yFrameAdjustment = (frameHeight / 2) - (targetWidth / 2);
|
|
||||||
|
|
||||||
generateTarget(xFrameAdjustment, yFrameAdjustment)
|
|
||||||
|
|
||||||
for (let i = 0; i < 360; i++) {
|
|
||||||
r = (frameWidth / 2) - (targetWidth / 2);
|
|
||||||
|
|
||||||
radians = degreesToRadians(i);
|
radians = degreesToRadians(i);
|
||||||
|
|
||||||
x = ((r * 1 * Math.cos(radians)) + xFrameAdjustment);
|
x = (r * 1 * Math.cos(radians)) + xFrameAdjustment;
|
||||||
y = ((r * ratio * Math.sin(radians)) + yFrameAdjustment);
|
y = (r * ratio * Math.sin(radians)) + yFrameAdjustment;
|
||||||
console.log(x + ', ' + y);
|
|
||||||
|
|
||||||
generateTarget(x, y);
|
// console.log(x + ', ' + y);
|
||||||
|
// console.log(ratio);
|
||||||
|
// console.log(xFrameAdjustment + 'adj, ' + yFrameAdjustment + 'adj');
|
||||||
|
|
||||||
|
target = generateTarget(x, y);
|
||||||
|
document.getElementById("frame").insertAdjacentElement("afterbegin", target);
|
||||||
|
|
||||||
|
if (animate) await sleep(15);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// init logs:
|
function sleep(ms) {
|
||||||
console.log('page: ' + pageWidth + ' x ' + pageHeight);
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
console.log('frame: ' + frameWidth + ' x ' + frameHeight);
|
}
|
||||||
|
|
||||||
|
function degreesToRadians(degrees) {
|
||||||
|
return degrees * (Math.PI / 180)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function degreesToRadians(degrees) {
|
function generateTarget(x, y) {
|
||||||
return degrees * (Math.PI / 180)
|
const target = document.createElement("div");
|
||||||
}
|
target.classList.add("target");
|
||||||
|
target.style.top = y +'px';
|
||||||
|
target.style.left = x + 'px';
|
||||||
|
// console.log(target);
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function generateTarget(x, y) {
|
function getRandomInt(min, max) {
|
||||||
const target = document.createElement("div");
|
const minCeiled = Math.ceil(min);
|
||||||
target.id = "target";
|
const maxFloored = Math.floor(max);
|
||||||
target.style.top = y +'px';
|
return Math.floor(Math.random() * (maxFloored - minCeiled) + minCeiled); // The maximum is exclusive and the minimum is inclusive
|
||||||
target.style.left = x + 'px';
|
}
|
||||||
// console.log(target);
|
|
||||||
document.getElementById("frame").insertAdjacentElement("afterbegin", target);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function getRandomInt(min, max) {
|
|
||||||
const minCeiled = Math.ceil(min);
|
|
||||||
const maxFloored = Math.floor(max);
|
|
||||||
return Math.floor(Math.random() * (maxFloored - minCeiled) + minCeiled); // The maximum is exclusive and the minimum is inclusive
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user