Initial React app setup on login/signup branch
This commit is contained in:
+394
@@ -0,0 +1,394 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
||||
<title>Static TV Cat Component</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.crt-wrapper {
|
||||
background: #080808;
|
||||
padding: 20px 24px 24px 24px;
|
||||
border-radius: 56px 56px 64px 64px;
|
||||
box-shadow: 0 25px 45px rgba(0,0,0,0.8), inset 0 1px 0 rgba(255,255,255,0.05);
|
||||
border: 1px solid #2a2520;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.crt-wrapper::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
left: 20%;
|
||||
width: 60%;
|
||||
height: 8px;
|
||||
background: radial-gradient(ellipse, rgba(70,200,140,0.3), transparent);
|
||||
filter: blur(6px);
|
||||
border-radius: 50%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.cat-artifact {
|
||||
background: black;
|
||||
border-radius: 28px;
|
||||
padding: 16px;
|
||||
box-shadow: inset 0 0 30px rgba(0,0,0,0.7), 0 12px 24px rgba(0,0,0,0.5);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.pixel-canvas-wrapper {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
background: #000;
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 0 0 3px #3a3530, 0 0 0 7px #0e0e0e;
|
||||
}
|
||||
|
||||
canvas {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
image-rendering: crisp-edges;
|
||||
image-rendering: pixelated;
|
||||
filter: url(#heavyStaticFilter) blur(0.6px) contrast(1.3) brightness(1.05);
|
||||
}
|
||||
|
||||
.scanlines-heavy {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
background: repeating-linear-gradient(0deg,
|
||||
rgba(0,0,0,0.35) 0px,
|
||||
rgba(0,0,0,0.35) 2px,
|
||||
transparent 2px,
|
||||
transparent 5px);
|
||||
z-index: 5;
|
||||
border-radius: 20px;
|
||||
animation: scanlineShift 0.2s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes scanlineShift {
|
||||
0% { background-position: 0 0; }
|
||||
100% { background-position: 0 4px; }
|
||||
}
|
||||
|
||||
.static-overlay-heavy {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300"><filter id="tvNoiseHeavy"><feTurbulence type="fractalNoise" baseFrequency="1.2" numOctaves="5" stitchTiles="stitch"><animate attributeName="baseFrequency" values="1.2;1.8;1.2" dur="0.12s" repeatCount="indefinite" /></filter><rect width="100%" height="100%" filter="url(%23tvNoiseHeavy)" opacity="0.7"/></svg>');
|
||||
background-repeat: repeat;
|
||||
background-size: 120px 90px;
|
||||
mix-blend-mode: screen;
|
||||
opacity: 0.65;
|
||||
border-radius: 20px;
|
||||
z-index: 3;
|
||||
animation: staticIntense 0.08s infinite;
|
||||
}
|
||||
|
||||
@keyframes staticIntense {
|
||||
0% { background-position: 0% 0%; opacity: 0.6; mix-blend-mode: screen; }
|
||||
25% { background-position: 3% 2%; opacity: 0.75; mix-blend-mode: hard-light; }
|
||||
50% { background-position: -2% 1%; opacity: 0.65; mix-blend-mode: screen; }
|
||||
75% { background-position: 4% 3%; opacity: 0.8; }
|
||||
100% { background-position: 0% 0%; opacity: 0.6; }
|
||||
}
|
||||
|
||||
.sparkle-static {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
background-image: radial-gradient(circle at 30% 45%, rgba(255,255,220,0.12) 1px, transparent 1px);
|
||||
background-size: 12px 12px;
|
||||
mix-blend-mode: overlay;
|
||||
animation: sparkleFlicker 0.1s infinite;
|
||||
z-index: 4;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
@keyframes sparkleFlicker {
|
||||
0% { opacity: 0.4; background-size: 10px 10px; }
|
||||
50% { opacity: 0.7; background-size: 14px 14px; }
|
||||
100% { opacity: 0.4; background-size: 10px 10px; }
|
||||
}
|
||||
|
||||
/* VHS glitch */
|
||||
.glitch-flash {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(255,255,240,0.03);
|
||||
pointer-events: none;
|
||||
animation: vhsFlicker 0.05s infinite;
|
||||
z-index: 2;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
@keyframes vhsFlicker {
|
||||
0% { opacity: 0.04; background: rgba(255,240,200,0.02); }
|
||||
33% { opacity: 0.12; background: rgba(0,0,0,0.08); }
|
||||
66% { opacity: 0.06; background: rgba(180,210,255,0.03); }
|
||||
100% { opacity: 0.04; background: rgba(0,0,0,0.02); }
|
||||
}
|
||||
|
||||
/* rolling noise bar */
|
||||
.rolling-bar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 6px;
|
||||
background: rgba(255,255,240,0.2);
|
||||
filter: blur(3px);
|
||||
animation: rollDown 1.8s linear infinite;
|
||||
pointer-events: none;
|
||||
z-index: 6;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
@keyframes rollDown {
|
||||
0% { top: -10px; opacity: 0; }
|
||||
10% { opacity: 0.5; }
|
||||
90% { opacity: 0.3; }
|
||||
100% { top: 100%; opacity: 0; }
|
||||
}
|
||||
|
||||
.crt-glow {
|
||||
position: absolute;
|
||||
bottom: -6px;
|
||||
left: 15%;
|
||||
width: 70%;
|
||||
height: 16px;
|
||||
background: radial-gradient(ellipse, rgba(90,220,150,0.25), transparent);
|
||||
filter: blur(10px);
|
||||
pointer-events: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="margin:0; padding:0; background:transparent; display:flex; justify-content:center; align-items:center; min-height:100vh;">
|
||||
<div class="crt-wrapper">
|
||||
<div class="cat-artifact">
|
||||
<div class="pixel-canvas-wrapper">
|
||||
<canvas id="pixelCatCanvas" width="416" height="352" style="width:100%; height:auto; max-width:416px; border-radius: 16px;"></canvas>
|
||||
<div class="scanlines-heavy"></div>
|
||||
<div class="static-overlay-heavy"></div>
|
||||
<div class="sparkle-static"></div>
|
||||
<div class="glitch-flash"></div>
|
||||
<div class="rolling-bar"></div>
|
||||
</div>
|
||||
<div class="crt-glow"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SVG STATIC FILTER -->
|
||||
<svg style="position: absolute; width: 0; height: 0; overflow: visible;" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<filter id="heavyStaticFilter" x="-15%" y="-15%" width="130%" height="130%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="0.55" result="bloom" />
|
||||
<feComponentTransfer in="bloom" result="boostContrast">
|
||||
<feFuncR type="linear" slope="1.45" intercept="-0.2"/>
|
||||
<feFuncG type="linear" slope="1.45" intercept="-0.2"/>
|
||||
<feFuncB type="linear" slope="1.45" intercept="-0.2"/>
|
||||
<feFuncA type="linear" slope="1" intercept="0"/>
|
||||
</feComponentTransfer>
|
||||
<feTurbulence type="fractalNoise" baseFrequency="2.2" numOctaves="4" result="intenseNoise">
|
||||
<animate attributeName="baseFrequency" values="2.1;2.5;2.1" dur="0.08s" repeatCount="indefinite" />
|
||||
</feTurbulence>
|
||||
<feDisplacementMap in="boostContrast" in2="intenseNoise" scale="1.8" xChannelSelector="R" yChannelSelector="G" result="displacedStatic"/>
|
||||
<feColorMatrix type="matrix" values="1.1 0 0 0 0.05 0 1.05 0 0 0.02 0 0 1.1 0 0.03 0 0 0 1 0" in="displacedStatic" result="colorNoise"/>
|
||||
<feGaussianBlur in="colorNoise" stdDeviation="0.3" result="finalStatic"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
// CAT PIXEL DATA
|
||||
const originalCatRows = [
|
||||
[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0],
|
||||
[0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0],
|
||||
[0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0],
|
||||
[0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0],
|
||||
[0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0],
|
||||
[0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0],
|
||||
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
|
||||
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
|
||||
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],
|
||||
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],
|
||||
[0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],
|
||||
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
|
||||
[0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,0,0],
|
||||
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
|
||||
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
|
||||
[0,0,1,1,1,1,1,1,0,1,0,1,1,1,0,1,1,1,1,1,1,1,1,0,0,0],
|
||||
[0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0],
|
||||
[0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0],
|
||||
[0,0,0,0,0,0,1,1,1,1,0,0,1,1,0,1,1,1,0,0,0,0,0,0,0,0],
|
||||
[0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0],
|
||||
[0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0],
|
||||
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
|
||||
];
|
||||
|
||||
let currentCatRows = JSON.parse(JSON.stringify(originalCatRows));
|
||||
const rows = 22, cols = 26;
|
||||
const cellSize = 16;
|
||||
const canvas = document.getElementById('pixelCatCanvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
const leftEyeCols = [6, 7, 8, 9];
|
||||
const rightEyeCols = [15, 16, 17, 18];
|
||||
const eyeRow = 12;
|
||||
|
||||
let leftPupilCol = 7;
|
||||
let rightPupilCol = 16;
|
||||
let isBlinking = false;
|
||||
|
||||
function updatePupilInMatrix() {
|
||||
for (let col of leftEyeCols) {
|
||||
if (currentCatRows[eyeRow][col] === 1) currentCatRows[eyeRow][col] = 0;
|
||||
}
|
||||
for (let col of rightEyeCols) {
|
||||
if (currentCatRows[eyeRow][col] === 1) currentCatRows[eyeRow][col] = 0;
|
||||
}
|
||||
if (leftEyeCols.includes(leftPupilCol)) currentCatRows[eyeRow][leftPupilCol] = 1;
|
||||
else currentCatRows[eyeRow][7] = 1;
|
||||
if (rightEyeCols.includes(rightPupilCol)) currentCatRows[eyeRow][rightPupilCol] = 1;
|
||||
else currentCatRows[eyeRow][16] = 1;
|
||||
}
|
||||
|
||||
function drawCatFromMatrix() {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
for (let row = 0; row < rows; row++) {
|
||||
for (let col = 0; col < cols; col++) {
|
||||
const val = currentCatRows[row][col];
|
||||
const x = col * cellSize;
|
||||
const y = row * cellSize;
|
||||
|
||||
if (val === 1) {
|
||||
ctx.fillStyle = "#12100c";
|
||||
ctx.fillRect(x, y, cellSize, cellSize);
|
||||
for (let i = 0; i < 12; i++) {
|
||||
const dx = x + 2 + Math.random() * (cellSize - 4);
|
||||
const dy = y + 2 + Math.random() * (cellSize - 4);
|
||||
ctx.beginPath();
|
||||
ctx.arc(dx, dy, 0.7 + Math.random() * 1.7, 0, Math.PI*2);
|
||||
ctx.fillStyle = `rgba(35,30,24,${0.5 + Math.random() * 0.5})`;
|
||||
ctx.fill();
|
||||
}
|
||||
if (Math.random() > 0.78) {
|
||||
ctx.beginPath();
|
||||
ctx.arc(x + Math.random() * cellSize, y + Math.random() * cellSize, 1.1, 0, Math.PI*2);
|
||||
ctx.fillStyle = `rgba(210,200,180,0.6)`;
|
||||
ctx.fill();
|
||||
}
|
||||
} else {
|
||||
ctx.fillStyle = "#f5f2ea";
|
||||
ctx.fillRect(x, y, cellSize, cellSize);
|
||||
for (let d = 0; d < 4; d++) {
|
||||
ctx.fillStyle = `rgba(0,0,0,0.07)`;
|
||||
ctx.beginPath();
|
||||
ctx.arc(x + Math.random() * cellSize, y + Math.random() * cellSize, 0.9, 0, Math.PI*2);
|
||||
ctx.fill();
|
||||
}
|
||||
if (Math.random() > 0.92) {
|
||||
ctx.fillStyle = `rgba(30,25,20,0.4)`;
|
||||
ctx.beginPath();
|
||||
ctx.arc(x + Math.random() * cellSize, y + Math.random() * cellSize, 1.3, 0, Math.PI*2);
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < 1200; i++) {
|
||||
const randX = Math.random() * canvas.width;
|
||||
const randY = Math.random() * canvas.height;
|
||||
ctx.beginPath();
|
||||
ctx.arc(randX, randY, 0.6 + Math.random() * 1.8, 0, Math.PI * 2);
|
||||
ctx.fillStyle = `rgba(0,0,0,${0.1 + Math.random() * 0.35})`;
|
||||
ctx.fill();
|
||||
}
|
||||
for (let s = 0; s < 400; s++) {
|
||||
const sx = Math.random() * canvas.width;
|
||||
const sy = Math.random() * canvas.height;
|
||||
ctx.fillStyle = `rgba(230,220,190,${0.2 + Math.random() * 0.5})`;
|
||||
ctx.fillRect(sx, sy, 1.5 + Math.random() * 3, 1);
|
||||
}
|
||||
for (let b = 0; b < 45; b++) {
|
||||
const bandY = Math.random() * canvas.height;
|
||||
ctx.fillStyle = `rgba(0,0,0,0.12)`;
|
||||
ctx.fillRect(0, bandY, canvas.width, 1.5);
|
||||
}
|
||||
}
|
||||
|
||||
function performBlink() {
|
||||
if (isBlinking) return;
|
||||
isBlinking = true;
|
||||
const savedLeft = leftPupilCol;
|
||||
const savedRight = rightPupilCol;
|
||||
for (let col of leftEyeCols) currentCatRows[eyeRow][col] = 1;
|
||||
for (let col of rightEyeCols) currentCatRows[eyeRow][col] = 1;
|
||||
drawCatFromMatrix();
|
||||
setTimeout(() => {
|
||||
for (let col of leftEyeCols) currentCatRows[eyeRow][col] = 0;
|
||||
for (let col of rightEyeCols) currentCatRows[eyeRow][col] = 0;
|
||||
leftPupilCol = savedLeft;
|
||||
rightPupilCol = savedRight;
|
||||
updatePupilInMatrix();
|
||||
drawCatFromMatrix();
|
||||
isBlinking = false;
|
||||
}, 130);
|
||||
}
|
||||
|
||||
setInterval(() => {
|
||||
if (isBlinking) return;
|
||||
leftPupilCol = (leftPupilCol === 7) ? 8 : 7;
|
||||
rightPupilCol = (rightPupilCol === 16) ? 17 : 16;
|
||||
updatePupilInMatrix();
|
||||
drawCatFromMatrix();
|
||||
}, 480);
|
||||
|
||||
setInterval(() => {
|
||||
if (!isBlinking) performBlink();
|
||||
}, 2600 + Math.random() * 2400);
|
||||
|
||||
const wrapper = document.querySelector('.pixel-canvas-wrapper');
|
||||
wrapper.addEventListener('mouseenter', () => { if (!isBlinking) performBlink(); });
|
||||
wrapper.addEventListener('click', () => {
|
||||
if (!isBlinking) performBlink();
|
||||
setTimeout(() => { if (!isBlinking) performBlink(); }, 180);
|
||||
});
|
||||
|
||||
for (let col of leftEyeCols) currentCatRows[eyeRow][col] = 0;
|
||||
for (let col of rightEyeCols) currentCatRows[eyeRow][col] = 0;
|
||||
leftPupilCol = 7;
|
||||
rightPupilCol = 16;
|
||||
updatePupilInMatrix();
|
||||
drawCatFromMatrix();
|
||||
|
||||
setInterval(() => {
|
||||
if (!isBlinking) drawCatFromMatrix();
|
||||
}, 180);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.8 KiB |
+10
-40
@@ -1,43 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
||||
<title>Purrgram Login</title>
|
||||
<!-- Pixel font -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 9.4 KiB |
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
||||
Reference in New Issue
Block a user