TEMPLATES & FRAMER OVERRIDES

Explore our growing library of templates, Framer custom components, overrides and code components.

Templates

AVAILABLE
SOON

NICHE

BUSINESS

WHAT

FRAMER TEMPlate

Framer Template

Coming

soon

WHAT

FRAMER TEMPLATE

NICHE

PUB/FOOD

Framer Overrides

IMAGE PARALLAX

COPY

import { useRef, type ComponentType } from "react"
import { createStore } from "https://framer.com/m/framer/store.js@^1.0.0"
import { motion, useScroll, useTransform } from "framer-motion"


export function imageParallax160px(
    Component
): ComponentType {
    return function ScrollTranslateYOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null)

        // Use Framer Motion's useScroll to track scroll progress
        const { scrollYProgress } = useScroll({
            target: componentRef, // Attach scroll tracking to this component
            offset: ["start end", "end start"], // Animation starts when top enters and ends when bottom leaves
        })

        // Map scrollYProgress (0 to 1) to a translateY value (e.g., 50px to -50px)
        const y = useTransform(scrollYProgress, [0, 1], [0, 160])

        return (
            <motion.div
                ref={componentRef}
                style={{
                    ...props.style,
                    position: "absolute",
                    inset: 0,
                    translateY: y, // Bind the y translation to the motion value
                }}
            >
                <Component {...props} />
            </motion.div>
        )
    }
}

IMAGE PARALLAX

COPY

import { useRef, type ComponentType } from "react"
import { createStore } from "https://framer.com/m/framer/store.js@^1.0.0"
import { motion, useScroll, useTransform } from "framer-motion"


export function imageParallax160px(
    Component
): ComponentType {
    return function ScrollTranslateYOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null)

        // Use Framer Motion's useScroll to track scroll progress
        const { scrollYProgress } = useScroll({
            target: componentRef, // Attach scroll tracking to this component
            offset: ["start end", "end start"], // Animation starts when top enters and ends when bottom leaves
        })

        // Map scrollYProgress (0 to 1) to a translateY value (e.g., 50px to -50px)
        const y = useTransform(scrollYProgress, [0, 1], [0, 160])

        return (
            <motion.div
                ref={componentRef}
                style={{
                    ...props.style,
                    position: "absolute",
                    inset: 0,
                    translateY: y, // Bind the y translation to the motion value
                }}
            >
                <Component {...props} />
            </motion.div>
        )
    }
}

IMAGE PARALLAX

COPY

import { useRef, type ComponentType } from "react"
import { createStore } from "https://framer.com/m/framer/store.js@^1.0.0"
import { motion, useScroll, useTransform } from "framer-motion"


export function imageParallax160px(
    Component
): ComponentType {
    return function ScrollTranslateYOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null)

        // Use Framer Motion's useScroll to track scroll progress
        const { scrollYProgress } = useScroll({
            target: componentRef, // Attach scroll tracking to this component
            offset: ["start end", "end start"], // Animation starts when top enters and ends when bottom leaves
        })

        // Map scrollYProgress (0 to 1) to a translateY value (e.g., 50px to -50px)
        const y = useTransform(scrollYProgress, [0, 1], [0, 160])

        return (
            <motion.div
                ref={componentRef}
                style={{
                    ...props.style,
                    position: "absolute",
                    inset: 0,
                    translateY: y, // Bind the y translation to the motion value
                }}
            >
                <Component {...props} />
            </motion.div>
        )
    }
}

IMAGE PARALLAX

COPY

import { useRef, type ComponentType } from "react"
import { createStore } from "https://framer.com/m/framer/store.js@^1.0.0"
import { motion, useScroll, useTransform } from "framer-motion"


export function imageParallax160px(
    Component
): ComponentType {
    return function ScrollTranslateYOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null)

        // Use Framer Motion's useScroll to track scroll progress
        const { scrollYProgress } = useScroll({
            target: componentRef, // Attach scroll tracking to this component
            offset: ["start end", "end start"], // Animation starts when top enters and ends when bottom leaves
        })

        // Map scrollYProgress (0 to 1) to a translateY value (e.g., 50px to -50px)
        const y = useTransform(scrollYProgress, [0, 1], [0, 160])

        return (
            <motion.div
                ref={componentRef}
                style={{
                    ...props.style,
                    position: "absolute",
                    inset: 0,
                    translateY: y, // Bind the y translation to the motion value
                }}
            >
                <Component {...props} />
            </motion.div>
        )
    }
}

MAGNETIC BEHAVIOR

COPY

