PageSourceSearch

https://stelliverse.fr/experience/timeline.mjs

js stelliverse.fr collected 2026-10-03 20:11:04 UTC 3,793 bytes, 57 lines download raw bytes

1// Une seule position pilote l'objet, la caméra, les masques et les démonstrations.
2export const clamp = (n, a = 0, b = 1) => Math.max(a, Math.min(b, n));
3export const lerp = (a, b, t) => a + (b - a) * t;
4// Jeton hérité --ease-in-out: cubic-bezier(.77, 0, .175, 1).
5export function ease(x) {
6  x = clamp(x); let lo = 0, hi = 1, t = x;
7  if (x <= 0 || x >= 1) return x;
8  for (let i = 0; i < 22; i++) {
9    t = (lo + hi) / 2; const u = 1 - t;
10    if (3 * u * u * t * .77 + 3 * u * t * t * .175 + t * t * t < x) lo = t; else hi = t;
11  }
12  return 3 * (1 - t) * t * t + t * t * t;
13}
14export const phase = (p, a, b) => ease((p - a) / (b - a));
15export const windowAt = (p, a, b, c, d) => phase(p, a, b) * (1 - phase(p, c, d));
16// Keep the opening copy above the projected screenshot, including its idle tilt.
17export function openingProductFrame(copyBottom, height, scale, mobile = false) {
18  const shortMobile=mobile&&height<740;
19  const top = copyBottom + (shortMobile?12:24);
20  const bottom = Math.max(top, height - (mobile ? shortMobile?64:128 : 72));
21  return {y: (top + bottom) / 2 / height * 100, scale: Math.min(scale, (bottom - top) / (625 * 1.18))};
22}
23export const chapters = [
24  {id: 'application', at: 0, label: 'L’application', title: 'Stelliverse.', text: 'Votre compagnon pour Star Citizen.'},
25  {id: 'preparer', at: .235, label: 'Préparer', title: 'Le départ se prépare ici.', text: 'Votre hangar. Le bon équipement. Vos objectifs. Avant même de rejoindre le Verse.'},
26  {id: 'hub', at: .393, label: 'En jeu', title: 'Tout se replie. Rien ne vous quitte.', text: 'Une touche : le hub s’ouvre. Vos outils sont toujours à portée de main.'},
27  {id: 'prix', at: .524, label: 'Comparer', title: 'Une recherche. Une décision.', text: 'Quantanium. Les offres apparaissent. Vous comparez les lieux, puis gardez la main sur votre choix.'},
28  {id: 'missions', at: .68, label: 'Organiser', title: 'Chaque arrêt a une raison.', text: 'Prendre ici. Livrer là. Regroupez vos étapes et voyez ce qu’il reste à faire.'},
29  {id: 'carte', at: .79, label: 'Se repérer', title: 'Le lieu devient un monde.', text: 'Les noms prennent leur place dans la carte stellaire. Retrouvez vos repères et votre destination.'},
30  {id: 'ensemble', at: .94, label: 'Votre session', title: 'Tout votre Verse. Un seul compagnon.', text: 'Minage, Wikelo, missions, amis, traductions… Toute la session se retrouve dans Stelliverse.'}
31];
32const poses = [
33  [0, 50, 61, 1, 7, -8, -2], [.07, 50, 60, 1.12, 2, -2, 0],
34  [.17, 67, 57, .91, 4, -17, 1], [.26, 67, 57, .98, 0, -7, 0],
35  [.315, 63, 53, .95, 0, 0, 0], [.385, 65, 57, 1.05, 0, -6, 0],
36  [.465, 66, 58, .96, 2, -10, 0], [.575, 65, 58, 1.03, 0, -3, 0],
37  [.665, 66, 57, 1.02, 0, -7, 0], [.705, 63, 57, .91, 6, -15, -2],
38  [.78, 34, 69, .58, 14, 18, -5], [.85, 34, 69, .58, 6, 8, -2],
39  [.925, 67, 57, .86, 4, -9, 0], [1, 67, 57, .93, 0, -3, 0]
40];
41export function poseAt(progress) {
42  const p = clamp(progress);
43  let i = poses.findIndex((k, n) => n < poses.length - 1 && p <= poses[n + 1][0]);
44  if (i < 0) i = poses.length - 2;
45  const a = poses[i], b = poses[i + 1], t = phase(p, a[0], b[0]);
46  return {x: lerp(a[1], b[1], t), y: lerp(a[2], b[2], t), scale: lerp(a[3], b[3], t), rx: lerp(a[4], b[4], t), ry: lerp(a[5], b[5], t), rz: lerp(a[6], b[6], t)};
47}
48export function sceneAt(p) {
49  return p < .125 ? 0 : p < .29 ? 1 : p < .425 ? 2 : p < .605 ? 3 : p < .725 ? 4 : p < .885 ? 5 : 6;
50}
51export function presentationPose(p, mobile = false) {
52  const pose = poseAt(p);
53  if (!mobile) return pose;
54  // Keep the full-width mobile preview; only desktop moves beside the planet.
55  const mapScale=.40*windowAt(p,.705,.78,.85,.925);
56  return {...pose, x: 50, y: 58 + 3 * phase(p, .085, .16) + 5 * phase(p, .86, .925), scale:pose.scale+mapScale};
57}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.