2

When you scroll down the page, you will see the element with #pin will be sticky and the currentPercentage will keep updating until the value of currentPercentage is 1 and then not sticky anymore.

enter image description here

The problem is after I scroll to some value, I click the update progress to 0.5. The value of currentPercentage will become 0.5, but if I then scroll. The value will jump to previous value.

For example, if I scroll and stop at 0.33 and then click the button, the value of currentPercentage will become 0.5.
If I scroll down now, the value will increase from 0.33 instead of 0.5, which is mainly the problem.

How to fix it?

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

DarkBee
  • 16,592
  • 6
  • 46
  • 58
CCCC
  • 5,665
  • 4
  • 41
  • 88
  • When you set the currentPercentage to 0.5 with your Button, you are not scrolling to that position. You are just assigning the value 0.5 to the variable currentPercentage, the scroll position remains at 0.33. This will be overwritten when you continue scrolling, your ScrollMagic will call the "progress" callback and set the "real" scroll position. You have to scroll to this position, i don't know ScrollMagic but i guess it has a function for it? – Andreas Jagiella Jan 11 '22 at 12:35

1 Answers1

0

Finally figure out the solution

The key is to use

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

In `updateProgress` function.
Also, you have to initial `scene` and `controller` in React.state ``` const [controller, setController] = useState(null); const [scene, setScene] = useState(null); ```

The complete solution is

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>
  );
}
CCCC
  • 5,665
  • 4
  • 41
  • 88