import {
    useMotionValue,
    useTransform,
    motion,
    animate,
    useScroll,
    useSpring,
} from "framer-motion"
import { useEffect, useState, ComponentType, useRef } from "react"
import gsap from "gsap"

export function withMagneticBehavior(Component): ComponentType {
    return function MagneticOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null)

        // Motion values for x and y
        const x = useMotionValue(0)
        const y = useMotionValue(0)

        // Smooth spring animations for the magnetic effect
        const springX = useSpring(x, { stiffness: 250, damping: 30 })
        const springY = useSpring(y, { stiffness: 250, damping: 30 })

        const strength = 50 // Magnetic strength

        const handleMouseMove = (event: React.PointerEvent) => {
            if (event.pointerType !== "mouse") return // Ignore non-mouse inputs

            const bounding = componentRef.current.getBoundingClientRect()
            const offsetX =
                ((event.clientX - bounding.left) / bounding.width - 0.5) *
                strength
            const offsetY =
                ((event.clientY - bounding.top) / bounding.height - 0.5) *
                strength

            x.set(offsetX)
            y.set(offsetY)
        }

        const handleMouseOut = (event: React.PointerEvent) => {
            if (event.pointerType !== "mouse") return // Ignore non-mouse inputs

            x.set(0)
            y.set(0)
        }

        return (
            <motion.div
                ref={componentRef}
                style={{
                    position: "relative",
                    x: springX,
                    y: springY,
                }}
                onPointerMove={handleMouseMove}
                onPointerLeave={handleMouseOut}
            >
                <Component {...props} />
            </motion.div>
        )
    }
}

MAGNETIC BEHAVIOR

COPY

import {
    useMotionValue,
    useTransform,
    motion,
    animate,
    useScroll,
    useSpring,
} from "framer-motion"
import { useEffect, useState, ComponentType, useRef } from "react"
import gsap from "gsap"

export function withMagneticBehavior(Component): ComponentType {
    return function MagneticOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null)

        // Motion values for x and y
        const x = useMotionValue(0)
        const y = useMotionValue(0)

        // Smooth spring animations for the magnetic effect
        const springX = useSpring(x, { stiffness: 250, damping: 30 })
        const springY = useSpring(y, { stiffness: 250, damping: 30 })

        const strength = 50 // Magnetic strength

        const handleMouseMove = (event: React.PointerEvent) => {
            if (event.pointerType !== "mouse") return // Ignore non-mouse inputs

            const bounding = componentRef.current.getBoundingClientRect()
            const offsetX =
                ((event.clientX - bounding.left) / bounding.width - 0.5) *
                strength
            const offsetY =
                ((event.clientY - bounding.top) / bounding.height - 0.5) *
                strength

            x.set(offsetX)
            y.set(offsetY)
        }

        const handleMouseOut = (event: React.PointerEvent) => {
            if (event.pointerType !== "mouse") return // Ignore non-mouse inputs

            x.set(0)
            y.set(0)
        }

        return (
            <motion.div
                ref={componentRef}
                style={{
                    position: "relative",
                    x: springX,
                    y: springY,
                }}
                onPointerMove={handleMouseMove}
                onPointerLeave={handleMouseOut}
            >
                <Component {...props} />
            </motion.div>
        )
    }
}

MAGNETIC BEHAVIOR

COPY

import {
    useMotionValue,
    useTransform,
    motion,
    animate,
    useScroll,
    useSpring,
} from "framer-motion"
import { useEffect, useState, ComponentType, useRef } from "react"
import gsap from "gsap"

export function withMagneticBehavior(Component): ComponentType {
    return function MagneticOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null)

        // Motion values for x and y
        const x = useMotionValue(0)
        const y = useMotionValue(0)

        // Smooth spring animations for the magnetic effect
        const springX = useSpring(x, { stiffness: 250, damping: 30 })
        const springY = useSpring(y, { stiffness: 250, damping: 30 })

        const strength = 50 // Magnetic strength

        const handleMouseMove = (event: React.PointerEvent) => {
            if (event.pointerType !== "mouse") return // Ignore non-mouse inputs

            const bounding = componentRef.current.getBoundingClientRect()
            const offsetX =
                ((event.clientX - bounding.left) / bounding.width - 0.5) *
                strength
            const offsetY =
                ((event.clientY - bounding.top) / bounding.height - 0.5) *
                strength

            x.set(offsetX)
            y.set(offsetY)
        }

        const handleMouseOut = (event: React.PointerEvent) => {
            if (event.pointerType !== "mouse") return // Ignore non-mouse inputs

            x.set(0)
            y.set(0)
        }

        return (
            <motion.div
                ref={componentRef}
                style={{
                    position: "relative",
                    x: springX,
                    y: springY,
                }}
                onPointerMove={handleMouseMove}
                onPointerLeave={handleMouseOut}
            >
                <Component {...props} />
            </motion.div>
        )
    }
}

