Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
nonoumasy

Scrolltrigger.create() pass dynamic arrayItem object to onEnter property

Go to solution Solved by OSUblake,

Recommended Posts

https://codesandbox.io/s/elegant-meninsky-hwvu5?file=/src/App.js

Essentialy, I'm trying to create a scrollyTelling feature. I would like to trigger a flyTo function on the map using scrollTrigger rather than a click.  I want to pass arrayItem objects(which has latitude, longitude values) to the Scrolltiger.create onEnter property so that it can pass these values to the actual flyTo() function which moves the map around. Since scrollTrigger is the one triggering each event based on an item on the array, I figure you somehow need to involve it. Still trying to figure this out. Thanks for any help.

I'm using useRef in react to get a reference to the card div so it can create an array of refs for scrollTrigger.

const revealsRef = useRef([])
const data = [
  { id: "foo1", title: "lorem ipsum", latitude: 38, longitude: -118 },
  { id: "foo2", title: "lorem", latitude: 39, longitude: -119 },
  { id: "foo3", title: "lorem", latitude: 37, longitude: -117 }
]

revealsRef.current = []

const addToRefs = (item) => {
  if (item && !revealsRef.current.includes(item)) {
    revealsRef.current.push(item)
  }
}

 {data.map((item, index) => (
        <div
          className="card"
          key={index}
          ref={addToRefs}
          style={{ cursor: "pointer" }}
          onClick={() => flyTo({ data, id: item.id })}
        >
          <div>{item.title} </div>
          <div>{item.latitude} </div>
          <div>{item.longitude} </div>
        </div>
      ))}
...

I tried logging mapped items from these revealCurrents. I get this:

  1. <div class="card" style="cursor: pointer;">
    1.  <div>lorem </div>
    2.  <div>37 </div>
    3.  <div>-117 </div>
    4.  </div>

 

so I can probably do some querySelector to get that lat and lon values from this and pass this to the flyTo function. However, I was wondering if there was  a more elegant way to do this with ScrollTrigger. I apologize if this is more of a React/javascript thing more than a scrollTrigger, but just thought I would ask.

ps. just adding this. Would it be better not to include scrollTrigger to trigger the flyTo() function. Maybe I can just listen to when the card div hits a scrollPosition Y and then call the flyTo() and pass the lat and lon that way?

Link to comment
Share on other sites

Hi nonoumasy!

 

I'm a little confused about what you're asking here, but I don't see anything wrong with calling your flyTo function from a ScrollTrigger. Also, have you checked out our React guide?

 

You can use the selector util to create an array of all your cards. Then you can do map, forEach, or whatever. No need to do all that ref array stuff. 

 

let cardsArray = q(".card");

 

Link to comment
Share on other sites

Thanks for the tip on the selector util. Is that new? 
At any rate, I got the scrollytelling thing to work:
https://codesandbox.io/s/elegant-meninsky-hwvu5?file=/src/App.js

It's a bit hacky. In particular, the only way to get the lat and lon values is to add them as a div elements. I might have to use something like the intersection observer to make it cleaner. If thats the case, I wouldn't need scrollTrigger.
 

Btw, I was able to create the array of items by mapping the q('.card). I didn't see that in the documentation so it took awhile to figure it out. 
 

useEffect(() => {
q(".card").map((item) => {
ScrollTrigger.create({
trigger: item,
start: "top center+=150",
end: "top center",
toggleActions: "start reverse none start",
onEnter: () => myEnterFunc(item),
onLeave: myLeaveFunc,
onEnterBack: () => myEnterFunc(item),
onLeaveBack: myLeaveFunc,
markers: "true",
scrub: "true"
})
})
}, [])


 

Link to comment
Share on other sites

Thanks for the tip on the selector util. Is that new? 
At any rate, I got the scrollytelling thing to work eventhough its a bit hacky.
https://hwvu5.csb.app/
 

btw, I was able to get it to work by mapping the q('.card). I didn't see that in the documentation so it took awhile to figure it out. If you just wanted to animate though, then you don't have to map thru each item to get an individual breakpoint.

Link to comment
Share on other sites

  • Solution
6 hours ago, nonoumasy said:

Thanks for the tip on the selector util. Is that new? 

 

Yep. It was it added in v 3.7.

https://greensock.com/docs/v3/GSAP/UtilityMethods/selector()

 

6 hours ago, nonoumasy said:

It's a bit hacky. In particular, the only way to get the lat and lon values is to add them as a div elements.

 

You should be able to grab those values directly...

 

useEffect(() => {
    q(".card").map((item, i) => {
      const { latitude, longitude } = data[i];
      ScrollTrigger.create({
        trigger: item,
        start: "top center+=50",
        end: "top top+=50",
        onToggle: () => flyTo(latitude, longitude),
        markers: "true",
      })
    })
  }, [])

 

Link to comment
Share on other sites

Thank you! That works! I'm going to update all my react app with this new selector util.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×