fix(frontend): add hero tilt animation and stronger landing parity
This commit is contained in:
parent
973ec59b69
commit
e3b857a767
2 changed files with 29 additions and 2 deletions
|
|
@ -930,6 +930,8 @@ body {
|
|||
.lp-hero-slider {
|
||||
position: relative;
|
||||
min-height: 370px;
|
||||
transition: transform 260ms ease;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.lp-float-card {
|
||||
|
|
|
|||
|
|
@ -239,6 +239,8 @@ export default function PublicLanding() {
|
|||
const [scrolled, setScrolled] = createSignal(false);
|
||||
const [mobileOpen, setMobileOpen] = createSignal(false);
|
||||
const [scrollY, setScrollY] = createSignal(0);
|
||||
const [reduceMotion, setReduceMotion] = createSignal(false);
|
||||
const [heroTilt, setHeroTilt] = createSignal({ x: 0, y: 0 });
|
||||
const [heroIdx, setHeroIdx] = createSignal(0);
|
||||
const [filter, setFilter] = createSignal<'all' | 'customer' | 'professional' | 'company' | 'job_seeker'>('all');
|
||||
const [pathPage, setPathPage] = createSignal(0);
|
||||
|
|
@ -249,6 +251,10 @@ export default function PublicLanding() {
|
|||
const [openFaq, setOpenFaq] = createSignal(0);
|
||||
|
||||
onMount(() => {
|
||||
const media = window.matchMedia('(prefers-reduced-motion: reduce)');
|
||||
const syncMotion = () => setReduceMotion(media.matches);
|
||||
syncMotion();
|
||||
|
||||
const onScroll = () => {
|
||||
setScrolled(window.scrollY > 10);
|
||||
setScrollY(window.scrollY || 0);
|
||||
|
|
@ -271,6 +277,7 @@ export default function PublicLanding() {
|
|||
syncCardsPerPage();
|
||||
window.addEventListener('scroll', onScroll, { passive: true });
|
||||
window.addEventListener('resize', syncCardsPerPage);
|
||||
media.addEventListener('change', syncMotion);
|
||||
|
||||
const heroTimer = window.setInterval(() => setHeroIdx((x) => (x + 1) % heroSlides.length), 3500);
|
||||
const pathTimer = window.setInterval(() => setPathPage((x) => x + 1), 4200);
|
||||
|
|
@ -288,6 +295,7 @@ export default function PublicLanding() {
|
|||
onCleanup(() => {
|
||||
window.removeEventListener('scroll', onScroll);
|
||||
window.removeEventListener('resize', syncCardsPerPage);
|
||||
media.removeEventListener('change', syncMotion);
|
||||
window.clearInterval(heroTimer);
|
||||
window.clearInterval(pathTimer);
|
||||
window.clearInterval(benefitTimer);
|
||||
|
|
@ -377,7 +385,17 @@ export default function PublicLanding() {
|
|||
</Show>
|
||||
</header>
|
||||
|
||||
<section class="public-hero scene-dark">
|
||||
<section
|
||||
class="public-hero scene-dark"
|
||||
onMouseMove={(event) => {
|
||||
if (reduceMotion()) return;
|
||||
const rect = event.currentTarget.getBoundingClientRect();
|
||||
const px = (event.clientX - rect.left) / rect.width - 0.5;
|
||||
const py = (event.clientY - rect.top) / rect.height - 0.5;
|
||||
setHeroTilt({ x: px * 14, y: py * 12 });
|
||||
}}
|
||||
onMouseLeave={() => setHeroTilt({ x: 0, y: 0 })}
|
||||
>
|
||||
<div class="container lp-hero-grid">
|
||||
<div>
|
||||
<h1 class="lp-hero-title">Hire verified professionals. Post jobs. Get approvals in 24-48 hours.</h1>
|
||||
|
|
@ -389,7 +407,14 @@ export default function PublicLanding() {
|
|||
<A class="btn ghost-dark" href="/onboarding?schemaId=jobseeker_onboarding_v1">Apply for Jobs</A>
|
||||
</div>
|
||||
</div>
|
||||
<div class="lp-hero-slider">
|
||||
<div
|
||||
class="lp-hero-slider"
|
||||
style={{
|
||||
transform: reduceMotion()
|
||||
? 'none'
|
||||
: `translate3d(${heroTilt().x}px, ${heroTilt().y}px, 0)`,
|
||||
}}
|
||||
>
|
||||
<For each={heroSlides}>
|
||||
{(slide, idx) => (
|
||||
<article class={`lp-float-card ${idx() === heroIdx() ? 'active' : ''}`}>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue