forked from HoloTech/twitch-subathon-timer
Compare commits
17 Commits
master
...
v2-Prototy
| Author | SHA1 | Date | |
|---|---|---|---|
| 1a09ea3d80 | |||
| ff7c48dab4 | |||
| 6c2b897522 | |||
| 192f3c0eb1 | |||
| 8e95f378d7 | |||
| f2fc02ff7e | |||
| 75cdfcf09a | |||
| 11ca4470fe | |||
| 2d9e320d42 | |||
| da6ae0b9c3 | |||
| 960c037362 | |||
| 1f49e82035 | |||
| 31bc26c72f | |||
| 45502c00e4 | |||
| 9544579ebe | |||
| f8bce7a50c | |||
| b1fb0299d2 |
151
index.html
151
index.html
@@ -13,55 +13,118 @@
|
|||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
<div class='contentContainer'>
|
<div class='contentContainer'>
|
||||||
<img id='MainHeart' src='src/youve_got_mail_whiteheart.png'>
|
|
||||||
<div class='infoGroup'>
|
<img class='mainHeart' src='src/youvegotmail.webp'>
|
||||||
<div class='infoBox' id='InfoBox1'>
|
|
||||||
<h1 id='Timer'>
|
<div class='infoWrap'>
|
||||||
24:16
|
<div class='infoGroup'>
|
||||||
</h1>
|
|
||||||
<p id='TimerInfo'>
|
<div class='infoBox' id='InfoBox3'>
|
||||||
!subathon for details
|
<p id='TopUsers'>
|
||||||
</p>
|
Leaderboard:
|
||||||
</div>
|
|
||||||
<div class='infoBox' id='InfoBox2'>
|
|
||||||
<h2 id='GoalLabel'>
|
|
||||||
Current Goal:
|
|
||||||
</h2>
|
|
||||||
<h3 id='GoalName'>
|
|
||||||
Discord Watch Party + Puzzles
|
|
||||||
</h3>
|
|
||||||
<p id='GoalProgress'>
|
|
||||||
1524/3000 Points
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class='infoBox' id='InfoBox3'>
|
|
||||||
<h2 id='TopUsers'>
|
|
||||||
Top 3 Gifters:
|
|
||||||
</h2>
|
|
||||||
<div class='giftUserRow' id='GiftUserRow1'>
|
|
||||||
<p class='giftUserNum' id='GiftUserNum1'>
|
|
||||||
1.
|
|
||||||
</p>
|
</p>
|
||||||
<p class='giftUserName'id='GiftUserName1'>
|
|
||||||
Usernamethatisverylong
|
<div class='rightFadeWrap' id='RightFadeWrapInfoBox3'>
|
||||||
|
<div class='giftUserWrap' id='GiftUserWrap'>
|
||||||
|
<div class='giftUserRow' id='GiftUserRow1'>
|
||||||
|
<p class='giftUserNum' id='GiftUserNum1'>
|
||||||
|
1
|
||||||
|
</p>
|
||||||
|
<div class='scrollWrap' id='ScrollWrapName1'>
|
||||||
|
<div class='scrollWrapW' id='ScrollWrapNameW1'>
|
||||||
|
<p class='giftUserName'id='GiftUserName1'>
|
||||||
|
Usernamethatisverylong
|
||||||
|
</p>
|
||||||
|
<p class='giftUserNameDupe'id='GiftUserNameDupe1'>
|
||||||
|
Usernamethatisverylong
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class='giftUserScore' id='GiftUserScore1'>
|
||||||
|
0000
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class='giftUserRow' id='GiftUserRow2'>
|
||||||
|
<p class='giftUserNum' id='GiftUserNum2'>
|
||||||
|
2
|
||||||
|
</p>
|
||||||
|
<div class='scrollWrap' id='ScrollWrapName2'>
|
||||||
|
<div class='scrollWrapW' id='ScrollWrapNameW2'>
|
||||||
|
<p class='giftUserName'id='GiftUserName2'>
|
||||||
|
Usernamethatisverylong
|
||||||
|
</p>
|
||||||
|
<p class='giftUserNameDupe'id='GiftUserNameDupe2'>
|
||||||
|
Usernamethatisverylong
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class='giftUserScore' id='GiftUserScore2'>
|
||||||
|
25
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class='giftUserRow' id='GiftUserRow3'>
|
||||||
|
<p class='giftUserNum' id='GiftUserNum3'>
|
||||||
|
3
|
||||||
|
</p>
|
||||||
|
<div class='scrollWrap' id='ScrollWrapName3'>
|
||||||
|
<div class='scrollWrapW' id='ScrollWrapNameW3'>
|
||||||
|
<p class='giftUserName'id='GiftUserName3'>
|
||||||
|
Usernamethatisverylong
|
||||||
|
</p>
|
||||||
|
<p class='giftUserNameDupe'id='GiftUserNameDupe3'>
|
||||||
|
Usernamethatisverylong
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class='giftUserScore' id='GiftUserScore3'>
|
||||||
|
1
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<img class='mainHeart' id='SecondHeart' src='src/youvegotmail.webp'>
|
||||||
|
|
||||||
|
<div class='infoBox' id='InfoBox1'>
|
||||||
|
<h1 id='Timer'>
|
||||||
|
00:00
|
||||||
|
</h1>
|
||||||
|
<p id='TimerInfo'>
|
||||||
|
!subathon for details
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class='giftUserRow' id='GiftUserRow2'>
|
|
||||||
<p class='giftUserNum' id='GiftUserNum2'>
|
<div class='infoBox' id='InfoBox2'>
|
||||||
2.
|
<p id='GoalLabel'>
|
||||||
</p>
|
Next Goal:
|
||||||
<p class='giftUserName'id='GiftUserName2'>
|
|
||||||
Usernamethatisverylong
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class='giftUserRow' id='GiftUserRow3'>
|
|
||||||
<p class='giftUserNum' id='GiftUserNum3'>
|
|
||||||
3.
|
|
||||||
</p>
|
|
||||||
<p class='giftUserName'id='GiftUserName3'>
|
|
||||||
Usernamethatisverylong
|
|
||||||
</p>
|
</p>
|
||||||
|
<div class='rightFadeWrap' id='RightFadeWrapInfoBox2'>
|
||||||
|
<div class='scrollWrap' id='ScrollWrapGoal'>
|
||||||
|
<div class='scrollWrapW' id='ScrollWrapGoalW'>
|
||||||
|
<p id='GoalName'>
|
||||||
|
Discord Watch Party + Puzzles
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p id='GoalNameDupe'>
|
||||||
|
Discord Watch Party + Puzzles
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id='GoalProgressWrap'>
|
||||||
|
<div id='GoalProgressBar'>
|
||||||
|
<p id='GoalProgressTransparent' style='color: transparent;'>
|
||||||
|
1234/5678
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<p id='GoalProgress'>
|
||||||
|
1234/5678
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
BIN
src/youvegotmail.webp
Normal file
BIN
src/youvegotmail.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 110 KiB |
290
timer.css
290
timer.css
@@ -14,60 +14,63 @@ html, body {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
font-family: 'Inter', sans-serif;
|
font-family: 'Inter', sans-serif;
|
||||||
background-color: var(--background-color);
|
background-color: var(--background-color);
|
||||||
|
background-color: transparent;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
main {
|
||||||
font-family: "VT323", monospace;
|
font-family: "Silkscreen", sans-serif;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-size: 1em;
|
|
||||||
color: #EA4045;
|
color: #EA4045;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 68cqh;
|
font-size: 3.6em;
|
||||||
color: #404145;
|
color: #404145;
|
||||||
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 40cqh;
|
font-size: 1.4em;
|
||||||
color: #404145;
|
color: #404145;
|
||||||
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
font-family: "Silkscreen", sans-serif;
|
|
||||||
font-weight: 400;
|
|
||||||
font-style: normal;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 16cqh;
|
font-size: 1em;
|
||||||
color: #404145;
|
color: #404145;
|
||||||
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: "Silkscreen", sans-serif;
|
font-size: 1.3em;
|
||||||
font-weight: 400;
|
|
||||||
font-style: normal;
|
|
||||||
font-size: 20cqh;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.contentContainer {
|
.contentContainer {
|
||||||
height: fit-content;
|
height: fit-content;
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
position: relative;
|
position: relative;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#MainHeart {
|
.mainHeart {
|
||||||
max-height: 100vh;
|
max-height: 100vh;
|
||||||
max-width: 100vw;
|
max-width: 72vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
.infoGroup {
|
#SecondHeart {
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.infoWrap {
|
||||||
container-type: size;
|
container-type: size;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -76,105 +79,256 @@ p {
|
|||||||
top: 0px;
|
top: 0px;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 56% 34% 1fr;
|
grid-template-columns: 56% 34% 1fr;
|
||||||
grid-template-rows: 11% 28% 16% 16% 1fr;
|
grid-template-rows: 11% 1fr 29%;
|
||||||
place-items: center;
|
place-items: center;
|
||||||
|
text-wrap: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.infoBox {
|
.infoGroup {
|
||||||
container-type: size;
|
height: 100%;
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(1, 1fr);
|
|
||||||
grid-auto-rows: auto;
|
|
||||||
place-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#InfoBox1 {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
grid-column-start: 2;
|
grid-column-start: 2;
|
||||||
grid-column-end: 2;
|
grid-column-end: 2;
|
||||||
grid-row-start: 2;
|
grid-row-start: 2;
|
||||||
grid-row-end: 2;
|
grid-row-end: 2;
|
||||||
justify-self: left;
|
}
|
||||||
align-self: stretch;
|
|
||||||
transform: translate(-8%, 5%);
|
.infoBox {
|
||||||
|
height: auto;
|
||||||
|
width: 100%;
|
||||||
|
font-size: 4cqh;
|
||||||
|
}
|
||||||
|
|
||||||
|
#InfoBox1 {
|
||||||
|
transform: translate(-2%, 0%);
|
||||||
|
margin-top: -50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
#InfoBox2 {
|
#InfoBox2 {
|
||||||
display: grid;
|
/* -- !!DO NOT REMOVE!! --
|
||||||
width: 100%;
|
Removing this transform kills the goal label and I do not know why
|
||||||
grid-column-start: 2;
|
*/
|
||||||
grid-column-end: 2;
|
transform: translate(0%, 0%);
|
||||||
grid-row-start: 3;
|
|
||||||
grid-row-end: 3;
|
|
||||||
justify-self: left;
|
|
||||||
align-self: stretch;
|
|
||||||
transform: translate(6%, -24%);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#InfoBox3 {
|
#InfoBox3 {
|
||||||
width: 100%;
|
width: 142%;
|
||||||
grid-column-start: 2;
|
position: relative;
|
||||||
grid-column-end: 2;
|
transform: translate(65%, 10%) scale(1, 1);
|
||||||
grid-row-start: 4;
|
border-radius: 3cqh;
|
||||||
grid-row-end: 4;
|
border: .4cqh solid;
|
||||||
grid-template-columns: 1fr;
|
border-color: #00A0F3;
|
||||||
grid-template-rows: 1fr 23% 23% 23%;
|
background-color: white;
|
||||||
justify-self: left;
|
padding: .4ch 0 .4ch 0;
|
||||||
align-self: stretch;
|
}
|
||||||
transform: translate(0%, -32%);
|
|
||||||
|
#Timer {
|
||||||
|
/*
|
||||||
|
margin-top: 10%;
|
||||||
|
margin-bottom: 2%;
|
||||||
|
*/
|
||||||
|
transform: translate(0%, 0%) scale(.95, 1.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#TimerInfo {
|
#TimerInfo {
|
||||||
transform: translate(0%, -175%);
|
transform: translate(0%, -60%);
|
||||||
font-size: 9cqh;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#GoalLabel {
|
#GoalLabel {
|
||||||
transform: translate(0%, -20%);
|
color: #404145;
|
||||||
}
|
}
|
||||||
|
|
||||||
#GoalName {
|
#GoalName {
|
||||||
width: 85%;
|
width: fit-content;
|
||||||
transform: translate(10%, -110%);
|
position: relative;
|
||||||
color: #32B993;
|
color: #32B993;
|
||||||
text-wrap: nowrap;
|
text-wrap: nowrap;
|
||||||
|
display: inline-block;
|
||||||
|
padding-right: 4%;
|
||||||
|
transform: translate(.5ch, 0%);
|
||||||
|
/* --- animation-duration = JS VAR --- */
|
||||||
|
}
|
||||||
|
|
||||||
|
#GoalNameDupe {
|
||||||
|
width: fit-content;
|
||||||
|
position: relative;
|
||||||
|
color: #32B993;
|
||||||
|
text-wrap: nowrap;
|
||||||
|
padding-right: 4%;
|
||||||
|
transform: translate(.5ch, 0%);
|
||||||
|
/* --- animation-duration = JS VAR --- */
|
||||||
|
}
|
||||||
|
|
||||||
|
#GoalProgressWrap {
|
||||||
|
width: fit-content;
|
||||||
|
padding-left: .8cqh;
|
||||||
|
padding-right: .8cqh;
|
||||||
|
border-radius: 3cqh;
|
||||||
|
border: .4cqh solid;
|
||||||
|
border-color: #404145;
|
||||||
|
margin: .4ch auto 0 auto;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
mask-image: linear-gradient(to right, black 70%, transparent 100%);
|
}
|
||||||
|
|
||||||
|
#GoalProgressBar {
|
||||||
|
width: 110%;
|
||||||
|
background-color: #FC98B3;
|
||||||
|
transform: translate(-5%, 0%) scale(1, 1.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
#GoalProgress {
|
#GoalProgress {
|
||||||
transform: translate(0%, -75%);
|
transform: translate(0%, -8%) scale(1);
|
||||||
border-radius: 8cqh;
|
text-align: center;
|
||||||
border: 2cqh solid;
|
margin-top: -19%;
|
||||||
border-color: #404145;
|
color: #404145;
|
||||||
|
}
|
||||||
|
|
||||||
|
#TopUsers {
|
||||||
|
margin-bottom: 2%;
|
||||||
|
font-weight: normal;
|
||||||
|
color: #404145;
|
||||||
|
}
|
||||||
|
|
||||||
|
.giftUserWrap {
|
||||||
|
transform: translate(9%, -8%) scale(1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.giftUserRow {
|
.giftUserRow {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 10% 1fr;
|
grid-template-columns: 2ch 14ch 5ch;
|
||||||
grid-template-rows: 1fr;
|
grid-template-rows: 1fr;
|
||||||
text-wrap: nowrap;
|
text-wrap: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-align: left;
|
text-align: center;
|
||||||
justify-self: left;
|
}
|
||||||
transform: translate(18%, 0%);
|
|
||||||
|
.giftUserNum {
|
||||||
|
border-right: 1.5px solid #00A0F3;
|
||||||
|
border-image: linear-gradient(to top,
|
||||||
|
transparent 0%,
|
||||||
|
transparent 5%,
|
||||||
|
#00A0F3 35%,
|
||||||
|
#00A0F3 65%,
|
||||||
|
transparent 95%) 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.giftUserScore {
|
||||||
|
border-left: 1.5px solid #00A0F3;
|
||||||
|
border-image: linear-gradient(to top,
|
||||||
|
transparent 0%,
|
||||||
|
transparent 5%,
|
||||||
|
#00A0F3 40%,
|
||||||
|
#00A0F3 60%,
|
||||||
|
transparent 95%) 1;
|
||||||
|
text-align: right;
|
||||||
|
padding-right: .25ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
.giftUserName {
|
.giftUserName {
|
||||||
|
width: fit-content;
|
||||||
margin-left: 0%;
|
margin-left: 0%;
|
||||||
|
position: relative;
|
||||||
color: #32B993;
|
color: #32B993;
|
||||||
|
text-align: left;
|
||||||
|
display: inline-block;
|
||||||
|
padding-right: 4%;
|
||||||
|
transform: translate(.5ch, 0%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.giftUserNameDupe {
|
||||||
|
width: fit-content;
|
||||||
|
margin-left: 0%;
|
||||||
|
position: relative;
|
||||||
|
color: #32B993;
|
||||||
|
text-align: left;
|
||||||
|
padding-right: 4%;
|
||||||
|
transform: translate(.5ch, 0%);
|
||||||
}
|
}
|
||||||
|
|
||||||
#GiftUserName1 {
|
#GiftUserName1 {
|
||||||
width: 54%;
|
/* --- animation-duration = JS VAR --- */
|
||||||
mask-image: linear-gradient(to right, black 70%, transparent 100%);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#GiftUserName2 {
|
#GiftUserName2 {
|
||||||
width: 46%;
|
/* --- animation-duration = JS VAR --- */
|
||||||
mask-image: linear-gradient(to right, black 70%, transparent 100%);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#GiftUserName3 {
|
#GiftUserName3 {
|
||||||
width: 38%;
|
/* --- animation-duration = JS VAR --- */
|
||||||
mask-image: linear-gradient(to right, black 70%, transparent 100%);
|
}
|
||||||
|
|
||||||
|
#GiftUserNameDupe1 {
|
||||||
|
/* --- animation-duration = JS VAR --- */
|
||||||
|
}
|
||||||
|
|
||||||
|
#GiftUserNameDupe2 {
|
||||||
|
/* --- animation-duration = JS VAR --- */
|
||||||
|
}
|
||||||
|
|
||||||
|
#GiftUserNameDupe3 {
|
||||||
|
/* --- animation-duration = JS VAR --- */
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollWrap {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rightFadeWrap {
|
||||||
|
/*
|
||||||
|
mask-image: linear-gradient(to right, black 75%, transparent 90%);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
#RightFadeWrapInfoBox2 {
|
||||||
|
width: 90%;
|
||||||
|
border-left: 1.5px solid #00A0F3;
|
||||||
|
border-right: 1.5px solid #00A0F3;
|
||||||
|
border-image: linear-gradient(to top,
|
||||||
|
transparent 0%,
|
||||||
|
transparent 5%,
|
||||||
|
#00A0F3 40%,
|
||||||
|
#00A0F3 60%,
|
||||||
|
transparent 95%) 1;
|
||||||
|
transform: translate(1ch, 0%) scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fadeLeft {
|
||||||
|
mask-image: linear-gradient(to right,
|
||||||
|
transparent 0%,
|
||||||
|
black 1ch,
|
||||||
|
black calc(100% - 2ch),
|
||||||
|
transparent 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ScrollWrapGoal {
|
||||||
|
/*
|
||||||
|
width: 90%;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollWrapName {
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollWrapW {
|
||||||
|
width: fit-content;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ScrollWrapGoalW {
|
||||||
|
}
|
||||||
|
|
||||||
|
.hide {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollAnim {
|
||||||
|
animation: myScroll linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes myScroll {
|
||||||
|
0% {left: 0%; top: 0%;}
|
||||||
|
42% {left: 0%; top: 0%;}
|
||||||
|
100% {left: -54%; top: 0%;}
|
||||||
}
|
}
|
||||||
181
timer.js
181
timer.js
@@ -8,6 +8,7 @@ class Timer {
|
|||||||
constructor(renderer, timer_data) {
|
constructor(renderer, timer_data) {
|
||||||
this.renderer = renderer;
|
this.renderer = renderer;
|
||||||
this.destroying = false;
|
this.destroying = false;
|
||||||
|
this.ended = false;
|
||||||
|
|
||||||
this.update_from_data(timer_data);
|
this.update_from_data(timer_data);
|
||||||
}
|
}
|
||||||
@@ -32,13 +33,34 @@ class Timer {
|
|||||||
this.leaderboard = timer_data.leaderboard;
|
this.leaderboard = timer_data.leaderboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_ended() {
|
||||||
|
if (!this.ended && this.end_at < new Date()) {
|
||||||
|
this.ended = true;
|
||||||
|
this.renderer.finale();
|
||||||
|
}
|
||||||
|
return this.ended;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_ended() {
|
||||||
|
if (!this.ended && this.end_at < new Date()) {
|
||||||
|
this.ended = true;
|
||||||
|
this.renderer.finale();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render_time() {
|
render_time() {
|
||||||
|
if (this.check_ended()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.renderer.render_time(
|
this.renderer.render_time(
|
||||||
Math.floor((this.end_at - new Date()) / 1000)
|
Math.floor((this.end_at - new Date()) / 1000)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
if (this.ended) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Render goal
|
// Render goal
|
||||||
if (this.next_goal != null) {
|
if (this.next_goal != null) {
|
||||||
this.renderer.render_current_goal(
|
this.renderer.render_current_goal(
|
||||||
@@ -46,21 +68,26 @@ class Timer {
|
|||||||
this.total_contribution,
|
this.total_contribution,
|
||||||
this.next_goal.required,
|
this.next_goal.required,
|
||||||
);
|
);
|
||||||
|
this.renderer.animate();
|
||||||
} else if (this.last_goal != null) {
|
} else if (this.last_goal != null) {
|
||||||
this.renderer.render_current_goal(
|
this.renderer.render_current_goal(
|
||||||
this.last_goal.name,
|
this.last_goal.name,
|
||||||
this.total_contribution,
|
this.total_contribution,
|
||||||
this.last_goal.required,
|
this.last_goal.required,
|
||||||
);
|
);
|
||||||
|
this.renderer.animate();
|
||||||
} else {
|
} else {
|
||||||
this.renderer.clear_current_goal();
|
this.renderer.clear_current_goal();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render leaderboard
|
// Render leaderboard
|
||||||
this.renderer.render_users(this.leaderboard);
|
this.renderer.render_users(this.leaderboard);
|
||||||
|
this.renderer.animate();
|
||||||
|
|
||||||
// Render timer
|
// Render timer
|
||||||
this.render_time();
|
this.render_time();
|
||||||
|
|
||||||
|
this.set_ended();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,7 +101,6 @@ class Timer {
|
|||||||
setTimeout(this.tick.bind(this), 1000);
|
setTimeout(this.tick.bind(this), 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,41 +114,127 @@ class TimerRenderer {
|
|||||||
|
|
||||||
// Name of the goal to display
|
// Name of the goal to display
|
||||||
this.goal_name = document.getElementById("GoalName")
|
this.goal_name = document.getElementById("GoalName")
|
||||||
|
this.goal_namedupe = document.getElementById("GoalNameDupe")
|
||||||
|
|
||||||
// 1524/3000 Points
|
// 1524/3000 Points
|
||||||
this.goal_progress = document.getElementById("GoalProgress")
|
this.goal_progress = document.getElementById("GoalProgress")
|
||||||
|
this.goal_bar = document.getElementById("GoalProgressBar")
|
||||||
|
|
||||||
// Top 3 Gifters
|
// Top 3 Gifters
|
||||||
this.topusers_label = document.getElementById("TopUsers")
|
this.topusers_label = document.getElementById("TopUsers")
|
||||||
|
|
||||||
// Leaderboard items
|
// Leaderboard items
|
||||||
// 1. (or points?)
|
// 1. (or points?) (1 as in 1st place, static)
|
||||||
this.topusers_user1_num = document.getElementById("GiftUserNum1")
|
this.topusers_user1_num = document.getElementById("GiftUserNum1")
|
||||||
// Name of user 1
|
// Name of user 1
|
||||||
this.topusers_user1_name = document.getElementById("GiftUserName1")
|
this.topusers_user1_name = document.getElementById("GiftUserName1")
|
||||||
|
this.topusers_userdupe1_name = document.getElementById("GiftUserNameDupe1")
|
||||||
|
this.topusers_user1_score = document.getElementById("GiftUserScore1")
|
||||||
this.topusers_user2_num = document.getElementById("GiftUserNum2")
|
this.topusers_user2_num = document.getElementById("GiftUserNum2")
|
||||||
this.topusers_user2_name = document.getElementById("GiftUserName2")
|
this.topusers_user2_name = document.getElementById("GiftUserName2")
|
||||||
|
this.topusers_userdupe2_name = document.getElementById("GiftUserNameDupe2")
|
||||||
|
this.topusers_user2_score = document.getElementById("GiftUserScore2")
|
||||||
this.topusers_user3_num = document.getElementById("GiftUserNum3")
|
this.topusers_user3_num = document.getElementById("GiftUserNum3")
|
||||||
this.topusers_user3_name = document.getElementById("GiftUserName3")
|
this.topusers_user3_name = document.getElementById("GiftUserName3")
|
||||||
|
this.topusers_userdupe3_name = document.getElementById("GiftUserNameDupe3")
|
||||||
|
this.topusers_user3_score = document.getElementById("GiftUserScore3")
|
||||||
|
|
||||||
|
// -- Animation --
|
||||||
|
// Left-fade wrappers
|
||||||
|
this.scrollwraps = document.getElementsByClassName("scrollWrap")
|
||||||
|
// Parent wrappers
|
||||||
|
this.scrollboxes = [document.getElementById("GiftUserRow1"),
|
||||||
|
document.getElementById("GiftUserRow2"),
|
||||||
|
document.getElementById("GiftUserRow3"),
|
||||||
|
document.getElementById("ScrollWrapGoal")]
|
||||||
|
// Leaderboard names
|
||||||
|
this.userboxes = [this.topusers_user1_name, this.topusers_user2_name, this.topusers_user3_name]
|
||||||
|
this.userdupeboxes = [this.topusers_userdupe1_name, this.topusers_userdupe2_name, this.topusers_userdupe3_name]
|
||||||
|
|
||||||
|
// Thank you!
|
||||||
|
this.thankyou = "Thank you! The subathon has now ended, thank you so much for contributions and viewership to celebrate!"
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Toggles animation if text overflows container and adjusts speed for uniform movement --
|
||||||
|
animate() {
|
||||||
|
|
||||||
|
for (let i = 0; i < this.scrollboxes.length; i++) {
|
||||||
|
// Check whether the itteration is a username or goal
|
||||||
|
if (this.scrollboxes[i].id == 'ScrollWrapGoal') {
|
||||||
|
|
||||||
|
// Check if element text overflows
|
||||||
|
if (this.goal_name.getBoundingClientRect().width > (this.scrollboxes[i].getBoundingClientRect().width)) {
|
||||||
|
// Toggle animation
|
||||||
|
this.goal_name.classList.add("scrollAnim");
|
||||||
|
this.goal_namedupe.classList.add("scrollAnim");
|
||||||
|
this.goal_namedupe.style.display = 'inline-block';
|
||||||
|
this.scrollwraps[i].classList.add("fadeLeft");
|
||||||
|
// Set animation speed
|
||||||
|
this.goal_name.style.animationDuration = `${this.goal_name.getBoundingClientRect().width / 40}s`;
|
||||||
|
this.goal_namedupe.style.animationDuration = `${this.goal_name.getBoundingClientRect().width / 40}s`;
|
||||||
|
} else {
|
||||||
|
// Toggle animation
|
||||||
|
this.goal_name.classList.remove("scrollAnim");
|
||||||
|
this.goal_namedupe.classList.remove("scrollAnim");
|
||||||
|
this.goal_namedupe.style.display = 'none';
|
||||||
|
this.scrollwraps[i].classList.remove("fadeLeft");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Check if element text overflows
|
||||||
|
if (this.userboxes[i].getBoundingClientRect().width > (this.scrollboxes[i].getBoundingClientRect().width * .65)) {
|
||||||
|
// Toggle animation
|
||||||
|
this.userboxes[i].classList.add("scrollAnim");
|
||||||
|
this.userdupeboxes[i].classList.add("scrollAnim");
|
||||||
|
this.userdupeboxes[i].style.display = 'inline-block';
|
||||||
|
this.scrollwraps[i].classList.add("fadeLeft");
|
||||||
|
// Set animation speed
|
||||||
|
this.userboxes[i].style.animationDuration = `${this.userboxes[i].getBoundingClientRect().width / 40}s`;
|
||||||
|
this.userdupeboxes[i].style.animationDuration = `${this.userboxes[i].getBoundingClientRect().width / 40}s`;
|
||||||
|
} else {
|
||||||
|
// Toggle animation
|
||||||
|
this.userboxes[i].classList.remove("scrollAnim");
|
||||||
|
this.userdupeboxes[i].classList.remove("scrollAnim");
|
||||||
|
this.userdupeboxes[i].style.display = 'none';
|
||||||
|
this.scrollwraps[i].classList.remove("fadeLeft");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bring the display into a standard initial state.
|
* Bring the display into a standard initial state.
|
||||||
*/
|
*/
|
||||||
reset() {
|
reset() {
|
||||||
|
this.timer.textContent = "88:88";
|
||||||
|
this.goal_label.textContent = "Next Goal:";
|
||||||
|
this.goal_name.textContent = "Goal name for the subathon";
|
||||||
|
this.goal_namedupe.textContent = "Goal name for the subathon";
|
||||||
|
this.goal_progress.textContent = "1234/1234";
|
||||||
|
|
||||||
|
this.topusers_label.textContent = "Leaderboard:";
|
||||||
|
this.topusers_user1_num.textContent = "1";
|
||||||
|
this.topusers_user1_name.textContent = "Username1024";
|
||||||
|
this.topusers_userdupe1_name.textContent = "Username1024";
|
||||||
|
this.topusers_user1_score.textContent = "0000";
|
||||||
|
this.topusers_user2_num.textContent = "2";
|
||||||
|
this.topusers_user2_name.textContent = "User";
|
||||||
|
this.topusers_userdupe2_name.textContent = "User";
|
||||||
|
this.topusers_user2_score.textContent = "0000";
|
||||||
|
this.topusers_user3_num.textContent = "3";
|
||||||
|
this.topusers_user3_name.textContent = "Username_Very_Super_Long12";
|
||||||
|
this.topusers_userdupe3_name.textContent = "Username_Very_Super_Long12";
|
||||||
|
this.topusers_user3_score.textContent = "0000";
|
||||||
|
}
|
||||||
|
|
||||||
|
// End subathon, change timer color, and show thank you message
|
||||||
|
finale() {
|
||||||
this.timer.textContent = "00:00";
|
this.timer.textContent = "00:00";
|
||||||
this.goal_label.textContent = "Current Goal:";
|
this.timer.style.color = '#82C8B6';
|
||||||
this.goal_name.textContent = "Be awesome";
|
this.goal_label.textContent = "Completed!";
|
||||||
this.goal_progress.textContent = "00/00 Points";
|
this.goal_name.textContent = this.thankyou;
|
||||||
|
this.goal_namedupe.textContent = this.thankyou;
|
||||||
this.topusers_label.textContent = "Top 3 Gifters";
|
this.animate();
|
||||||
this.topusers_user1_num.textContent = "1.";
|
|
||||||
this.topusers_user1_name.textContent = "Anonymous";
|
|
||||||
this.topusers_user2_num.textContent = "2.";
|
|
||||||
this.topusers_user2_name.textContent = "Anonymous";
|
|
||||||
this.topusers_user3_num.textContent = "3.";
|
|
||||||
this.topusers_user3_name.textContent = "Anonymous";
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -165,9 +277,18 @@ class TimerRenderer {
|
|||||||
// Or after we accomplish all goals
|
// Or after we accomplish all goals
|
||||||
|
|
||||||
this.goal_name.textContent = name;
|
this.goal_name.textContent = name;
|
||||||
|
this.goal_namedupe.textContent = name;
|
||||||
|
//this.goal_name.style.animationDuration = `${this.goal_name.getBoundingClientRect().width / 50}s`;
|
||||||
|
|
||||||
// Bitwise OR done to convert floats to integers if needed
|
// Bitwise OR done to convert floats to integers if needed
|
||||||
this.goal_progress.textContent = String(current | 0) + '/' + String(required | 0) + ' Points'
|
this.goal_progress.textContent = String(current | 0) + '/' + String(required | 0)
|
||||||
|
|
||||||
|
// Update the progress bar
|
||||||
|
if (current / required > .02) {
|
||||||
|
this.goal_bar.style.maskImage = `linear-gradient(to right, #FC98B3 0%, #FC98B3 ${((current / required) - .02) * 100}%, transparent ${(current / required) * 100}%)`;
|
||||||
|
} else {
|
||||||
|
this.goal_bar.style.maskImage = `linear-gradient(to right, #FC98B3 0%, transparent .01%)`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -175,6 +296,7 @@ class TimerRenderer {
|
|||||||
*/
|
*/
|
||||||
clear_current_goal() {
|
clear_current_goal() {
|
||||||
this.goal_name.textContent = "";
|
this.goal_name.textContent = "";
|
||||||
|
//this.goal_namedupe.textContent = "";
|
||||||
this.goal_progress.textContent = "";
|
this.goal_progress.textContent = "";
|
||||||
this.goal_label.textContent = "";
|
this.goal_label.textContent = "";
|
||||||
}
|
}
|
||||||
@@ -189,27 +311,42 @@ class TimerRenderer {
|
|||||||
render_users(users) {
|
render_users(users) {
|
||||||
|
|
||||||
if (users.length >= 1) {
|
if (users.length >= 1) {
|
||||||
this.topusers_user1_num.textContent = "1.";
|
this.topusers_user1_num.textContent = "1";
|
||||||
this.topusers_user1_name.textContent = users[0].user_name;
|
this.topusers_user1_name.textContent = users[0].user_name;
|
||||||
|
this.topusers_userdupe1_name.textContent = users[0].user_name;
|
||||||
|
this.topusers_user1_score.textContent = Math.round(users[0].amount);
|
||||||
|
//this.topusers_user1_name.style.animationDuration = `${this.topusers_user1_name.getBoundingClientRect().width / 50}s`;
|
||||||
} else {
|
} else {
|
||||||
this.topusers_user1_num.textContent = "";
|
this.topusers_user1_num.textContent = "1";
|
||||||
this.topusers_user1_name.textContent = "";
|
this.topusers_user1_name.textContent = "";
|
||||||
|
this.topusers_userdupe1_name.textContent = "";
|
||||||
|
this.topusers_user1_score.textContent = "0000";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (users.length >= 2) {
|
if (users.length >= 2) {
|
||||||
this.topusers_user2_num.textContent = "2.";
|
this.topusers_user2_num.textContent = "2";
|
||||||
this.topusers_user2_name.textContent = users[1].user_name;
|
this.topusers_user2_name.textContent = users[1].user_name;
|
||||||
|
this.topusers_userdupe2_name.textContent = users[1].user_name;
|
||||||
|
this.topusers_user2_score.textContent = Math.round(users[1].amount);
|
||||||
|
//this.topusers_user2_name.style.animationDuration = `${this.topusers_user2_name.getBoundingClientRect().width / 50}s`;
|
||||||
} else {
|
} else {
|
||||||
this.topusers_user2_num.textContent = "";
|
this.topusers_user2_num.textContent = "2";
|
||||||
this.topusers_user2_name.textContent = "";
|
this.topusers_user2_name.textContent = "";
|
||||||
|
this.topusers_userdupe2_name.textContent = "";
|
||||||
|
this.topusers_user2_score.textContent = "0000";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (users.length >= 3) {
|
if (users.length >= 3) {
|
||||||
this.topusers_user3_num.textContent = "3.";
|
this.topusers_user3_num.textContent = "3";
|
||||||
this.topusers_user3_name.textContent = users[2].user_name;
|
this.topusers_user3_name.textContent = users[2].user_name;
|
||||||
|
this.topusers_userdupe3_name.textContent = users[2].user_name;
|
||||||
|
this.topusers_user3_score.textContent = Math.round(users[2].amount);
|
||||||
|
//this.topusers_user3_name.style.animationDuration = `${this.topusers_user3_name.getBoundingClientRect().width / 50}s`;
|
||||||
} else {
|
} else {
|
||||||
this.topusers_user3_num.textContent = "";
|
this.topusers_user3_num.textContent = "3";
|
||||||
this.topusers_user3_name.textContent = "";
|
this.topusers_user3_name.textContent = "";
|
||||||
|
this.topusers_userdupe3_name.textContent = "";
|
||||||
|
this.topusers_user3_score.textContent = "0000";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -320,6 +457,7 @@ function communicate(websocket) {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
renderer.reset();
|
renderer.reset();
|
||||||
|
renderer.animate();
|
||||||
};
|
};
|
||||||
|
|
||||||
websocket.onmessage = ({ data }) => {
|
websocket.onmessage = ({ data }) => {
|
||||||
@@ -345,6 +483,7 @@ function communicate(websocket) {
|
|||||||
timer = null;
|
timer = null;
|
||||||
}
|
}
|
||||||
renderer.reset();
|
renderer.reset();
|
||||||
|
renderer.animate();
|
||||||
case "endTimer":
|
case "endTimer":
|
||||||
if (timer != null) {
|
if (timer != null) {
|
||||||
timer.destroying = true;
|
timer.destroying = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user