905 lines
32 KiB
HTML
905 lines
32 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Signal Elsewhere</title>
|
|
<style>
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
background-color: #000;
|
|
overflow: hidden;
|
|
font-family: 'Courier New', monospace;
|
|
}
|
|
|
|
#matrixCanvas {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100vw;
|
|
height: 100vh;
|
|
z-index: 1;
|
|
opacity: 1;
|
|
transition: opacity 1s ease;
|
|
}
|
|
|
|
#textContainer {
|
|
position: fixed;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
z-index: 2;
|
|
text-align: center;
|
|
font-size: 1.2rem;
|
|
line-height: 2;
|
|
visibility: hidden;
|
|
color: #00ff00;
|
|
}
|
|
|
|
.typewriter-line {
|
|
visibility: hidden;
|
|
white-space: nowrap;
|
|
margin: 0.5rem 0;
|
|
}
|
|
|
|
#followBtn {
|
|
position: fixed;
|
|
bottom: 5%;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
z-index: 3;
|
|
padding: 1rem 3rem;
|
|
font-size: 1.1rem;
|
|
background-color: #001100;
|
|
color: #00ff00;
|
|
border: 2px solid #00ff00;
|
|
cursor: pointer;
|
|
visibility: hidden;
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
transition: opacity 0.5s ease, background-color 0.2s ease;
|
|
font-family: 'Courier New', monospace;
|
|
letter-spacing: 2px;
|
|
}
|
|
|
|
#followBtn:hover {
|
|
background-color: #003300;
|
|
}
|
|
|
|
.scene {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100vw;
|
|
height: 100vh;
|
|
z-index: 4;
|
|
background-color: #000;
|
|
color: #00ff00;
|
|
display: none;
|
|
justify-content: center;
|
|
align-items: center;
|
|
font-family: 'Courier New', monospace;
|
|
font-size: 1.2rem;
|
|
text-align: center;
|
|
padding: 2rem;
|
|
opacity: 0;
|
|
transition: opacity 1s ease;
|
|
}
|
|
|
|
#scene3RecruitLines {
|
|
display: none;
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
width: 100%;
|
|
padding: 2rem;
|
|
}
|
|
|
|
.scene3RecruitLine {
|
|
display: none;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
font-size: 1.2rem;
|
|
line-height: 2;
|
|
color: #00ff00;
|
|
}
|
|
|
|
#scene3RecruitLine1 {
|
|
margin-top: 7.2rem;
|
|
}
|
|
|
|
#scene3RecruitCursor,
|
|
#scene3RecruitCursor2 {
|
|
display: none;
|
|
width: 10px;
|
|
height: 1.4em;
|
|
background-color: #00ff00;
|
|
margin-left: 4px;
|
|
flex-shrink: 0;
|
|
opacity: 1;
|
|
}
|
|
|
|
#scene3RecruitLine3 {
|
|
min-height: 2em;
|
|
}
|
|
|
|
#scene2 {
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
align-items: center;
|
|
position: relative;
|
|
}
|
|
|
|
.choiceBtn {
|
|
position: absolute;
|
|
padding: 1rem 3rem;
|
|
font-size: 1.1rem;
|
|
background-color: #001100;
|
|
color: #00ff00;
|
|
border: 2px solid #00ff00;
|
|
cursor: pointer;
|
|
visibility: hidden;
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
transition: opacity 0.5s ease, background-color 0.2s ease;
|
|
font-family: 'Courier New', monospace;
|
|
letter-spacing: 2px;
|
|
display: none;
|
|
}
|
|
|
|
.choiceBtn:hover {
|
|
background-color: #003300;
|
|
}
|
|
|
|
#creatorBtn {
|
|
top: 55%;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
}
|
|
|
|
#builderBtn {
|
|
top: 70%;
|
|
left: 35%;
|
|
transform: translateX(-50%);
|
|
}
|
|
|
|
#developerBtn {
|
|
top: 70%;
|
|
left: 65%;
|
|
transform: translateX(-50%);
|
|
}
|
|
|
|
#scene3FitInText {
|
|
position: absolute;
|
|
bottom: 48%;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
font-size: 1.2rem;
|
|
color: #00ff00;
|
|
opacity: 0;
|
|
visibility: hidden;
|
|
transition: opacity 1s ease;
|
|
}
|
|
|
|
#scene2Lines {
|
|
display: none;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 100%;
|
|
}
|
|
|
|
#scene2Line1 {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 1.2rem;
|
|
line-height: 1.8;
|
|
color: #00ff00;
|
|
visibility: hidden;
|
|
padding: 2rem;
|
|
text-align: center;
|
|
}
|
|
|
|
#scene2Line2 {
|
|
display: none;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 1.2rem;
|
|
line-height: 1.8;
|
|
color: #00ff00;
|
|
padding: 0 2rem 2rem;
|
|
text-align: center;
|
|
}
|
|
|
|
#scene2Message2 {
|
|
color: #00ff00;
|
|
font-family: 'Courier New', monospace;
|
|
font-size: 1.2rem;
|
|
}
|
|
|
|
#scene2Cursor,
|
|
#scene2Cursor2 {
|
|
display: none;
|
|
width: 10px;
|
|
height: 1.4em;
|
|
background-color: #00ff00;
|
|
margin-left: 4px;
|
|
flex-shrink: 0;
|
|
opacity: 1;
|
|
}
|
|
|
|
#whatIsLabBtn {
|
|
position: fixed;
|
|
bottom: 5%;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
z-index: 3;
|
|
padding: 1rem 3rem;
|
|
font-size: 1.1rem;
|
|
background-color: #001100;
|
|
color: #00ff00;
|
|
border: 2px solid #00ff00;
|
|
cursor: pointer;
|
|
visibility: hidden;
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
transition: opacity 0.5s ease, background-color 0.2s ease;
|
|
font-family: 'Courier New', monospace;
|
|
letter-spacing: 2px;
|
|
}
|
|
|
|
#whatIsLabBtn:hover {
|
|
background-color: #003300;
|
|
}
|
|
|
|
#scene3Title {
|
|
position: absolute;
|
|
top: 2rem;
|
|
left: 2rem;
|
|
font-size: 3rem;
|
|
font-weight: bold;
|
|
color: #00ff00;
|
|
opacity: 0;
|
|
transition: opacity 1.5s ease-out;
|
|
}
|
|
|
|
#scene3Title.visible {
|
|
opacity: 1;
|
|
}
|
|
|
|
#scene3 {
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
justify-content: flex-start;
|
|
padding: 6rem 2rem;
|
|
}
|
|
|
|
#scene3Text {
|
|
white-space: pre-wrap;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<canvas id="matrixCanvas"></canvas>
|
|
|
|
<div id="textContainer">
|
|
<div class="typewriter-line" id="line1"></div>
|
|
<div class="typewriter-line" id="line2"></div>
|
|
<div class="typewriter-line" id="line3"></div>
|
|
</div>
|
|
|
|
<button id="followBtn">FOLLOW THEM</button>
|
|
|
|
<div id="scene2" class="scene">
|
|
<div id="scene2Lines">
|
|
<div id="scene2Line1">
|
|
<span id="scene2Message"></span>
|
|
<span id="scene2Cursor"></span>
|
|
</div>
|
|
<div id="scene2Line2">
|
|
<span id="scene2Message2"></span>
|
|
<span id="scene2Cursor2"></span>
|
|
</div>
|
|
</div>
|
|
<button id="whatIsLabBtn">WHAT IS LAB 484?</button>
|
|
</div>
|
|
|
|
<div id="scene3" class="scene">
|
|
<div id="scene3Title">LAB 484</div>
|
|
<div id="scene3Text"></div>
|
|
<div id="scene3RecruitLines">
|
|
<div id="scene3RecruitLine1" class="scene3RecruitLine">
|
|
<span id="scene3RecruitText1"></span>
|
|
<span id="scene3RecruitCursor"></span>
|
|
</div>
|
|
<div id="scene3RecruitLine2" class="scene3RecruitLine">
|
|
<span id="scene3RecruitText2"></span>
|
|
</div>
|
|
<div id="scene3RecruitLine3" class="scene3RecruitLine">
|
|
<span id="scene3RecruitCursor2"></span>
|
|
</div>
|
|
<div id="scene3RecruitLine4" class="scene3RecruitLine">
|
|
<span id="scene3RecruitText4"></span>
|
|
</div>
|
|
</div>
|
|
<div id="scene3FitInText"></div>
|
|
<button id="creatorBtn" class="choiceBtn">CREATOR</button>
|
|
<button id="builderBtn" class="choiceBtn">BUILDER</button>
|
|
<button id="developerBtn" class="choiceBtn">DEVELOPER</button>
|
|
</div>
|
|
|
|
<div id="sceneCreator" class="scene">
|
|
<div id="creatorSceneText"></div>
|
|
</div>
|
|
|
|
<div id="sceneBuilder" class="scene">
|
|
<div id="builderSceneText"></div>
|
|
</div>
|
|
|
|
<div id="sceneDeveloper" class="scene">
|
|
<div id="developerSceneText"></div>
|
|
</div>
|
|
|
|
<script>
|
|
// Testing shortcuts state
|
|
let skipAnimations = false;
|
|
|
|
// Canvas setup for Matrix rain
|
|
const canvas = document.getElementById('matrixCanvas');
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
function resizeCanvas() {
|
|
canvas.width = window.innerWidth;
|
|
canvas.height = window.innerHeight;
|
|
}
|
|
resizeCanvas();
|
|
window.addEventListener('resize', resizeCanvas);
|
|
|
|
// Matrix rain configuration
|
|
const fontSize = 14;
|
|
let columns = Math.floor(canvas.width / fontSize);
|
|
let drops = [];
|
|
const chars = '0123456789@#$%^&*()';
|
|
const rainDuration = 8000; // 8 seconds
|
|
let rainActive = false;
|
|
let rainStartTime = null;
|
|
|
|
// CRT flicker effect
|
|
function crtFlicker() {
|
|
let flickerCount = 0;
|
|
const maxFlickers = 3;
|
|
const flickerInterval = setInterval(() => {
|
|
ctx.fillStyle = flickerCount % 2 === 0 ? 'rgba(255,255,255,0.15)' : 'rgba(0,0,0,1)';
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
flickerCount++;
|
|
if (flickerCount >= maxFlickers * 2) {
|
|
clearInterval(flickerInterval);
|
|
ctx.fillStyle = '#000';
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
startMatrixRain();
|
|
}
|
|
}, 100);
|
|
}
|
|
|
|
// Start Matrix rain animation
|
|
function startMatrixRain() {
|
|
rainActive = true;
|
|
rainStartTime = Date.now();
|
|
columns = Math.floor(canvas.width / fontSize);
|
|
drops = Array(columns).fill(0).map(() => Math.floor(Math.random() * canvas.height / fontSize));
|
|
drawMatrix();
|
|
}
|
|
|
|
// Draw Matrix rain frame
|
|
function drawMatrix() {
|
|
if (!rainActive) return;
|
|
|
|
// Create trail effect
|
|
ctx.fillStyle = 'rgba(0,0,0,0.05)';
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
ctx.fillStyle = '#00ff00';
|
|
ctx.font = fontSize + 'px Courier New, monospace';
|
|
|
|
for (let i = 0; i < columns; i++) {
|
|
const x = i * fontSize;
|
|
const y = drops[i] * fontSize;
|
|
|
|
// Chance to render "484" as a horizontal string in this column
|
|
if (Math.random() < 0.003) {
|
|
ctx.fillText('484', x, y);
|
|
} else {
|
|
const text = chars[Math.floor(Math.random() * chars.length)];
|
|
ctx.fillText(text, x, y);
|
|
}
|
|
|
|
// Reset drop when it goes off screen
|
|
if (y > canvas.height && Math.random() > 0.975) {
|
|
drops[i] = 0;
|
|
}
|
|
drops[i] += 0.5;
|
|
}
|
|
|
|
// End rain after duration
|
|
if (Date.now() - rainStartTime > rainDuration) {
|
|
fadeRainToBackground();
|
|
rainActive = false;
|
|
} else {
|
|
requestAnimationFrame(drawMatrix);
|
|
}
|
|
}
|
|
|
|
// Fade rain to background
|
|
function fadeRainToBackground() {
|
|
const canvasElem = document.getElementById('matrixCanvas');
|
|
let opacity = 1;
|
|
const fadeInterval = setInterval(() => {
|
|
opacity -= 0.02;
|
|
if (opacity <= 0.15) {
|
|
opacity = 0.15;
|
|
clearInterval(fadeInterval);
|
|
document.getElementById('textContainer').style.visibility = 'visible';
|
|
typewriter();
|
|
}
|
|
canvasElem.style.opacity = opacity;
|
|
}, 16);
|
|
}
|
|
|
|
// Reusable typewriter function with custom delays
|
|
function typewriterLines(lines, targetElem, onComplete, charDelay, lineDelay, endCharDelay) {
|
|
charDelay = charDelay || 60;
|
|
lineDelay = lineDelay || 500;
|
|
let currentLine = 0;
|
|
let currentChar = 0;
|
|
let totalChars = 0;
|
|
let charsTyped = 0;
|
|
|
|
// Calculate total characters if using accelerating speed
|
|
if (endCharDelay !== null) {
|
|
totalChars = 0;
|
|
for (let i = 0; i < lines.length; i++) {
|
|
totalChars += lines[i].length;
|
|
}
|
|
}
|
|
|
|
function getDelay() {
|
|
if (endCharDelay === null || totalChars === 0) return charDelay;
|
|
const progress = charsTyped / totalChars;
|
|
return charDelay + (endCharDelay - charDelay) * progress;
|
|
}
|
|
|
|
function tick() {
|
|
if (skipAnimations) {
|
|
let remainingText = '';
|
|
for (let i = currentLine; i < lines.length; i++) {
|
|
remainingText += lines[i];
|
|
}
|
|
targetElem.textContent = remainingText;
|
|
onComplete && onComplete();
|
|
return;
|
|
}
|
|
|
|
if (currentLine >= lines.length) {
|
|
onComplete && onComplete();
|
|
return;
|
|
}
|
|
|
|
targetElem.style.visibility = 'visible';
|
|
const lineText = lines[currentLine];
|
|
|
|
if (currentChar < lineText.length) {
|
|
targetElem.textContent += lineText[currentChar];
|
|
currentChar++;
|
|
charsTyped++;
|
|
setTimeout(tick, getDelay());
|
|
} else {
|
|
currentLine++;
|
|
currentChar = 0;
|
|
setTimeout(tick, lineDelay);
|
|
}
|
|
}
|
|
tick();
|
|
}
|
|
|
|
// Scene 1 typewriter
|
|
const scene1lines = [
|
|
"YOU ARE NOT IMAGINING THINGS",
|
|
"THE SYNCHRONICITIES YOU ARE EXPERIENCING HAVE ALWAYS BEEN THERE",
|
|
"THE ONLY THING THAT HAS CHANGED IS YOUR AWARENESS OF THEM"
|
|
];
|
|
let scene1LineIndex = 0;
|
|
let scene1Timeouts = [];
|
|
|
|
function typewriter() {
|
|
if (scene1LineIndex >= scene1lines.length) {
|
|
showButton();
|
|
return;
|
|
}
|
|
|
|
const lineElem = document.getElementById('line' + (scene1LineIndex + 1));
|
|
lineElem.style.visibility = 'visible';
|
|
const lineText = scene1lines[scene1LineIndex];
|
|
let charIndex = 0;
|
|
|
|
function typeChar() {
|
|
if (charIndex < lineText.length) {
|
|
lineElem.textContent += lineText[charIndex];
|
|
charIndex++;
|
|
const t = setTimeout(typeChar, 60);
|
|
scene1Timeouts.push(t);
|
|
} else {
|
|
scene1LineIndex++;
|
|
const t = setTimeout(typewriter, 500);
|
|
scene1Timeouts.push(t);
|
|
}
|
|
}
|
|
typeChar();
|
|
}
|
|
|
|
function skipScene1() {
|
|
scene1Timeouts.forEach(t => clearTimeout(t));
|
|
scene1Timeouts = [];
|
|
document.getElementById('line1').textContent = scene1lines[0];
|
|
document.getElementById('line2').textContent = scene1lines[1];
|
|
document.getElementById('line3').textContent = scene1lines[2];
|
|
document.getElementById('line1').style.visibility = 'visible';
|
|
document.getElementById('line2').style.visibility = 'visible';
|
|
document.getElementById('line3').style.visibility = 'visible';
|
|
showButton();
|
|
}
|
|
|
|
// Show "FOLLOW THEM" button
|
|
function showButton() {
|
|
const btn = document.getElementById('followBtn');
|
|
btn.style.visibility = 'visible';
|
|
let opacity = 0;
|
|
const fadeIn = setInterval(() => {
|
|
opacity += 0.05;
|
|
if (opacity >= 1) {
|
|
opacity = 1;
|
|
clearInterval(fadeIn);
|
|
btn.style.pointerEvents = 'auto';
|
|
}
|
|
btn.style.opacity = opacity;
|
|
}, 30);
|
|
}
|
|
|
|
// Scene transition functions
|
|
function transitionToScene2() {
|
|
const canvas = document.getElementById('matrixCanvas');
|
|
const textContainer = document.getElementById('textContainer');
|
|
const btn = document.getElementById('followBtn');
|
|
const scene2 = document.getElementById('scene2');
|
|
|
|
let opacity = 1;
|
|
const fadeOut = setInterval(() => {
|
|
opacity -= 0.05;
|
|
if (opacity <= 0) {
|
|
opacity = 0;
|
|
clearInterval(fadeOut);
|
|
canvas.style.display = 'none';
|
|
textContainer.style.display = 'none';
|
|
btn.style.display = 'none';
|
|
loadScene2(scene2);
|
|
}
|
|
canvas.style.opacity = opacity;
|
|
textContainer.style.opacity = opacity;
|
|
btn.style.opacity = opacity;
|
|
}, 30);
|
|
}
|
|
|
|
// Scene 2 loader: calm typing sequence
|
|
function blinkCursor(cursor, times, callback) {
|
|
cursor.style.display = 'inline-block';
|
|
cursor.style.opacity = '1';
|
|
let count = 0;
|
|
let visible = true;
|
|
const interval = setInterval(() => {
|
|
visible = !visible;
|
|
cursor.style.opacity = visible ? '1' : '0';
|
|
count++;
|
|
if (count >= times * 2) {
|
|
clearInterval(interval);
|
|
cursor.style.display = 'none';
|
|
callback && callback();
|
|
}
|
|
}, 500);
|
|
}
|
|
|
|
function typeCalmly(elem, text, callback, minDelay, maxDelay) {
|
|
let i = 0;
|
|
const total = text.length;
|
|
|
|
function typeChar() {
|
|
if (i >= total) {
|
|
callback && callback();
|
|
return;
|
|
}
|
|
elem.textContent += text[i];
|
|
i++;
|
|
const progress = i / total;
|
|
const dMin = minDelay || 35;
|
|
const dMax = maxDelay || 65;
|
|
const delay = dMin + progress * progress * (dMax - dMin);
|
|
setTimeout(typeChar, delay);
|
|
}
|
|
typeChar();
|
|
}
|
|
|
|
function loadScene2(sceneElem) {
|
|
sceneElem.style.display = 'flex';
|
|
const linesContainer = document.getElementById('scene2Lines');
|
|
const line1 = document.getElementById('scene2Line1');
|
|
const line2 = document.getElementById('scene2Line2');
|
|
const message = document.getElementById('scene2Message');
|
|
const message2 = document.getElementById('scene2Message2');
|
|
const cursor = document.getElementById('scene2Cursor');
|
|
const cursor2 = document.getElementById('scene2Cursor2');
|
|
const btn = document.getElementById('whatIsLabBtn');
|
|
|
|
let opacity = 0;
|
|
const fadeIn = setInterval(() => {
|
|
opacity += 0.05;
|
|
if (opacity >= 1) {
|
|
opacity = 1;
|
|
clearInterval(fadeIn);
|
|
|
|
linesContainer.style.display = 'flex';
|
|
line1.style.visibility = 'visible';
|
|
|
|
blinkCursor(cursor, 3, () => {
|
|
typeCalmly(message, "...AND THAT AWARENESS HAS LED YOU HERE...", () => {
|
|
cursor.style.display = 'none';
|
|
line2.style.display = 'flex';
|
|
|
|
blinkCursor(cursor2, 3, () => {
|
|
typeCalmly(message2, "TO LAB 484", () => {
|
|
setTimeout(() => {
|
|
btn.style.visibility = 'visible';
|
|
let btnOpacity = 0;
|
|
const btnFadeIn = setInterval(() => {
|
|
btnOpacity += 0.05;
|
|
if (btnOpacity >= 1) {
|
|
btnOpacity = 1;
|
|
clearInterval(btnFadeIn);
|
|
btn.style.pointerEvents = 'auto';
|
|
}
|
|
btn.style.opacity = btnOpacity;
|
|
}, 30);
|
|
}, 3000);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
}
|
|
sceneElem.style.opacity = opacity;
|
|
}, 30);
|
|
}
|
|
|
|
// Scene transition helper
|
|
function transitionToScene(fromId, loader, toId) {
|
|
const from = document.getElementById(fromId);
|
|
from.style.display = 'none';
|
|
const to = document.getElementById(toId);
|
|
loader(to);
|
|
}
|
|
|
|
// Placeholder scene loaders
|
|
function loadSceneCreator(sceneElem) {
|
|
sceneElem.style.display = 'flex';
|
|
const text = document.getElementById('creatorSceneText');
|
|
text.style.visibility = 'visible';
|
|
text.textContent = 'CREATOR';
|
|
let opacity = 0;
|
|
const fadeIn = setInterval(() => {
|
|
opacity += 0.05;
|
|
if (opacity >= 1) {
|
|
opacity = 1;
|
|
clearInterval(fadeIn);
|
|
}
|
|
sceneElem.style.opacity = opacity;
|
|
}, 30);
|
|
}
|
|
|
|
function loadSceneBuilder(sceneElem) {
|
|
sceneElem.style.display = 'flex';
|
|
const text = document.getElementById('builderSceneText');
|
|
text.style.visibility = 'visible';
|
|
text.textContent = 'BUILDER';
|
|
let opacity = 0;
|
|
const fadeIn = setInterval(() => {
|
|
opacity += 0.05;
|
|
if (opacity >= 1) {
|
|
opacity = 1;
|
|
clearInterval(fadeIn);
|
|
}
|
|
sceneElem.style.opacity = opacity;
|
|
}, 30);
|
|
}
|
|
|
|
function loadSceneDeveloper(sceneElem) {
|
|
sceneElem.style.display = 'flex';
|
|
const text = document.getElementById('developerSceneText');
|
|
text.style.visibility = 'visible';
|
|
text.textContent = 'DEVELOPER';
|
|
let opacity = 0;
|
|
const fadeIn = setInterval(() => {
|
|
opacity += 0.05;
|
|
if (opacity >= 1) {
|
|
opacity = 1;
|
|
clearInterval(fadeIn);
|
|
}
|
|
sceneElem.style.opacity = opacity;
|
|
}, 30);
|
|
}
|
|
|
|
// Scene 3 loader with recruitment text and 3 choice buttons
|
|
function loadScene3(sceneElem) {
|
|
sceneElem.style.display = 'flex';
|
|
const title = document.getElementById('scene3Title');
|
|
const textContainer = document.getElementById('scene3Text');
|
|
const recruitLines = document.getElementById('scene3RecruitLines');
|
|
const rl1 = document.getElementById('scene3RecruitLine1');
|
|
const rt1 = document.getElementById('scene3RecruitText1');
|
|
const cursor = document.getElementById('scene3RecruitCursor');
|
|
const creatorBtn = document.getElementById('creatorBtn');
|
|
const builderBtn = document.getElementById('builderBtn');
|
|
const developerBtn = document.getElementById('developerBtn');
|
|
const choiceBtns = [creatorBtn, builderBtn, developerBtn];
|
|
|
|
let opacity = 0;
|
|
const fadeIn = setInterval(() => {
|
|
opacity += 0.05;
|
|
if (opacity >= 1) {
|
|
opacity = 1;
|
|
clearInterval(fadeIn);
|
|
|
|
setTimeout(() => {
|
|
title.classList.add('visible');
|
|
}, 300);
|
|
|
|
typeCalmly(textContainer, "- IS AN INCUBATOR THAT HAS MANY DECENTRALIZED STARTUPS UNDERNEATH IT", () => {
|
|
recruitLines.style.display = 'flex';
|
|
|
|
setTimeout(() => {
|
|
rl1.style.display = 'flex';
|
|
|
|
blinkCursor(cursor, 3, () => {
|
|
typeCalmly(rt1, "THE LAB IS CONNECTING WITH PEOPLE WHO SEE WHAT'S HAPPENINGG - WHO KNOW CHANGE ISN'T OPTIONAL. WE'RE LOOKING FOR THOSE READY TO STEP IN AND SHAPE THE FUTURE", () => {
|
|
setTimeout(() => {
|
|
choiceBtns.forEach(btn => {
|
|
btn.style.display = 'block';
|
|
btn.style.visibility = 'visible';
|
|
let btnOpacity = 0;
|
|
const btnFadeIn = setInterval(() => {
|
|
btnOpacity += 0.02;
|
|
if (btnOpacity >= 1) {
|
|
btnOpacity = 1;
|
|
clearInterval(btnFadeIn);
|
|
btn.style.pointerEvents = 'auto';
|
|
}
|
|
btn.style.opacity = btnOpacity;
|
|
}, 30);
|
|
});
|
|
setTimeout(() => {
|
|
const fitInText = document.getElementById('scene3FitInText');
|
|
fitInText.textContent = 'WHERE DO YOU FIT IN?';
|
|
fitInText.style.visibility = 'visible';
|
|
let fiOpacity = 0;
|
|
const fiFadeIn = setInterval(() => {
|
|
fiOpacity += 0.05;
|
|
if (fiOpacity >= 1) {
|
|
fiOpacity = 1;
|
|
clearInterval(fiFadeIn);
|
|
}
|
|
fitInText.style.opacity = fiOpacity;
|
|
}, 30);
|
|
}, 500);
|
|
}, 3000);
|
|
}, 10, 25);
|
|
});
|
|
}, 2000);
|
|
});
|
|
}
|
|
sceneElem.style.opacity = opacity;
|
|
}, 30);
|
|
}
|
|
|
|
// Initialize on load
|
|
window.addEventListener('load', () => {
|
|
setTimeout(crtFlicker, 1500);
|
|
});
|
|
|
|
// Button click handlers
|
|
document.getElementById('followBtn').addEventListener('click', transitionToScene2);
|
|
document.getElementById('creatorBtn').addEventListener('click', () => {
|
|
transitionToScene('scene3', loadSceneCreator, 'sceneCreator');
|
|
});
|
|
document.getElementById('builderBtn').addEventListener('click', () => {
|
|
transitionToScene('scene3', loadSceneBuilder, 'sceneBuilder');
|
|
});
|
|
document.getElementById('developerBtn').addEventListener('click', () => {
|
|
transitionToScene('scene3', loadSceneDeveloper, 'sceneDeveloper');
|
|
});
|
|
document.getElementById('whatIsLabBtn').addEventListener('click', () => {
|
|
transitionToScene('scene2', loadScene3, 'scene3');
|
|
});
|
|
|
|
|
|
|
|
// Keyboard shortcuts for testing
|
|
document.addEventListener('keydown', (e) => {
|
|
if (e.key === 'Escape') {
|
|
// Escape alone: Skip current animation to text
|
|
|
|
// Scene 1 skip (rain or typewriter)
|
|
const textContainer = document.getElementById('textContainer');
|
|
const canvas = document.getElementById('matrixCanvas');
|
|
if (textContainer.style.visibility !== 'visible') {
|
|
canvas.style.opacity = '0.15';
|
|
skipScene1();
|
|
}
|
|
|
|
// Scene 2 skip (calm typing)
|
|
const scene2 = document.getElementById('scene2');
|
|
const s2Cursor = document.getElementById('scene2Cursor');
|
|
const s2Cursor2 = document.getElementById('scene2Cursor2');
|
|
const s2Message = document.getElementById('scene2Message');
|
|
const s2Message2 = document.getElementById('scene2Message2');
|
|
const s2Line2 = document.getElementById('scene2Line2');
|
|
const s2Btn = document.getElementById('whatIsLabBtn');
|
|
if (scene2.style.display === 'flex' && s2Btn.style.visibility !== 'visible') {
|
|
s2Cursor.style.display = 'none';
|
|
s2Cursor2.style.display = 'none';
|
|
s2Message.textContent = '...AND THAT AWARENESS HAS LED YOU HERE...';
|
|
s2Line2.style.display = 'flex';
|
|
s2Message2.textContent = 'TO LAB 484';
|
|
s2Btn.style.visibility = 'visible';
|
|
s2Btn.style.opacity = '1';
|
|
s2Btn.style.pointerEvents = 'auto';
|
|
}
|
|
|
|
// Scene 3 skip (recruit text typing)
|
|
const scene3 = document.getElementById('scene3');
|
|
const recruitLines = document.getElementById('scene3RecruitLines');
|
|
const rl1 = document.getElementById('scene3RecruitLine1');
|
|
const rt1 = document.getElementById('scene3RecruitText1');
|
|
const rCursor = document.getElementById('scene3RecruitCursor');
|
|
const creatorBtn = document.getElementById('creatorBtn');
|
|
const builderBtn = document.getElementById('builderBtn');
|
|
const developerBtn = document.getElementById('developerBtn');
|
|
if (scene3.style.display === 'flex' && creatorBtn.style.visibility !== 'visible') {
|
|
rCursor.style.display = 'none';
|
|
recruitLines.style.display = 'flex';
|
|
rl1.style.display = 'flex';
|
|
rt1.textContent = "THE LAB IS CONNECTING WITH PEOPLE WHO SEE WHAT'S HAPPENINGG - WHO KNOW CHANGE ISN'T OPTIONAL. WE'RE LOOKING FOR THOSE READY TO STEP IN AND SHAPE THE FUTURE";
|
|
[creatorBtn, builderBtn, developerBtn].forEach(btn => {
|
|
btn.style.display = 'block';
|
|
btn.style.visibility = 'visible';
|
|
btn.style.opacity = '1';
|
|
btn.style.pointerEvents = 'auto';
|
|
});
|
|
const fitInText = document.getElementById('scene3FitInText');
|
|
fitInText.textContent = 'WHERE DO YOU FIT IN?';
|
|
fitInText.style.visibility = 'visible';
|
|
fitInText.style.opacity = '1';
|
|
}
|
|
}
|
|
|
|
if (e.key === 'Delete') {
|
|
// Fast-forward to Scene 2
|
|
document.getElementById('matrixCanvas').style.display = 'none';
|
|
document.getElementById('textContainer').style.display = 'none';
|
|
document.getElementById('followBtn').style.display = 'none';
|
|
|
|
loadScene2(document.getElementById('scene2'));
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|