MAGNETIC BEHAVIOR

COPY

import {
    useMotionValue,
    useTransform,
    motion,
    animate,
    useScroll,
    useSpring,
} from "framer-motion"
import { useEffect, useState, ComponentType, useRef } from "react"
import gsap from "gsap"

export function withMagneticBehavior(Component): ComponentType {
    return function MagneticOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null)

        // Motion values for x and y
        const x = useMotionValue(0)
        const y = useMotionValue(0)

        // Smooth spring animations for the magnetic effect
        const springX = useSpring(x, { stiffness: 250, damping: 30 })
        const springY = useSpring(y, { stiffness: 250, damping: 30 })

        const strength = 50 // Magnetic strength

        const handleMouseMove = (event: React.PointerEvent) => {
            if (event.pointerType !== "mouse") return // Ignore non-mouse inputs

            const bounding = componentRef.current.getBoundingClientRect()
            const offsetX =
                ((event.clientX - bounding.left) / bounding.width - 0.5) *
                strength
            const offsetY =
                ((event.clientY - bounding.top) / bounding.height - 0.5) *
                strength

            x.set(offsetX)
            y.set(offsetY)
        }

        const handleMouseOut = (event: React.PointerEvent) => {
            if (event.pointerType !== "mouse") return // Ignore non-mouse inputs

            x.set(0)
            y.set(0)
        }

        return (
            <motion.div
                ref={componentRef}
                style={{
                    position: "relative",
                    x: springX,
                    y: springY,
                }}
                onPointerMove={handleMouseMove}
                onPointerLeave={handleMouseOut}
            >
                <Component {...props} />
            </motion.div>
        )
    }
}

COMPONENT PARALLAX

COPY

import { useRef, type ComponentType } from "react"
import { createStore } from "https://framer.com/m/framer/store.js@^1.0.0"
import { motion, useScroll, useTransform } from "framer-motion"

// Learn more: https://www.framer.com/developers/overrides/
export function withScrollTranslateY100(Component): ComponentType {
    return function ScrollTranslateYOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null)

        // Use Framer Motion's useScroll to track scroll progress
        const { scrollYProgress } = useScroll({
            target: componentRef, // Attach scroll tracking to this component
            offset: ["start end", "end start"], // Animation starts when top enters and ends when bottom leaves
        })

        // Map scrollYProgress (0 to 1) to a translateY value (e.g., 50px to -50px)
        const y = useTransform(scrollYProgress, [0, 1], [150, -150])

        return (
            <motion.div
                ref={componentRef}
                style={{
                    ...props.style,

                    width: "fitContent",
                    scale: 1,
                    opacity: 1,
                    translateY: y, // Bind the y translation to the motion value
                }}
            >
                <Component {...props} />
            </motion.div>
        )
    }
}

COMPONENT PARALLAX

COPY

import { useRef, type ComponentType } from "react"
import { createStore } from "https://framer.com/m/framer/store.js@^1.0.0"
import { motion, useScroll, useTransform } from "framer-motion"

// Learn more: https://www.framer.com/developers/overrides/
export function withScrollTranslateY100(Component): ComponentType {
    return function ScrollTranslateYOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null)

        // Use Framer Motion's useScroll to track scroll progress
        const { scrollYProgress } = useScroll({
            target: componentRef, // Attach scroll tracking to this component
            offset: ["start end", "end start"], // Animation starts when top enters and ends when bottom leaves
        })

        // Map scrollYProgress (0 to 1) to a translateY value (e.g., 50px to -50px)
        const y = useTransform(scrollYProgress, [0, 1], [150, -150])

        return (
            <motion.div
                ref={componentRef}
                style={{
                    ...props.style,

                    width: "fitContent",
                    scale: 1,
                    opacity: 1,
                    translateY: y, // Bind the y translation to the motion value
                }}
            >
                <Component {...props} />
            </motion.div>
        )
    }
}

COMPONENT PARALLAX

COPY

import { useRef, type ComponentType } from "react"
import { createStore } from "https://framer.com/m/framer/store.js@^1.0.0"
import { motion, useScroll, useTransform } from "framer-motion"

