Replace the landing with the artifact design and rebuild the admin in Ant Design.
Adds consultation leads, section editors, and the one-time content reset for this release. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import type { Ref } from "vue";
|
||||
|
||||
/**
|
||||
* Scroll-scrubbed hero device parallax. GSAP is imported only on the client after mount,
|
||||
* keeping it off the critical rendering path; the context is reverted on unmount.
|
||||
*/
|
||||
export function useHeroScrollParallax(sectionEl: Ref<HTMLElement | null>) {
|
||||
let revert: (() => void) | null = null;
|
||||
let disposed = false;
|
||||
|
||||
onMounted(async () => {
|
||||
const [{ gsap }, { ScrollTrigger }] = await Promise.all([import("gsap"), import("gsap/ScrollTrigger")]);
|
||||
const root = sectionEl.value;
|
||||
if (disposed || !root) return;
|
||||
|
||||
gsap.registerPlugin(ScrollTrigger);
|
||||
const laptop = root.querySelector<HTMLElement>("#hero-laptop");
|
||||
const mobile = root.querySelector<HTMLElement>("#hero-mobile");
|
||||
if (!laptop || !mobile) return;
|
||||
|
||||
const ctx = gsap.context(() => {
|
||||
gsap.to(laptop, {
|
||||
scrollTrigger: { trigger: root, start: "top top", end: "bottom top", scrub: 1.2 },
|
||||
y: -40,
|
||||
rotateY: -25,
|
||||
rotateX: 13,
|
||||
scale: 0.98,
|
||||
ease: "none",
|
||||
});
|
||||
gsap.to(mobile, {
|
||||
scrollTrigger: { trigger: root, start: "top top", end: "bottom top", scrub: 1.5 },
|
||||
y: -85,
|
||||
rotateY: -6,
|
||||
rotateX: 4,
|
||||
scale: 1.03,
|
||||
ease: "none",
|
||||
});
|
||||
}, root);
|
||||
revert = () => ctx.revert();
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
disposed = true;
|
||||
revert?.();
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user