perf: replace live oasis background with loop
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
background: #030603;
|
background: #071108;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
font-feature-settings: "cv02", "cv03", "cv04", "cv11", "ss01";
|
font-feature-settings: "cv02", "cv03", "cv04", "cv11", "ss01";
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
@@ -12,28 +12,135 @@ html, body {
|
|||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: ui-sans-serif, system-ui, -apple-system, "SF Pro Text", "PingFang SC", "Noto Sans SC", "Helvetica Neue", sans-serif;
|
font-family: ui-sans-serif, system-ui, -apple-system, "SF Pro Text", "PingFang SC", "Noto Sans SC", "Helvetica Neue", sans-serif;
|
||||||
background-color: #030603;
|
background-color: #071108;
|
||||||
background-image: linear-gradient(180deg, rgba(13, 24, 12, 0.9), rgba(2, 4, 2, 1));
|
background-image: linear-gradient(180deg, rgba(22, 42, 16, 0.92), rgba(5, 12, 4, 1));
|
||||||
background-attachment: fixed;
|
background-attachment: fixed;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
::selection { background: rgba(230, 245, 120, 0.28); color: #fff; }
|
::selection { background: rgba(230, 245, 120, 0.28); color: #fff; }
|
||||||
|
|
||||||
|
.login-oasis-loop {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
pointer-events: none;
|
||||||
|
isolation: isolate;
|
||||||
|
contain: strict;
|
||||||
|
background: #0d1d0b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.oasis-loop__sky,
|
||||||
|
.oasis-loop__light,
|
||||||
|
.oasis-loop__haze,
|
||||||
|
.oasis-loop__grass,
|
||||||
|
.oasis-loop__grain {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.oasis-loop__sky {
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at 70% 22%, rgba(255, 238, 152, 0.42), transparent 26%),
|
||||||
|
radial-gradient(circle at 26% 56%, rgba(230, 245, 120, 0.24), transparent 34%),
|
||||||
|
linear-gradient(180deg, #2f4a23 0%, #172d12 42%, #0a1708 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.oasis-loop__light {
|
||||||
|
inset: -18%;
|
||||||
|
background:
|
||||||
|
conic-gradient(from 26deg at 72% 30%, transparent 0 18%, rgba(255, 240, 170, 0.18) 22%, transparent 36% 100%),
|
||||||
|
radial-gradient(ellipse at 68% 36%, rgba(230, 245, 120, 0.16), transparent 42%);
|
||||||
|
filter: blur(18px);
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.oasis-loop__haze {
|
||||||
|
inset: -8% -12%;
|
||||||
|
background:
|
||||||
|
linear-gradient(104deg, transparent 0 20%, rgba(255, 255, 220, 0.12) 24%, transparent 36% 100%),
|
||||||
|
linear-gradient(74deg, transparent 0 48%, rgba(214, 179, 106, 0.10) 56%, transparent 70% 100%),
|
||||||
|
repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.035) 0 1px, transparent 1px 70px);
|
||||||
|
mix-blend-mode: screen;
|
||||||
|
opacity: 0.82;
|
||||||
|
transform: translate3d(-1.5%, 0, 0) scale(1.04);
|
||||||
|
animation: oasis-haze-loop 18s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.oasis-loop__grass {
|
||||||
|
top: auto;
|
||||||
|
bottom: -9vh;
|
||||||
|
height: 55vh;
|
||||||
|
transform-origin: 50% 100%;
|
||||||
|
mask-image: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.7) 20%, #000 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.oasis-loop__grass--back {
|
||||||
|
opacity: 0.46;
|
||||||
|
background:
|
||||||
|
linear-gradient(180deg, transparent, rgba(61, 100, 42, 0.38) 34%, rgba(5, 18, 5, 0.94)),
|
||||||
|
repeating-linear-gradient(102deg, transparent 0 18px, rgba(214, 232, 130, 0.18) 18px 20px, transparent 20px 38px),
|
||||||
|
repeating-linear-gradient(83deg, transparent 0 24px, rgba(111, 160, 79, 0.22) 24px 26px, transparent 26px 48px);
|
||||||
|
animation: oasis-grass-loop 9s ease-in-out infinite alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
.oasis-loop__grass--front {
|
||||||
|
bottom: -13vh;
|
||||||
|
height: 49vh;
|
||||||
|
opacity: 0.58;
|
||||||
|
background:
|
||||||
|
linear-gradient(180deg, transparent, rgba(20, 52, 14, 0.46) 32%, rgba(1, 7, 1, 0.98)),
|
||||||
|
repeating-linear-gradient(107deg, transparent 0 10px, rgba(232, 246, 132, 0.22) 10px 12px, transparent 12px 26px),
|
||||||
|
repeating-linear-gradient(76deg, transparent 0 16px, rgba(76, 129, 54, 0.28) 16px 18px, transparent 18px 31px);
|
||||||
|
animation: oasis-grass-loop 7s ease-in-out infinite alternate-reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.oasis-loop__grain {
|
||||||
|
background-image:
|
||||||
|
linear-gradient(90deg, rgba(255, 255, 255, 0.032) 1px, transparent 1px),
|
||||||
|
linear-gradient(180deg, rgba(255, 255, 255, 0.026) 1px, transparent 1px);
|
||||||
|
background-size: 64px 64px;
|
||||||
|
opacity: 0.48;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes oasis-haze-loop {
|
||||||
|
0%, 100% { transform: translate3d(-1.5%, 0, 0) scale(1.04); }
|
||||||
|
50% { transform: translate3d(1.5%, -1%, 0) scale(1.06); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes oasis-grass-loop {
|
||||||
|
0% { transform: skewX(-0.6deg) translate3d(-0.5%, 0, 0); }
|
||||||
|
100% { transform: skewX(0.8deg) translate3d(0.5%, -1%, 0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.oasis-loop__haze,
|
||||||
|
.oasis-loop__grass {
|
||||||
|
animation: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.app-oasis .login-oasis-canvas {
|
.app-oasis .login-oasis-canvas {
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
opacity: 0.74;
|
opacity: 0.74;
|
||||||
filter: saturate(0.92) contrast(1.04);
|
filter: saturate(0.92) contrast(1.04);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.app-oasis .login-oasis-loop {
|
||||||
|
opacity: 1;
|
||||||
|
filter: saturate(1.08) brightness(1.2);
|
||||||
|
}
|
||||||
|
|
||||||
.app-oasis-shade {
|
.app-oasis-shade {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
background:
|
background:
|
||||||
linear-gradient(90deg, rgba(0, 0, 0, 0.76), rgba(3, 9, 3, 0.46) 42%, rgba(0, 0, 0, 0.72)),
|
linear-gradient(90deg, rgba(0, 0, 0, 0.42), rgba(9, 22, 7, 0.14) 42%, rgba(0, 0, 0, 0.42)),
|
||||||
linear-gradient(180deg, rgba(0, 0, 0, 0.68), rgba(0, 0, 0, 0.12) 36%, rgba(0, 0, 0, 0.82)),
|
linear-gradient(180deg, rgba(0, 0, 0, 0.28), rgba(0, 0, 0, 0.02) 36%, rgba(0, 0, 0, 0.54)),
|
||||||
linear-gradient(90deg, rgba(255, 255, 255, 0.026) 1px, transparent 1px),
|
linear-gradient(90deg, rgba(255, 255, 255, 0.026) 1px, transparent 1px),
|
||||||
linear-gradient(180deg, rgba(255, 255, 255, 0.022) 1px, transparent 1px);
|
linear-gradient(180deg, rgba(255, 255, 255, 0.022) 1px, transparent 1px);
|
||||||
background-size: auto, auto, 64px 64px, 64px 64px;
|
background-size: auto, auto, 64px 64px, 64px 64px;
|
||||||
@@ -47,11 +154,11 @@ body {
|
|||||||
z-index: 2;
|
z-index: 2;
|
||||||
height: 34vh;
|
height: 34vh;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
opacity: 0.38;
|
opacity: 0.46;
|
||||||
background:
|
background:
|
||||||
linear-gradient(180deg, transparent, rgba(5, 12, 4, 0.78) 60%, rgba(0, 0, 0, 0.94)),
|
linear-gradient(180deg, transparent, rgba(10, 25, 7, 0.62) 60%, rgba(0, 0, 0, 0.82)),
|
||||||
repeating-linear-gradient(103deg, transparent 0 13px, rgba(188, 218, 112, 0.13) 13px 14px, transparent 14px 28px),
|
repeating-linear-gradient(103deg, transparent 0 13px, rgba(204, 230, 120, 0.18) 13px 14px, transparent 14px 28px),
|
||||||
repeating-linear-gradient(78deg, transparent 0 18px, rgba(84, 122, 67, 0.18) 18px 20px, transparent 20px 34px);
|
repeating-linear-gradient(78deg, transparent 0 18px, rgba(98, 146, 76, 0.22) 18px 20px, transparent 20px 34px);
|
||||||
mask-image: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.8) 38%, #000 100%);
|
mask-image: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.8) 38%, #000 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,7 +363,7 @@ input, textarea {
|
|||||||
mix-blend-mode: screen;
|
mix-blend-mode: screen;
|
||||||
}
|
}
|
||||||
.login-page--oasis {
|
.login-page--oasis {
|
||||||
background: #030303;
|
background: #071108;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
.login-page--oasis::before {
|
.login-page--oasis::before {
|
||||||
@@ -270,8 +377,8 @@ input, textarea {
|
|||||||
.login-page--oasis::after {
|
.login-page--oasis::after {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
background:
|
background:
|
||||||
radial-gradient(circle at 50% 26%, rgba(214, 179, 106, 0.16), transparent 32%),
|
radial-gradient(circle at 50% 26%, rgba(230, 245, 120, 0.18), transparent 32%),
|
||||||
linear-gradient(90deg, rgba(0, 0, 0, 0.86), rgba(0, 0, 0, 0.34) 48%, rgba(0, 0, 0, 0.76));
|
linear-gradient(90deg, rgba(0, 0, 0, 0.58), rgba(0, 0, 0, 0.18) 48%, rgba(0, 0, 0, 0.48));
|
||||||
background-size: auto;
|
background-size: auto;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
mix-blend-mode: normal;
|
mix-blend-mode: normal;
|
||||||
@@ -283,7 +390,7 @@ input, textarea {
|
|||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
border: 0;
|
border: 0;
|
||||||
background: #030303;
|
background: #071108;
|
||||||
}
|
}
|
||||||
.login-oasis-shade {
|
.login-oasis-shade {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@@ -291,8 +398,8 @@ input, textarea {
|
|||||||
z-index: 2;
|
z-index: 2;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
background:
|
background:
|
||||||
linear-gradient(180deg, rgba(0, 0, 0, 0.62), rgba(0, 0, 0, 0.12) 42%, rgba(0, 0, 0, 0.74)),
|
linear-gradient(180deg, rgba(0, 0, 0, 0.42), rgba(0, 0, 0, 0.04) 42%, rgba(0, 0, 0, 0.58)),
|
||||||
radial-gradient(circle at 78% 50%, rgba(214, 179, 106, 0.12), transparent 32%);
|
radial-gradient(circle at 78% 50%, rgba(230, 245, 120, 0.14), transparent 32%);
|
||||||
}
|
}
|
||||||
.login-page--oasis .login-oasis-hero {
|
.login-page--oasis .login-oasis-hero {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
@@ -471,8 +578,8 @@ input, textarea {
|
|||||||
}
|
}
|
||||||
.login-page--source .login-oasis-shade {
|
.login-page--source .login-oasis-shade {
|
||||||
background:
|
background:
|
||||||
radial-gradient(circle at 34% 52%, rgba(230, 245, 120, 0.08), transparent 28%),
|
radial-gradient(circle at 34% 52%, rgba(230, 245, 120, 0.14), transparent 28%),
|
||||||
linear-gradient(90deg, rgba(0, 0, 0, 0.22), rgba(0, 0, 0, 0.04) 44%, rgba(0, 0, 0, 0.38));
|
linear-gradient(90deg, rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.02) 44%, rgba(0, 0, 0, 0.24));
|
||||||
}
|
}
|
||||||
.login-source-overlay {
|
.login-source-overlay {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@@ -1696,12 +1803,12 @@ input, textarea {
|
|||||||
background: linear-gradient(164deg, #f7f7f4 0 48%, #111214 48% 100%);
|
background: linear-gradient(164deg, #f7f7f4 0 48%, #111214 48% 100%);
|
||||||
}
|
}
|
||||||
.login-page--oasis {
|
.login-page--oasis {
|
||||||
background: #030303;
|
background: #071108;
|
||||||
}
|
}
|
||||||
.login-page--oasis::after {
|
.login-page--oasis::after {
|
||||||
background:
|
background:
|
||||||
radial-gradient(circle at 50% 34%, rgba(214, 179, 106, 0.16), transparent 40%),
|
radial-gradient(circle at 50% 34%, rgba(230, 245, 120, 0.18), transparent 40%),
|
||||||
linear-gradient(180deg, rgba(0, 0, 0, 0.72), rgba(0, 0, 0, 0.2) 48%, rgba(0, 0, 0, 0.82));
|
linear-gradient(180deg, rgba(0, 0, 0, 0.48), rgba(0, 0, 0, 0.08) 48%, rgba(0, 0, 0, 0.62));
|
||||||
}
|
}
|
||||||
.login-page--oasis .login-oasis-hero {
|
.login-page--oasis .login-oasis-hero {
|
||||||
min-height: 740px;
|
min-height: 740px;
|
||||||
|
|||||||
@@ -2,10 +2,16 @@
|
|||||||
|
|
||||||
import { useEffect, useRef } from 'react';
|
import { useEffect, useRef } from 'react';
|
||||||
|
|
||||||
export function OasisCanvas() {
|
type OasisCanvasProps = {
|
||||||
|
mode?: 'loop' | 'live';
|
||||||
|
};
|
||||||
|
|
||||||
|
export function OasisCanvas({ mode = 'loop' }: OasisCanvasProps) {
|
||||||
const frameRef = useRef<HTMLIFrameElement | null>(null);
|
const frameRef = useRef<HTMLIFrameElement | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (mode !== 'live') return;
|
||||||
|
|
||||||
const dispatchNativeMouseEvent = (type: 'mousemove' | 'mouseleave', event?: PointerEvent) => {
|
const dispatchNativeMouseEvent = (type: 'mousemove' | 'mouseleave', event?: PointerEvent) => {
|
||||||
const frameWindow = frameRef.current?.contentWindow;
|
const frameWindow = frameRef.current?.contentWindow;
|
||||||
if (!frameWindow) return false;
|
if (!frameWindow) return false;
|
||||||
@@ -52,7 +58,20 @@ export function OasisCanvas() {
|
|||||||
document.removeEventListener('pointermove', onPointerMove, listenerOptions);
|
document.removeEventListener('pointermove', onPointerMove, listenerOptions);
|
||||||
window.removeEventListener('pointerleave', onPointerLeave, listenerOptions);
|
window.removeEventListener('pointerleave', onPointerLeave, listenerOptions);
|
||||||
};
|
};
|
||||||
}, []);
|
}, [mode]);
|
||||||
|
|
||||||
|
if (mode === 'loop') {
|
||||||
|
return (
|
||||||
|
<div aria-hidden="true" className="login-oasis-loop">
|
||||||
|
<div className="oasis-loop__sky" />
|
||||||
|
<div className="oasis-loop__light" />
|
||||||
|
<div className="oasis-loop__haze" />
|
||||||
|
<div className="oasis-loop__grass oasis-loop__grass--back" />
|
||||||
|
<div className="oasis-loop__grass oasis-loop__grass--front" />
|
||||||
|
<div className="oasis-loop__grain" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<iframe
|
<iframe
|
||||||
|
|||||||
Reference in New Issue
Block a user