// Learn more: https://www.framer.com/developers/overrides/
export function withScrollTranslateY100(Component): ComponentType {
    return function ScrollTranslateYOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null)

        // Use Framer Motion's useScroll to track scroll progress
        const { scrollYProgress } = useScroll({
            target: componentRef, // Attach scroll tracking to this component
            offset: ["start end", "end start"], // Animation starts when top enters and ends when bottom leaves
        })

        // Map scrollYProgress (0 to 1) to a translateY value (e.g., 50px to -50px)
        const y = useTransform(scrollYProgress, [0, 1], [150, -150])

        return (
            <motion.div
                ref={componentRef}
                style={{
                    ...props.style,

                    width: "fitContent",
                    scale: 1,
                    opacity: 1,
                    translateY: y, // Bind the y translation to the motion value
                }}
            >
                <Component {...props} />
            </motion.div>
        )
    }
}

COMPONENT PARALLAX

COPY

import { useRef, type ComponentType } from "react"
import { createStore } from "https://framer.com/m/framer/store.js@^1.0.0"
import { motion, useScroll, useTransform } from "framer-motion"

// Learn more: https://www.framer.com/developers/overrides/
export function withScrollTranslateY100(Component): ComponentType {
    return function ScrollTranslateYOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null)

        // Use Framer Motion's useScroll to track scroll progress
        const { scrollYProgress } = useScroll({
            target: componentRef, // Attach scroll tracking to this component
            offset: ["start end", "end start"], // Animation starts when top enters and ends when bottom leaves
        })

        // Map scrollYProgress (0 to 1) to a translateY value (e.g., 50px to -50px)
        const y = useTransform(scrollYProgress, [0, 1], [150, -150])

        return (
            <motion.div
                ref={componentRef}
                style={{
                    ...props.style,

                    width: "fitContent",
                    scale: 1,
                    opacity: 1,
                    translateY: y, // Bind the y translation to the motion value
                }}
            >
                <Component {...props} />
            </motion.div>
        )
    }
}

STAGGER ON HOVER

COPY

import { animate } from "framer-motion";
import React, { useEffect, useRef } from "react";
import type { ComponentType } from "react";

export function withHoverTextAnimation(
    Component
): ComponentType {
    return function HoverTextAnimationOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null);

        // Function to pre-wrap text in spans
        const wrapTextInSpans = () => {
            if (!componentRef.current) return;

            // Select all paragraphs within the component
            const paragraphs = Array.from(componentRef.current.querySelectorAll("p"));

            paragraphs.forEach((paragraph) => {
                // Skip if already processed
                if (paragraph.hasAttribute("data-animated")) return;

                const letters = Array.from(paragraph.textContent).map((letter) => {
                    const span = document.createElement("span");
                    span.textContent = letter;
                    span.style.display = "inline-block"; // Prevent layout shift
                    span.style.whiteSpace = "pre"; // Preserve spacing
                    return span;
                });

                // Replace the paragraph text with the spans
                paragraph.innerHTML = "";
                letters.forEach((span) => paragraph.appendChild(span));

                // Mark paragraph as processed
                paragraph.setAttribute("data-animated", "true");
            });
        };

        const animateText = (direction: "enter" | "leave") => {
            if (!componentRef.current) return;

            // Select all paragraphs within the component
            const paragraphs = Array.from(componentRef.current.querySelectorAll("p"));

            paragraphs.forEach((paragraph) => {
                // Get the spans inside the paragraph
                const spans = Array.from(paragraph.querySelectorAll("span"));

                // Animate each letter in order
                spans.forEach((span, index) => {
                    const delay = index * 0.015; // 15ms delay per letter

                    animate(
                        span,
                        {
                            transform:
                                direction === "enter"
                                    ? "translateY(-100%)" // Move up on mouseEnter
                                    : "translateY(0)", // Move back down on mouseLeave
                        },
                        {
                            duration: 0.5, // 0.5s duration
                            delay, // Stagger delay
                            ease: [0.7, 0, 0.3, 1], // Accentuated easing
                        }
                    );
                });
            });
        };

        const handleMouseEnter = () => animateText("enter");
        const handleMouseLeave = () => animateText("leave");

        useEffect(() => {
            wrapTextInSpans(); // Pre-wrap text in spans on component mount
        }, []);

        return (
            <div
                ref={componentRef}
                onMouseEnter={handleMouseEnter}
                onMouseLeave={handleMouseLeave}
                style={{ cursor: "pointer" }} // Optional styling
            >
                <Component {...props} />
            </div>
        );
    };
}

STAGGER ON HOVER

COPY

