You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React中最新版Framer Motion的useInvertedScale钩子替代方案及使用问题咨询

Fixing the Missing useInvertedScale in Latest Framer Motion

Hey there! Let's break down what's happening with useInvertedScale and how to fix your code for the latest Framer Motion versions.

Quick Answer

Yes, useInvertedScale was removed in Framer Motion v2.0 and later. This hook was a convenience utility for creating "reverse-scaled" animations, but its functionality can be easily replicated with custom transform logic—no extra hooks needed.

How to Replace It

The core purpose of useInvertedScale was to counteract the visual stretching that happens when you move an element scaled from a non-center origin. Here are two straightforward replacements that match your original code's behavior:

Option 1: Extend Your Existing transformTemplate (Closest to Original Code)

You're already using a custom transformTemplate, so we can just bake the reverse scale logic directly into it. This keeps your code structure almost identical to what you had before:

import React from "react";
import { motion } from "framer-motion";

export const Title = ({ title, category, isSelected }) => {
  const x = isSelected ? 30 : 15;
  const y = x;
  
  // Updated transform template with built-in reverse scaling
  const scaleTranslate = ({ x, y }) => {
    // Calculate inverse scale to offset the visual stretch from translation
    const scaleX = 1 / (1 + x / 100);
    const scaleY = 1 / (1 + y / 100);
    return `scaleX(${scaleX}) scaleY(${scaleY}) translate(${x}px, ${y}px) translateZ(0)`;
  };

  return (
    <motion.div
      initial={false}
      animate={{ x, y }}
      transition={
        isSelected
          ? { type: "spring", stiffness: 200, damping: 30 }
          : { type: "spring", stiffness: 300, damping: 35 }
      }
      transformTemplate={scaleTranslate}
      style={{
        originX: 0,
        originY: 0,
        position: "absolute",
        top: 0,
        left: 0,
        maxWidth: "300px",
      }}
    >
      <span
        style={{
          color: "#fff",
          fontSize: "14px",
          textAlign: "right",
          direction: "rtl",
        }}
      >
        {category}
      </span>
      <h2 style={{ textAlign: "right", direction: "rtl" }}>{title}</h2>
    </motion.div>
  );
};

Option 2: Calculate Scale Values Directly in animate

If you prefer to explicitly control the scale properties, you can calculate them alongside your x/y values and pass them directly to the animate prop:

import React from "react";
import { motion } from "framer-motion";

export const Title = ({ title, category, isSelected }) => {
  const x = isSelected ? 30 : 15;
  const y = x;
  // Compute inverse scale values manually
  const scaleX = 1 / (1 + x / 100);
  const scaleY = 1 / (1 + y / 100);

  return (
    <motion.div
      initial={false}
      animate={{ x, y, scaleX, scaleY }}
      transition={
        isSelected
          ? { type: "spring", stiffness: 200, damping: 30 }
          : { type: "spring", stiffness: 300, damping: 35 }
      }
      style={{
        originX: 0,
        originY: 0,
        position: "absolute",
        top: 0,
        left: 0,
        maxWidth: "300px",
      }}
    >
      <span
        style={{
          color: "#fff",
          fontSize: "14px",
          textAlign: "right",
          direction: "rtl",
        }}
      >
        {category}
      </span>
      <h2 style={{ textAlign: "right", direction: "rtl" }}>{title}</h2>
    </motion.div>
  );
};

Why Was useInvertedScale Removed?

The Framer Motion team removed this hook to simplify the library's API. The logic it handled is relatively straightforward, and by removing the abstraction, they let developers have more control over how transforms are combined—without relying on a specialized hook.

内容的提问来源于stack exchange,提问作者Mehdi Faraji

火山引擎 最新活动