entrada suave no video, loader com logo e login vazio
This commit is contained in:
parent
d0f3ba8655
commit
6cc1a2bc00
@ -88,34 +88,24 @@ h3,
|
|||||||
z-index: 50;
|
z-index: 50;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 1rem;
|
|
||||||
background: #000;
|
background: #000;
|
||||||
color: #e8f4e5;
|
|
||||||
letter-spacing: 0.18em;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-size: 0.72rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.orbit-loader-dot {
|
.orbit-loader-logo {
|
||||||
width: 10px;
|
width: min(11.5rem, 58vw);
|
||||||
height: 10px;
|
height: auto;
|
||||||
border-radius: 999px;
|
animation: loader-glow 1.6s ease-in-out infinite;
|
||||||
background: #82c85c;
|
|
||||||
animation: loader-pulse 1s ease-in-out infinite;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes loader-pulse {
|
@keyframes loader-glow {
|
||||||
0%,
|
0%,
|
||||||
100% {
|
100% {
|
||||||
opacity: 0.35;
|
opacity: 0.4;
|
||||||
transform: scale(1);
|
|
||||||
}
|
}
|
||||||
50% {
|
50% {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: scale(1.35);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,10 @@ type ScrollFilmProps = {
|
|||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function easeInOutCubic(value: number) {
|
||||||
|
return value < 0.5 ? 4 * value * value * value : 1 - (-2 * value + 2) ** 3 / 2;
|
||||||
|
}
|
||||||
|
|
||||||
export function ScrollFilm({ src, poster, children }: ScrollFilmProps) {
|
export function ScrollFilm({ src, poster, children }: ScrollFilmProps) {
|
||||||
const orbitRef = useRef<HTMLDivElement>(null);
|
const orbitRef = useRef<HTMLDivElement>(null);
|
||||||
const filmRef = useRef<HTMLVideoElement>(null);
|
const filmRef = useRef<HTMLVideoElement>(null);
|
||||||
@ -30,6 +34,9 @@ export function ScrollFilm({ src, poster, children }: ScrollFilmProps) {
|
|||||||
let current = 0;
|
let current = 0;
|
||||||
let frame = 0;
|
let frame = 0;
|
||||||
let blobUrl: string | null = null;
|
let blobUrl: string | null = null;
|
||||||
|
let introStartedAt = 0;
|
||||||
|
let introDone = false;
|
||||||
|
const introMs = 2400;
|
||||||
|
|
||||||
const markReady = () => {
|
const markReady = () => {
|
||||||
if (ready) {
|
if (ready) {
|
||||||
@ -39,6 +46,9 @@ export function ScrollFilm({ src, poster, children }: ScrollFilmProps) {
|
|||||||
film.pause();
|
film.pause();
|
||||||
film.classList.add("is-ready");
|
film.classList.add("is-ready");
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
||||||
|
introDone = reduce;
|
||||||
|
introStartedAt = reduce ? 0 : performance.now();
|
||||||
};
|
};
|
||||||
|
|
||||||
fetch(src)
|
fetch(src)
|
||||||
@ -59,13 +69,33 @@ export function ScrollFilm({ src, poster, children }: ScrollFilmProps) {
|
|||||||
return y / total;
|
return y / total;
|
||||||
};
|
};
|
||||||
|
|
||||||
const tick = () => {
|
const introSeconds = (now: number, duration: number) => {
|
||||||
|
if (introDone || !introStartedAt) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (progressFromScroll() > 0.02) {
|
||||||
|
introDone = true;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const elapsed = now - introStartedAt;
|
||||||
|
const t = Math.min(elapsed / introMs, 1);
|
||||||
|
const peak = Math.min(2, Math.max(duration * 0.22, 0.6));
|
||||||
|
const trip = t < 0.5 ? easeInOutCubic(t * 2) : 1 - easeInOutCubic((t - 0.5) * 2);
|
||||||
|
if (t >= 1) {
|
||||||
|
introDone = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return trip * peak;
|
||||||
|
};
|
||||||
|
|
||||||
|
const tick = (now: number) => {
|
||||||
const target = progressFromScroll();
|
const target = progressFromScroll();
|
||||||
current += (target - current) * 0.42;
|
current += (target - current) * 0.42;
|
||||||
orbit.style.setProperty("--scrub", current.toFixed(4));
|
orbit.style.setProperty("--scrub", current.toFixed(4));
|
||||||
|
|
||||||
if (ready && film.duration && !film.seeking) {
|
if (ready && film.duration && !film.seeking) {
|
||||||
const time = current * (film.duration - 0.04);
|
const intro = introSeconds(now, film.duration);
|
||||||
|
const time = intro ?? current * (film.duration - 0.04);
|
||||||
if (Math.abs(film.currentTime - time) >= 0.02) {
|
if (Math.abs(film.currentTime - time) >= 0.02) {
|
||||||
film.currentTime = time;
|
film.currentTime = time;
|
||||||
}
|
}
|
||||||
@ -104,9 +134,8 @@ export function ScrollFilm({ src, poster, children }: ScrollFilmProps) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="orbit-story">{children}</div>
|
<div className="orbit-story">{children}</div>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<div className="orbit-loader" role="status" aria-live="polite">
|
<div className="orbit-loader" role="status" aria-live="polite" aria-label="Sinka">
|
||||||
<span className="orbit-loader-dot" />
|
<img src="/brand/sinka-logo.webp" alt="Sinka" className="orbit-loader-logo" />
|
||||||
<p>Carregando Sinka</p>
|
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -19,10 +19,8 @@ export function LoginForm({
|
|||||||
google_unlinked: "Este e-mail Google não tem acesso à administração.",
|
google_unlinked: "Este e-mail Google não tem acesso à administração.",
|
||||||
google_denied: "Não foi possível entrar com o Google.",
|
google_denied: "Não foi possível entrar com o Google.",
|
||||||
}[search.get("error") ?? ""];
|
}[search.get("error") ?? ""];
|
||||||
const [email, setEmail] = useState(
|
const [email, setEmail] = useState("");
|
||||||
variant === "admin" ? "tina.r@example.net" : "xena.w@example.org",
|
const [password, setPassword] = useState("");
|
||||||
);
|
|
||||||
const [password, setPassword] = useState(variant === "admin" ? "SinkaPlatform!1" : "SinkaAdmin!1");
|
|
||||||
const [error, setError] = useState("");
|
const [error, setError] = useState("");
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user