import { animate } from "framer-motion";
import React, { useEffect, useRef } from "react";
import type { ComponentType } from "react";

export function withHoverTextAnimation(
    Component
): ComponentType {
    return function HoverTextAnimationOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null);

        // Function to pre-wrap text in spans
        const wrapTextInSpans = () => {
            if (!componentRef.current) return;

            // Select all paragraphs within the component
            const paragraphs = Array.from(componentRef.current.querySelectorAll("p"));

            paragraphs.forEach((paragraph) => {
                // Skip if already processed
                if (paragraph.hasAttribute("data-animated")) return;

                const letters = Array.from(paragraph.textContent).map((letter) => {
                    const span = document.createElement("span");
                    span.textContent = letter;
                    span.style.display = "inline-block"; // Prevent layout shift
                    span.style.whiteSpace = "pre"; // Preserve spacing
                    return span;
                });

                // Replace the paragraph text with the spans
                paragraph.innerHTML = "";
                letters.forEach((span) => paragraph.appendChild(span));

                // Mark paragraph as processed
                paragraph.setAttribute("data-animated", "true");
            });
        };

        const animateText = (direction: "enter" | "leave") => {
            if (!componentRef.current) return;

            // Select all paragraphs within the component
            const paragraphs = Array.from(componentRef.current.querySelectorAll("p"));

            paragraphs.forEach((paragraph) => {
                // Get the spans inside the paragraph
                const spans = Array.from(paragraph.querySelectorAll("span"));

                // Animate each letter in order
                spans.forEach((span, index) => {
                    const delay = index * 0.015; // 15ms delay per letter

                    animate(
                        span,
                        {
                            transform:
                                direction === "enter"
                                    ? "translateY(-100%)" // Move up on mouseEnter
                                    : "translateY(0)", // Move back down on mouseLeave
                        },
                        {
                            duration: 0.5, // 0.5s duration
                            delay, // Stagger delay
                            ease: [0.7, 0, 0.3, 1], // Accentuated easing
                        }
                    );
                });
            });
        };

        const handleMouseEnter = () => animateText("enter");
        const handleMouseLeave = () => animateText("leave");

        useEffect(() => {
            wrapTextInSpans(); // Pre-wrap text in spans on component mount
        }, []);

        return (
            <div
                ref={componentRef}
                onMouseEnter={handleMouseEnter}
                onMouseLeave={handleMouseLeave}
                style={{ cursor: "pointer" }} // Optional styling
            >
                <Component {...props} />
            </div>
        );
    };
}

STAGGER ON HOVER

COPY

import { animate } from "framer-motion";
import React, { useEffect, useRef } from "react";
import type { ComponentType } from "react";

export function withHoverTextAnimation(
    Component
): ComponentType {
    return function HoverTextAnimationOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null);

        // Function to pre-wrap text in spans
        const wrapTextInSpans = () => {
            if (!componentRef.current) return;

            // Select all paragraphs within the component
            const paragraphs = Array.from(componentRef.current.querySelectorAll("p"));

            paragraphs.forEach((paragraph) => {
                // Skip if already processed
                if (paragraph.hasAttribute("data-animated")) return;

                const letters = Array.from(paragraph.textContent).map((letter) => {
                    const span = document.createElement("span");
                    span.textContent = letter;
                    span.style.display = "inline-block"; // Prevent layout shift
                    span.style.whiteSpace = "pre"; // Preserve spacing
                    return span;
                });

                // Replace the paragraph text with the spans
                paragraph.innerHTML = "";
                letters.forEach((span) => paragraph.appendChild(span));

                // Mark paragraph as processed
                paragraph.setAttribute("data-animated", "true");
            });
        };

        const animateText = (direction: "enter" | "leave") => {
            if (!componentRef.current) return;

            // Select all paragraphs within the component
            const paragraphs = Array.from(componentRef.current.querySelectorAll("p"));

            paragraphs.forEach((paragraph) => {
                // Get the spans inside the paragraph
                const spans = Array.from(paragraph.querySelectorAll("span"));

                // Animate each letter in order
                spans.forEach((span, index) => {
                    const delay = index * 0.015; // 15ms delay per letter

                    animate(
                        span,
                        {
                            transform:
                                direction === "enter"
                                    ? "translateY(-100%)" // Move up on mouseEnter
                                    : "translateY(0)", // Move back down on mouseLeave
                        },
                        {
                            duration: 0.5, // 0.5s duration
                            delay, // Stagger delay
                            ease: [0.7, 0, 0.3, 1], // Accentuated easing
                        }
                    );
                });
            });
        };

        const handleMouseEnter = () => animateText("enter");
        const handleMouseLeave = () => animateText("leave");

        useEffect(() => {
            wrapTextInSpans(); // Pre-wrap text in spans on component mount
        }, []);

        return (
            <div
                ref={componentRef}
                onMouseEnter={handleMouseEnter}
                onMouseLeave={handleMouseLeave}
                style={{ cursor: "pointer" }} // Optional styling
            >
                <Component {...props} />
            </div>
        );
    };
}

