Initial commit: RHINE LAB · ANALYSIS OS:三维界面与动效实验(本仓库不含个人归档索引数据)
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
// Original footage is 25 fps. App time zero corresponds to video time 5 s.
|
||||
// Discrete editorial cuts use frame numbers; spatial motion uses continuous time.
|
||||
import { brandTrack, companyTrack, scanTrack, track } from "./boot-tracks";
|
||||
import { scanOrbitTrack } from "./boot-orbit-tracks";
|
||||
import { bootLogoTrack } from "./boot-logo-tracks";
|
||||
export const progress = (t: number, a: number, b: number) =>
|
||||
Math.max(0, Math.min(1, (t - a) / (b - a)));
|
||||
export const smooth = (p: number) => p * p * (3 - 2 * p);
|
||||
const typed = (text: string, f: number, start: number, end: number) =>
|
||||
text.slice(
|
||||
0,
|
||||
f < start
|
||||
? 0
|
||||
: Math.min(
|
||||
text.length,
|
||||
1 + Math.floor(((f - start) * (text.length - 1)) / (end - start)),
|
||||
),
|
||||
);
|
||||
const at = (f: number, frames: number[]) => frames.includes(f);
|
||||
const accessCounts = [
|
||||
1, 1, 3, 4, 5, 6, 9, 11, 12, 14, 17, 18, 19, 20, 22, 23, 25, 26,
|
||||
];
|
||||
|
||||
export function bootMotion(appTime: number) {
|
||||
const t = appTime + 5;
|
||||
const f = Math.floor(t * 25 + 0.00001);
|
||||
const step =
|
||||
t < 9.12
|
||||
? "access"
|
||||
: t < 11.12
|
||||
? "logo"
|
||||
: t < 19.48
|
||||
? "auth"
|
||||
: t < 22.76
|
||||
? "scan"
|
||||
: "welcome";
|
||||
let auth = "";
|
||||
if (f < 363) {
|
||||
auth = typed("ID CONFIRMED", f, 282, 295);
|
||||
if (f >= 320) auth += " : " + typed("JOYCE MOORE", f, 321, 339);
|
||||
} else if (f < 421) auth = typed("REQUEST RECEIVED", f, 367, 389);
|
||||
else {
|
||||
auth = typed("START PROCESSING", f, 423, 440);
|
||||
if (f >= 449)
|
||||
auth += ".".repeat(Math.min(3, 1 + Math.floor((f - 449) / 4)));
|
||||
if (at(f, [479, 485, 486])) auth = " SING...";
|
||||
}
|
||||
const frame = t * 25;
|
||||
const scan = scanTrack(frame);
|
||||
const scanOrbit = scanOrbitTrack(frame);
|
||||
const scanGlitch = at(f, [525, 526, 528, 529]);
|
||||
const welcomeIntro = [1, 0, 0.28, 0, 1, 0, 0];
|
||||
const flashIndex = f - 569;
|
||||
const exit = smooth(progress(t, 26.56, 26.92));
|
||||
return {
|
||||
t,
|
||||
f,
|
||||
step,
|
||||
auth,
|
||||
access: "ACCESS PERMISSION REQUIRED".slice(
|
||||
0,
|
||||
f < 170 ? 0 : accessCounts[Math.min(17, f - 170)],
|
||||
),
|
||||
accessOpacity: f >= 170 && f < 227 ? (f === 226 ? 0.25 : 1) : 0,
|
||||
logoOpacity: t >= 9.16 && t < 19.48 ? 1 : 0,
|
||||
logo: bootLogoTrack(frame),
|
||||
logoLetters: typed("RHINE·LAB", f, 232, 255),
|
||||
authOpacity: f >= 281 && f < 487 ? 1 : 0,
|
||||
brand: [0, 1, 2].map((line) => brandTrack(frame, line)),
|
||||
poweredLetters: typed("POWERED BY RHINE LAB", f, 279, 295).length,
|
||||
scanVisible: t >= 19.48 && t < 22.76,
|
||||
scan,
|
||||
scanOrbit,
|
||||
scanRadius: scan.radius,
|
||||
ringScale: scanGlitch ? 1.94 : 1,
|
||||
ringOpacity: scanGlitch
|
||||
? 0.32
|
||||
: track(
|
||||
[
|
||||
[487, 0],
|
||||
[488, 0.18],
|
||||
[490, 0.6],
|
||||
[493, 1],
|
||||
],
|
||||
frame,
|
||||
),
|
||||
ringBlur: scanGlitch ? 2.2 : 0,
|
||||
scanTracking: track(
|
||||
[
|
||||
[487, 40],
|
||||
[492, 28],
|
||||
[497, 18],
|
||||
[500, 14],
|
||||
[505, 8],
|
||||
[510, 4],
|
||||
[515, 1.7],
|
||||
[520, 0.5],
|
||||
[527, 0],
|
||||
[568, 0],
|
||||
],
|
||||
frame,
|
||||
),
|
||||
scanFont: 26.5,
|
||||
permissionOpacity:
|
||||
t < 21.8
|
||||
? progress(t, 19.48, 19.88)
|
||||
: track(
|
||||
[
|
||||
[545, 1],
|
||||
[546, 0.4],
|
||||
[547, 0.3],
|
||||
[548, 0.25],
|
||||
[549, 0.1],
|
||||
[550, 0.04],
|
||||
[551, 0],
|
||||
],
|
||||
frame,
|
||||
),
|
||||
ornament: t >= 21.84,
|
||||
coreRadius: scanOrbit.coreRadius,
|
||||
welcomeVisible: t >= 22.76 && t < 26.92,
|
||||
welcomePanel:
|
||||
flashIndex >= 0 && flashIndex < 7 ? welcomeIntro[flashIndex] : 0,
|
||||
welcomeInk:
|
||||
flashIndex >= 0 && flashIndex < 7
|
||||
? [0, 0, 0.2, 1, 0, 0, 0.25][flashIndex]
|
||||
: 1,
|
||||
companyVisible: f >= 588 && !at(f, [590, 591]),
|
||||
companyMask: at(f, [594, 595]),
|
||||
highlight: companyTrack(frame),
|
||||
databaseOpacity: f < 626 || at(f, [628, 629, 631, 634]) ? 0 : 1,
|
||||
welcomeLogo: f >= 588,
|
||||
welcomeScale: 1 - 0.46 * exit,
|
||||
welcomeOpacity: 1 - Math.pow(exit, 3),
|
||||
exitBlur: 8 * exit,
|
||||
exit,
|
||||
backgroundOpacity: t < 26.92 ? 1 : 0,
|
||||
white: smooth(progress(t, 26.16, 26.88)),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user