Initial Release
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
body {
|
||||
margin: 32px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Layout */
|
||||
|
||||
div.layout-buttons {
|
||||
margin: 32px 0;
|
||||
}
|
||||
|
||||
div.layout-document {
|
||||
position: relative;
|
||||
width: 11in;
|
||||
height: 8.5in;
|
||||
border: 2px solid black;
|
||||
}
|
||||
|
||||
img.page-background {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
/* Certificate */
|
||||
|
||||
span {
|
||||
position: absolute;
|
||||
background-color: white;
|
||||
color: red;
|
||||
}
|
||||
|
||||
span#name {
|
||||
left: 3.75in;
|
||||
top: 3in;
|
||||
font-size: 2em;
|
||||
width: 3.5in;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
span#cheat {
|
||||
left: 3.95in;
|
||||
top: 1in;
|
||||
font-size: 3em;
|
||||
}
|
||||
|
||||
span#time {
|
||||
left: 6in;
|
||||
top: 4in;
|
||||
}
|
||||
|
||||
span#date {
|
||||
left: 4.8in;
|
||||
top: 3.67in;
|
||||
padding: 0 32px;
|
||||
}
|
||||
|
||||
/* Printing Fixup */
|
||||
@media print {
|
||||
@page {
|
||||
size: letter landscape;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.no-print {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
(() => {
|
||||
|
||||
// SUPER SOPHISTICATED ANTICHEAT //
|
||||
const search = new URLSearchParams(document.location.search)
|
||||
let field_name, field_time, field_cheat
|
||||
|
||||
if (localStorage.getItem("secret_picross_complete")) {
|
||||
// Normal Ending :3
|
||||
field_name = search.get("name")
|
||||
field_time = search.get("time")
|
||||
|
||||
} else {
|
||||
// Cheater Ending...
|
||||
alert("i know what you are...")
|
||||
field_name = "cheater mccheater pants"
|
||||
field_time = "whatever"
|
||||
field_cheat = "CHEATED"
|
||||
}
|
||||
|
||||
document.querySelector("span#date").textContent = new Date().toDateString()
|
||||
document.querySelector("span#time").textContent =field_time
|
||||
document.querySelector("span#name").textContent = field_name
|
||||
document.querySelector("span#cheat").textContent = field_cheat
|
||||
document.querySelector("div.layout-document").style.opacity = '1'
|
||||
|
||||
})()
|
||||
@@ -0,0 +1,110 @@
|
||||
:root {
|
||||
--transition-time: 200ms;
|
||||
--animation-time: 200ms;
|
||||
--color-background: #1d1e2e;
|
||||
--color-text-default: #f0f0f0;
|
||||
--color-text-hint: #d0d0d0;
|
||||
--color-disabled: #212335;
|
||||
--color-inactive: #2d2f47;
|
||||
--color-active: #a1a8ff;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--color-background);
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p,
|
||||
a {
|
||||
display: inline-block;
|
||||
color: var(--color-text-default);
|
||||
font-family: 'Poppins', sans-serif;
|
||||
font-size: 1em;
|
||||
font-weight: normal;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
border-radius: 8px;
|
||||
border: 2px solid var(--color-inactive);
|
||||
padding: 4px 8px;
|
||||
min-width: 120px;
|
||||
cursor: pointer;
|
||||
margin: 0 8px;
|
||||
}
|
||||
|
||||
a:hover,
|
||||
a:focus-visible {
|
||||
border-color: var(--color-active);
|
||||
}
|
||||
|
||||
.text-tip {
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
.text-hidden {
|
||||
color: var(--color-text-hint);
|
||||
}
|
||||
|
||||
/* Layout */
|
||||
|
||||
div.layout-container {
|
||||
margin: auto;
|
||||
width: fit-content;
|
||||
padding: 32px 16px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
div.layout-header {
|
||||
display: grid;
|
||||
text-align: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
div.picross-row {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
div.layout-content {
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
padding: 32px 0;
|
||||
justify-content: center;
|
||||
/* visually centered */
|
||||
margin-left: -32px;
|
||||
}
|
||||
|
||||
p.picross-hint {
|
||||
color: var(--color-text-hint);
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
button.picross-button {
|
||||
transition: var(--animation-time) ease-in-out background-color;
|
||||
background-color: var(--color-inactive);
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
button.state-active {
|
||||
background-color: var(--color-active) !important;
|
||||
}
|
||||
|
||||
button.state-ignore {
|
||||
background-color: var(--color-disabled) !important;
|
||||
}
|
||||
|
||||
div.layout-footer {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
p.layout-timer {
|
||||
padding: 16px 0;
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
(() => {
|
||||
const correctAnswer = 2560660350
|
||||
const soundSet = document.querySelector("audio#audio-set"); soundSet.volume = 0.5
|
||||
const soundDel = document.querySelector("audio#audio-del"); soundDel.volume = 0.5
|
||||
document.
|
||||
querySelector("div.layout-content")
|
||||
.addEventListener(
|
||||
// Prevent annoying context menu popup whenever you miss a grid tile by 1 pixel
|
||||
"contextmenu",
|
||||
e => e.preventDefault()
|
||||
)
|
||||
|
||||
// Setup Board //
|
||||
document.querySelectorAll("button.picross-button").forEach(e => {
|
||||
e.addEventListener("click", () => {
|
||||
e.classList.remove("state-ignore")
|
||||
e.classList.toggle("state-active")
|
||||
? soundSet.play()
|
||||
: soundDel.play()
|
||||
})
|
||||
e.addEventListener("contextmenu", ev => {
|
||||
ev.preventDefault()
|
||||
e.classList.remove("state-active")
|
||||
e.classList.toggle("state-ignore")
|
||||
soundDel.play()
|
||||
})
|
||||
})
|
||||
|
||||
// Setup Timer //
|
||||
function getTime() {
|
||||
const f = s => s.toString().padStart(2, "0")
|
||||
const h = Math.floor(t / 3600)
|
||||
const m = Math.floor(t % 3600 / 60)
|
||||
const s = Math.floor(t % 60)
|
||||
return `Time Spent: ${f(h)}:${f(m)}:${f(s)}`
|
||||
}
|
||||
let t = 0
|
||||
const timerElement = document.querySelector("p.layout-timer")
|
||||
setInterval(() => {
|
||||
t++
|
||||
timerElement.textContent = getTime()
|
||||
}, 1000)
|
||||
|
||||
// Action: Submit //
|
||||
document.querySelector("a#action-send").addEventListener("click", () => {
|
||||
|
||||
// Check Answer
|
||||
let givenAnswer = 0
|
||||
document.querySelectorAll('div.picross-row').forEach((childRow, rowIndex) => {
|
||||
let childIndex = 0
|
||||
for (const child of childRow.children) {
|
||||
if (child.nodeName === 'BUTTON') {
|
||||
if (child.classList.contains('state-active')) {
|
||||
givenAnswer += 1 << ((rowIndex - 3) * 9) + childIndex
|
||||
}
|
||||
childIndex++
|
||||
}
|
||||
}
|
||||
})
|
||||
if (correctAnswer !== givenAnswer) {
|
||||
alert("Nope! Try Again")
|
||||
return
|
||||
}
|
||||
|
||||
// Redirect to Certificate
|
||||
localStorage.setItem("secret_picross_complete", "true")
|
||||
const time = getTime()
|
||||
const name = prompt("Congratulations you win! Please enter your name for your certificate:", "Anon")
|
||||
window.location.assign(
|
||||
`/secret/picross/award?name=${encodeURIComponent(name)}&time=${encodeURIComponent(time)}`
|
||||
)
|
||||
})
|
||||
|
||||
})()
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 1.0 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1,94 @@
|
||||
:root {
|
||||
--accent: #4d58ff;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: black;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a,
|
||||
p {
|
||||
display: inline-block;
|
||||
font-family: 'Poppins', sans-serif;
|
||||
line-height: 1.5em;
|
||||
font-weight: 400;
|
||||
color: #f0f0f0;
|
||||
padding: 0 16px;
|
||||
margin: 0;
|
||||
text-align: justify;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Layout */
|
||||
|
||||
div.layout-section {
|
||||
width: 100%;
|
||||
max-width: 640px;
|
||||
margin: 16px auto;
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
display: grid;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
img.article-banner {
|
||||
width: 100%;
|
||||
image-rendering: pixelated;
|
||||
aspect-ratio: 3.4;
|
||||
}
|
||||
|
||||
/* Effects */
|
||||
|
||||
.effect-caution {
|
||||
position: relative;
|
||||
border: 4px solid var(--accent);
|
||||
background-color: black;
|
||||
margin-bottom: 12px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.effect-caution::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: -16px;
|
||||
bottom: -16px;
|
||||
box-sizing: border-box;
|
||||
filter: brightness(0.5);
|
||||
background: repeating-linear-gradient(45deg, var(--accent) 0, var(--accent) 8px, black 8px, black 16px);
|
||||
clip-path: polygon(calc(100% - 11px) 0, 100% 0, 100% 100%, 0 100%, 0 calc(100% - 11px), calc(100% - 11px) calc(100% - 11px));
|
||||
}
|
||||
|
||||
.effect-rhombus {
|
||||
position: relative;
|
||||
font-weight: 500;
|
||||
padding: 0 16px;
|
||||
z-index: 1;
|
||||
clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 100%, 8px 100%);
|
||||
}
|
||||
|
||||
.effect-rhombus::before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
box-sizing: border-box;
|
||||
background: var(--accent);
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
/* Mobile */
|
||||
@media only screen and (max-width: 600px) {
|
||||
div.layout-section {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.effect-caution::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
(() => {
|
||||
/** @type {HTMLAudioElement | null} */
|
||||
const soundActive = document.querySelector('audio#active')
|
||||
/** @type {HTMLAudioElement | null} */
|
||||
const soundBounce = document.querySelector('audio#bounce')
|
||||
/** @type {HTMLCanvasElement | null} */
|
||||
const canvas = document.querySelector('canvas#sprites')
|
||||
|
||||
if (canvas && soundActive && soundBounce) {
|
||||
|
||||
const RENDER_WIDTH = 256, RENDER_HEIGHT = 256, GRAVITY = 0.67, BOUNCE = 0.75, JUMP = 8, COUNT = 3
|
||||
const TEXTURE_WIDTH = 68, TEXTURE_HEIGHT = 78, TEXTURE_SCALE = 0.5
|
||||
const TEXTURE = new Image()
|
||||
const SPRITES = new Array()
|
||||
const OFFSET = (RENDER_WIDTH - (COUNT * (TEXTURE_WIDTH * TEXTURE_SCALE))) / COUNT
|
||||
|
||||
for (let i = 0; i < COUNT; i++) {
|
||||
SPRITES.push({
|
||||
x: (OFFSET / 2) + (OFFSET * i) + ((TEXTURE_WIDTH * TEXTURE_SCALE) * i),
|
||||
v: 0,
|
||||
y: 0
|
||||
})
|
||||
}
|
||||
|
||||
const ctx = canvas.getContext('2d')
|
||||
TEXTURE.src = `data:image/gif;base64,R0lGODlhRABOAPAAAAAAAFJSUiH5BAUKAAAALAAAAABEAE4AAAL/hI+pF+0P45p0uQqi3hD79CjcSF6fZzLlyp1iCrKy5KphPOe3SyP6D0N1fMBioGYxKpFE5ZKZcTqR0urxZM0Ks9Utd1r5WimksFgzKWNy5FHavZ61W0m6eeXt4TYfVp9fBxhX8of2AjeoVrjTZHenmNcQKPiIGHm1RzkHmRhkQHhp2Mlo47hpeUr66TeJV6kadaaZCSurdSjVmIsLtjrG++TbBQzUamT887arWxQqR1s8qkOcLM0GXR0rWRqNbZvN/N3NLd7sXf4cjn59vg7a7o4qHJ+uTs85f+8Krz/E3+9JG0B8AgeaymdQlL2EnhgSdCivIMSAE2dJrIgMI7mKPow4OvJICaRCkXpI+rvokdpEZezSTYvyj5SMjWq20ZS3D6Ggjjkz2sy05RwVPTxgQTk6NCDSpYt+Mn2aB0EBADs=`
|
||||
canvas.style.imageRendering = 'pixelated'
|
||||
canvas.style.width = `${RENDER_WIDTH}px`
|
||||
canvas.style.height = `${RENDER_HEIGHT}px`
|
||||
canvas.width = RENDER_WIDTH
|
||||
canvas.height = RENDER_HEIGHT
|
||||
soundBounce.playbackRate = 2
|
||||
soundBounce.volume = 0.5
|
||||
|
||||
canvas.addEventListener('click', () => {
|
||||
for (let i = 0; i < COUNT; i++) {
|
||||
SPRITES[i].v += JUMP + (Math.random() * (JUMP / 2))
|
||||
}
|
||||
})
|
||||
|
||||
setInterval(() => {
|
||||
ctx.clearRect(0, 0, RENDER_WIDTH, RENDER_HEIGHT)
|
||||
for (let i = 0; i < SPRITES.length; i++) {
|
||||
let oy = (RENDER_HEIGHT - (TEXTURE_HEIGHT * TEXTURE_SCALE))
|
||||
let s = SPRITES[i]
|
||||
s.v -= GRAVITY
|
||||
s.y += s.v
|
||||
|
||||
if (s.y < 0) {
|
||||
s.y = 0
|
||||
s.v = -s.v * BOUNCE
|
||||
if (Math.abs(s.v) < 0.8) {
|
||||
s.v = 0
|
||||
} else {
|
||||
soundBounce.currentTime = 0
|
||||
soundBounce.play()
|
||||
}
|
||||
}
|
||||
|
||||
ctx.drawImage(TEXTURE, s.x,
|
||||
oy - s.y,
|
||||
TEXTURE_WIDTH * TEXTURE_SCALE,
|
||||
TEXTURE_HEIGHT * TEXTURE_SCALE
|
||||
)
|
||||
}
|
||||
}, 1000 / 60);
|
||||
|
||||
}
|
||||
})()
|
||||
Reference in New Issue
Block a user