STAGGER ON HOVER

COPY

import { animate } from "framer-motion";
import React, { useEffect, useRef } from "react";
import type { ComponentType } from "react";

export function withHoverTextAnimation(
    Component
): ComponentType {
    return function HoverTextAnimationOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null);

        // Function to pre-wrap text in spans
        const wrapTextInSpans = () => {
            if (!componentRef.current) return;

            // Select all paragraphs within the component
            const paragraphs = Array.from(componentRef.current.querySelectorAll("p"));

            paragraphs.forEach((paragraph) => {
                // Skip if already processed
                if (paragraph.hasAttribute("data-animated")) return;

                const letters = Array.from(paragraph.textContent).map((letter) => {
                    const span = document.createElement("span");
                    span.textContent = letter;
                    span.style.display = "inline-block"; // Prevent layout shift
                    span.style.whiteSpace = "pre"; // Preserve spacing
                    return span;
                });

                // Replace the paragraph text with the spans
                paragraph.innerHTML = "";
                letters.forEach((span) => paragraph.appendChild(span));

                // Mark paragraph as processed
                paragraph.setAttribute("data-animated", "true");
            });
        };

        const animateText = (direction: "enter" | "leave") => {
            if (!componentRef.current) return;

            // Select all paragraphs within the component
            const paragraphs = Array.from(componentRef.current.querySelectorAll("p"));

            paragraphs.forEach((paragraph) => {
                // Get the spans inside the paragraph
                const spans = Array.from(paragraph.querySelectorAll("span"));

                // Animate each letter in order
                spans.forEach((span, index) => {
                    const delay = index * 0.015; // 15ms delay per letter

                    animate(
                        span,
                        {
                            transform:
                                direction === "enter"
                                    ? "translateY(-100%)" // Move up on mouseEnter
                                    : "translateY(0)", // Move back down on mouseLeave
                        },
                        {
                            duration: 0.5, // 0.5s duration
                            delay, // Stagger delay
                            ease: [0.7, 0, 0.3, 1], // Accentuated easing
                        }
                    );
                });
            });
        };

        const handleMouseEnter = () => animateText("enter");
        const handleMouseLeave = () => animateText("leave");

        useEffect(() => {
            wrapTextInSpans(); // Pre-wrap text in spans on component mount
        }, []);

        return (
            <div
                ref={componentRef}
                onMouseEnter={handleMouseEnter}
                onMouseLeave={handleMouseLeave}
                style={{ cursor: "pointer" }} // Optional styling
            >
                <Component {...props} />
            </div>
        );
    };
}

More coming soon

Coming

soon

COPY

import {
    useMotionValue,
    useTransform,
    motion,
    animate,
    useScroll,
    useSpring,
} from "framer-motion"
import { useEffect, useState, ComponentType, useRef } from "react"
import gsap from "gsap"

export function withMagneticBehavior(Component): ComponentType {
    return function MagneticOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null)

        // Motion values for x and y
        const x = useMotionValue(0)
        const y = useMotionValue(0)

        // Smooth spring animations for the magnetic effect
        const springX = useSpring(x, { stiffness: 250, damping: 30 })
        const springY = useSpring(y, { stiffness: 250, damping: 30 })

        const strength = 50 // Magnetic strength

        const handleMouseMove = (event: React.PointerEvent) => {
            if (event.pointerType !== "mouse") return // Ignore non-mouse inputs

            const bounding = componentRef.current.getBoundingClientRect()
            const offsetX =
                ((event.clientX - bounding.left) / bounding.width - 0.5) *
                strength
            const offsetY =
                ((event.clientY - bounding.top) / bounding.height - 0.5) *
                strength

            x.set(offsetX)
            y.set(offsetY)
        }

        const handleMouseOut = (event: React.PointerEvent) => {
            if (event.pointerType !== "mouse") return // Ignore non-mouse inputs

            x.set(0)
            y.set(0)
        }

        return (
            <motion.div
                ref={componentRef}
                style={{
                    position: "relative",
                    x: springX,
                    y: springY,
                }}
                onPointerMove={handleMouseMove}
                onPointerLeave={handleMouseOut}
            >
                <Component {...props} />
            </motion.div>
        )
    }
} ComponentType } from "react"
import { createStore } from "https://framer.com/m/framer/store.js@^1.0.0"
import { motion, useScroll, useTransform } from "framer-motion"


