8 Maret 20266 min read

Crafting Premium Micro-Interactions & Brutalist Animations with Framer Motion

How to craft magnetic cursor buttons, smooth layout morphing, parallax scroll animations, and scroll-driven physics without dropping frames.

Framer MotionAnimationUI/UXFrontendReact

High-end digital experiences distinguish themselves through the quality of their micro-interactions. In my portfolio, subtle physics-based cursor magnetism and scroll transitions give the interface a tactile, engaging feel.


1. Magnetic Button Implementation

"use client";

import { useRef, useState } from "react";
import { motion } from "framer-motion";

export function MagneticButton({ children }: { children: React.ReactNode }) {
  const ref = useRef<HTMLDivElement>(null);
  const [position, setPosition] = useState({ x: 0, y: 0 });

  function handleMouseMove(e: React.MouseEvent<HTMLDivElement>) {
    const { clientX, clientY } = e;
    const { left, top, width, height } = ref.current!.getBoundingClientRect();
    const middleX = clientX - (left + width / 2);
    const middleY = clientY - (top + height / 2);
    setPosition({ x: middleX * 0.25, y: middleY * 0.25 });
  }

  function handleMouseLeave() {
    setPosition({ x: 0, y: 0 });
  }

  return (
    <motion.div
      ref={ref}
      onMouseMove={handleMouseMove}
      onMouseLeave={handleMouseLeave}
      animate={{ x: position.x, y: position.y }}
      transition={{ type: "spring", stiffness: 150, damping: 15, mass: 0.1 }}
      className="inline-block"
    >
      {children}
    </motion.div>
  );
}

2. Scroll-Driven Parallax

Using useScroll and useTransform allows hardware-accelerated transforms on the compositor thread without causing repaints:

import { useScroll, useTransform, motion } from "framer-motion";

export function ParallaxHero() {
  const { scrollY } = useScroll();
  const y = useTransform(scrollY, [0, 500], [0, 150]);
  const opacity = useTransform(scrollY, [0, 300], [1, 0]);

  return (
    <motion.div style={{ y, opacity }} className="will-change-transform">
      <h1>MAULANA</h1>
    </motion.div>
  );
}

Micro-interactions should feel effortless, responsive, and purposeful.

Bagikan

Artikel lainnya