javascript - useMotionValueEvent not working on motion react - Stack Overflow

I just discovered motion for react (previously framer motion) and I just started learning it. I've

I just discovered motion for react (previously framer motion) and I just started learning it. I've gotten a hold of the basic syntax from the docs to make some simple animations. I'm working with useMotionEvent. But I'm not sure I totally get the concept, because I've been trying to replicate this "Track element scroll offset" on the docs. /docs/react-scroll-animations,

I've gotten the scrollXprogress to work, but I'm not totally getting the function with the maskimg to work. It's supposed to give a fade gradient animation to the left or right depending on whether you've scrolled to the end or start or middle of the container.
The code on the docs is mostly using typescript and I'm not familiar with that. I use reactJS

This is what I've been able to do so far.

import React, { useRef } from "react";
import {
  animate,
  motion,
  useMotionValue,
  useMotionValueEvent,
  useScroll,
} from "motion/react";

const ScrollXBox = () => {
  const left = `0%`;
  const right = `100%`;
  const leftInset = `20%`;
  const rightInset = `80%`;
  const transparent = `#0000`;
  const opaque = `#000`;

  function useScrollOverflowMask(scrollXProgress) {
    const maskImage = useMotionValue(
      `linear-gradient(90deg, ${opaque}, ${opaque} ${left}, ${opaque} ${rightInset}, ${transparent})`
    );

    useMotionValueEvent(scrollXProgress, "change", (value) => {
      if (value === 0) {
        animate(
          maskImage,
          `linear-gradient(90deg, ${opaque}, ${opaque} ${left}, ${opaque} ${rightInset}, ${transparent})`
        );
      } else if (value === 1) {
        animate(
          maskImage,
          `linear-gradient(90deg, ${transparent}, ${opaque} ${leftInset}, ${opaque} ${right}, ${opaque})`
        );
      } else if (
        scrollXProgress.getPrevious() === 0 ||
        scrollXProgress.getPrevious() === 1
      ) {
        animate(
          maskImage,
          `linear-gradient(90deg, ${transparent}, ${opaque} ${leftInset}, ${opaque} ${rightInset}, ${transparent})`
        );
      }
    });

    return maskImage;
  }

  const elements = ["A", "B", "C", "D"];
  const colors = [
    "bg-red-800",
    "bg-yellow-600",
    "bg-green-900",
    "bg-purple-900",
  ];

  const ref = useRef(null);
  const { scrollXProgress } = useScroll({ container: ref });
  const maskImage = useScrollOverflowMask(scrollXProgress);

  return (
    <div className="scroll-x h-screen flex flex-col justify-center items-center gap-4 bg-violet-400">
      <div id="example">
        <svg id="progress" width="80" height="80" viewBox="0 0 100 100">
          <circle
            cx="50"
            cy="50"
            r="40"
            pathLength="1"
            style={{ fill: "none", stroke: "red", strokeWidth: 20 }}
          />
          <motion.circle
            cx="50"
            cy="50"
            r="40"
            style={{
              fill: "none",
              stroke: "yellow",
              strokeWidth: 10,
              pathLength: scrollXProgress,
            }}
          />
        </svg>
        <div
          ref={ref}
          className="element-container overflow-x-scroll w-96 flex gap-4"
          style={{
            WebkitMaskImage: maskImage.get(),
            maskImage: maskImage.get(),
          }}
        >
          {elements.map((element, index) => (
            <motion.ul key={index} className="flex-shrink-0">
              <li>
                <div className={`${colors[index]} w-64 h-64`}></div>
              </li>
            </motion.ul>
          ))}
        </div>
      </div>
    </div>
  );
};

export default ScrollXBox;

I tried using the .get() function with the maskImg but it only gets the value declared

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744229576a4564180.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信