export function imageParallax160px(
    Component
): ComponentType {
    return function ScrollTranslateYOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null)

        // Use Framer Motion's useScroll to track scroll progress
        const { scrollYProgress } = useScroll({
            target: componentRef, // Attach scroll tracking to this component
            offset: ["start end", "end start"], // Animation starts when top enters and ends when bottom leaves
        })

        // Map scrollYProgress (0 to 1) to a translateY value (e.g., 50px to -50px)
        const y = useTransform(scrollYProgress, [0, 1], [0, 160])

        return (
            <motion.div
                ref={componentRef}
                style={{
                    ...props.style,
                    position: "absolute",
                    inset: 0,
                    translateY: y, // Bind the y translation to the motion value
                }}
            >
                <Component {...props} />
            </motion.div>
        )
    }
}

More coming soon

Coming

soon

COPY

import {
    useMotionValue,
    useTransform,
    motion,
    animate,
    useScroll,
    useSpring,
} from "framer-motion"
import { useEffect, useState, ComponentType, useRef } from "react"
import gsap from "gsap"

export function withMagneticBehavior(Component): ComponentType {
    return function MagneticOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null)

        // Motion values for x and y
        const x = useMotionValue(0)
        const y = useMotionValue(0)

        // Smooth spring animations for the magnetic effect
        const springX = useSpring(x, { stiffness: 250, damping: 30 })
        const springY = useSpring(y, { stiffness: 250, damping: 30 })

        const strength = 50 // Magnetic strength

        const handleMouseMove = (event: React.PointerEvent) => {
            if (event.pointerType !== "mouse") return // Ignore non-mouse inputs

            const bounding = componentRef.current.getBoundingClientRect()
            const offsetX =
                ((event.clientX - bounding.left) / bounding.width - 0.5) *
                strength
            const offsetY =
                ((event.clientY - bounding.top) / bounding.height - 0.5) *
                strength

            x.set(offsetX)
            y.set(offsetY)
        }

        const handleMouseOut = (event: React.PointerEvent) => {
            if (event.pointerType !== "mouse") return // Ignore non-mouse inputs

            x.set(0)
            y.set(0)
        }

        return (
            <motion.div
                ref={componentRef}
                style={{
                    position: "relative",
                    x: springX,
                    y: springY,
                }}
                onPointerMove={handleMouseMove}
                onPointerLeave={handleMouseOut}
            >
                <Component {...props} />
            </motion.div>
        )
    }
} ComponentType } from "react"
import { createStore } from "https://framer.com/m/framer/store.js@^1.0.0"
import { motion, useScroll, useTransform } from "framer-motion"


export function imageParallax160px(
    Component
): ComponentType {
    return function ScrollTranslateYOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null)

        // Use Framer Motion's useScroll to track scroll progress
        const { scrollYProgress } = useScroll({
            target: componentRef, // Attach scroll tracking to this component
            offset: ["start end", "end start"], // Animation starts when top enters and ends when bottom leaves
        })

        // Map scrollYProgress (0 to 1) to a translateY value (e.g., 50px to -50px)
        const y = useTransform(scrollYProgress, [0, 1], [0, 160])

        return (
            <motion.div
                ref={componentRef}
                style={{
                    ...props.style,
                    position: "absolute",
                    inset: 0,
                    translateY: y, // Bind the y translation to the motion value
                }}
            >
                <Component {...props} />
            </motion.div>
        )
    }
}

More coming soon

Coming

soon

COPY

import {
    useMotionValue,
    useTransform,
    motion,
    animate,
    useScroll,
    useSpring,
} from "framer-motion"
import { useEffect, useState, ComponentType, useRef } from "react"
import gsap from "gsap"

