如何更新进度

How to update progress

当你向下滚动页面时,你会看到带有#pin的元素会被粘住,而currentPercentage会不断更新,直到currentPercentage的值为1,然后不会粘了。

问题是在滚动到某个值后,我单击了 update progress to 0.5currentPercentage 的值将变为 0.5,但如果我再滚动。该值将跳转到之前的值。

例如,如果我滚动并停在0.33,然后点击按钮,currentPercentage的值就会变成0.5。
如果我现在向下滚动,值将从 0.33 而不是 0.5 增加,这主要是问题所在。

如何解决?

App.js

import "./styles.css";
import ScrollMagic from "scrollmagic";
import React, { useState, useEffect } from "react";

export default function App() {
  const [currentPercentage, setCurrentPercentage] = useState(0);

  const scrollController = new ScrollMagic.Controller({
    globalSceneOptions: { triggerHook: "onLeave" }
  });
  useEffect(() => {
    new ScrollMagic.Scene({
      triggerElement: "#pin",
      duration: 1000,
      offset: -10
    })
      .setPin("#pin")
      .setClassToggle("#pin", "green")
      .on("progress", function (e) {
        console.log(e.progress);
        let progress = e.progress;
        setCurrentPercentage(progress);
      })
      .addTo(scrollController);
  }, []);

  const updateProgress = () => {
    setCurrentPercentage(0.5);
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>{" "}
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <div id="pin">
        <div>{currentPercentage}</div>
        <button
          onClick={() => {
            updateProgress();
          }}
        >
          Update Progress to 0.5
        </button>
      </div>
      <div
        style={{ margin: "1rem", border: "1px solid grey", height: "500px" }}
      />
    </div>
  );
}

Codesandbox
https://codesandbox.io/s/flamboyant-aryabhata-oi5xr?file=/src/App.js

终于想出解决办法

关键在于使用

 controller.scrollTo(scene.triggerPosition() + the_progress_you_want * scene.duration());

在 updateProgress 函数中。
此外,您必须在 React.state 中初始化 `scene` 和 `controller` ``` const [控制器, setController] = useState(null); const [场景, setScene] = useState(null); ```

完整的解决方案是

import "./styles.css";
import ScrollMagic from "scrollmagic";
import React, { useState, useEffect } from "react";

export default function App() {
  const [currentPercentage, setCurrentPercentage] = useState(0);

  const [controller, setController] = useState(null);
  const [scene, setScene] = useState(null);

  useEffect(() => {
    const scrollController = new ScrollMagic.Controller({
      globalSceneOptions: { triggerHook: "onLeave" }
    });
    const scrollScene = new ScrollMagic.Scene({
      triggerElement: "#pin",
      duration: 1000,
      offset: -10
    })
      .setPin("#pin")
      .setClassToggle("#pin", "green")
      .on("progress", function (e) {
        let progress = e.progress;
        setCurrentPercentage(progress);
      });
    scrollScene.addTo(scrollController);
    setController(scrollController);
    setScene(scrollScene);
  }, []);

  const updateProgress = () => {
    controller.scrollTo(scene.triggerPosition() + 0.5 * scene.duration());
    setCurrentPercentage(0.5);
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>{" "}
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <div id="pin">
        <div>{currentPercentage}</div>
        <button
          onClick={() => {
            updateProgress();
          }}
        >
          Update Progress to 0.5
        </button>
      </div>
      <div
        style={{ margin: "1rem", border: "1px solid grey", height: "500px" }}
      />
    </div>
  );
}