export function withMagneticBehavior(Component): ComponentType {
    return function MagneticOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null)

        // Motion values for x and y
        const x = useMotionValue(0)
        const y = useMotionValue(0)

        // Smooth spring animations for the magnetic effect
        const springX = useSpring(x, { stiffness: 250, damping: 30 })
        const springY = useSpring(y, { stiffness: 250, damping: 30 })

        const strength = 50 // Magnetic strength

        const handleMouseMove = (event: React.PointerEvent) => {
            if (event.pointerType !== "mouse") return // Ignore non-mouse inputs

            const bounding = componentRef.current.getBoundingClientRect()
            const offsetX =
                ((event.clientX - bounding.left) / bounding.width - 0.5) *
                strength
            const offsetY =
                ((event.clientY - bounding.top) / bounding.height - 0.5) *
                strength

            x.set(offsetX)
            y.set(offsetY)
        }

        const handleMouseOut = (event: React.PointerEvent) => {
            if (event.pointerType !== "mouse") return // Ignore non-mouse inputs

            x.set(0)
            y.set(0)
        }

        return (
            <motion.div
                ref={componentRef}
                style={{
                    position: "relative",
                    x: springX,
                    y: springY,
                }}
                onPointerMove={handleMouseMove}
                onPointerLeave={handleMouseOut}
            >
                <Component {...props} />
            </motion.div>
        )
    }
} ComponentType } from "react"
import { createStore } from "https://framer.com/m/framer/store.js@^1.0.0"
import { motion, useScroll, useTransform } from "framer-motion"


export function imageParallax160px(
    Component
): ComponentType {
    return function ScrollTranslateYOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null)

        // Use Framer Motion's useScroll to track scroll progress
        const { scrollYProgress } = useScroll({
            target: componentRef, // Attach scroll tracking to this component
            offset: ["start end", "end start"], // Animation starts when top enters and ends when bottom leaves
        })

        // Map scrollYProgress (0 to 1) to a translateY value (e.g., 50px to -50px)
        const y = useTransform(scrollYProgress, [0, 1], [0, 160])

        return (
            <motion.div
                ref={componentRef}
                style={{
                    ...props.style,
                    position: "absolute",
                    inset: 0,
                    translateY: y, // Bind the y translation to the motion value
                }}
            >
                <Component {...props} />
            </motion.div>
        )
    }
}

More coming soon

Coming

soon

COPY

import {
    useMotionValue,
    useTransform,
    motion,
    animate,
    useScroll,
    useSpring,
} from "framer-motion"
import { useEffect, useState, ComponentType, useRef } from "react"
import gsap from "gsap"

export function withMagneticBehavior(Component): ComponentType {
    return function MagneticOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null)

        // Motion values for x and y
        const x = useMotionValue(0)
        const y = useMotionValue(0)

        // Smooth spring animations for the magnetic effect
        const springX = useSpring(x, { stiffness: 250, damping: 30 })
        const springY = useSpring(y, { stiffness: 250, damping: 30 })

        const strength = 50 // Magnetic strength

        const handleMouseMove = (event: React.PointerEvent) => {
            if (event.pointerType !== "mouse") return // Ignore non-mouse inputs

            const bounding = componentRef.current.getBoundingClientRect()
            const offsetX =
                ((event.clientX - bounding.left) / bounding.width - 0.5) *
                strength
            const offsetY =
                ((event.clientY - bounding.top) / bounding.height - 0.5) *
                strength

            x.set(offsetX)
            y.set(offsetY)
        }

        const handleMouseOut = (event: React.PointerEvent) => {
            if (event.pointerType !== "mouse") return // Ignore non-mouse inputs

            x.set(0)
            y.set(0)
        }

        return (
            <motion.div
                ref={componentRef}
                style={{
                    position: "relative",
                    x: springX,
                    y: springY,
                }}
                onPointerMove={handleMouseMove}
                onPointerLeave={handleMouseOut}
            >
                <Component {...props} />
            </motion.div>
        )
    }
} ComponentType } from "react"
import { createStore } from "https://framer.com/m/framer/store.js@^1.0.0"
import { motion, useScroll, useTransform } from "framer-motion"


export function imageParallax160px(
    Component
): ComponentType {
    return function ScrollTranslateYOverride(props) {
        const componentRef = useRef<HTMLDivElement>(null)

        // Use Framer Motion's useScroll to track scroll progress
        const { scrollYProgress } = useScroll({
            target: componentRef, // Attach scroll tracking to this component
            offset: ["start end", "end start"], // Animation starts when top enters and ends when bottom leaves
        })

        // Map scrollYProgress (0 to 1) to a translateY value (e.g., 50px to -50px)
        const y = useTransform(scrollYProgress, [0, 1], [0, 160])

        return (
            <motion.div
                ref={componentRef}
                style={{
                    ...props.style,
                    position: "absolute",
                    inset: 0,
                    translateY: y, // Bind the y translation to the motion value
                }}
            >
                <Component {...props} />
            </motion.div>
        )
    }
}