Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracked Position on Page load #26

Open
mikegallay opened this issue Mar 20, 2017 · 12 comments
Open

Tracked Position on Page load #26

mikegallay opened this issue Mar 20, 2017 · 12 comments

Comments

@mikegallay
Copy link

mikegallay commented Mar 20, 2017

A few of the items I am tracking appear slightly above the bottom of the page on load. These items are appearing with a translate3d y-position of -33% (see code below). Once I scroll they jump to the calculated position based on my tween. Is there any way to have the tween calculate and apply while their position on load (without seeing a jump)?

I have already tried applying a scroll using js, but you can still see they items jump once the calculated tween takes hold. Thanks!

<DIV
	className='tile-wrapper-scroll'
	style={ tween(scrollY, [
		[posTopBottom, { transform: translate3d(0, percent(0), 0) }],
		[posBottomTop, { transform: translate3d(0, percent(-33), 0) }]
	])}
	>
	<div className='tile-wrapper' style={tileStyle}></div>
</DIV>
@gilbox
Copy link
Owner

gilbox commented Mar 20, 2017

Try adding the updateOnDidMount prop to <TrackDocument /> and lmk if it works. For some reason I never documented this prop.

@mikegallay
Copy link
Author

So, it should look like this?

<TrackDocument updateOnDidMount formulas={[getDocumentElement, ...

@gilbox
Copy link
Owner

gilbox commented Mar 20, 2017

yes

@mikegallay
Copy link
Author

I don't see any difference. Is there anything else I need to import?

@gilbox
Copy link
Owner

gilbox commented Mar 20, 2017

Nah that's it... I'm not sure to what extend the problem you're experiencing is specific to react-track... try logging the values of scrollY, posTopBottom, posBottomTop in your render function. I suspect that one of them is jumping, probably posBottomTop.

@mikegallay
Copy link
Author

On page load: scrollY = 0; posTopBottom = -677; posBottomTop = 0;
On slight scroll: scrollY = 2; posTopBottom = 250; posBottomTop = 1404;
From what I can tell, the scroll position is calculated just before the content is actually on the page, so that position and value get locked in. As soon as I scroll, the new positioning takes over.

@gilbox
Copy link
Owner

gilbox commented Mar 20, 2017

I set a breakpoint in the demo page and noticed the same behavior happening there. I wonder if you can somehow structure your page in a similar way so that the initial calculation doesn't mess anything up? Another thing to try is to use visibility: hidden until the calculation is correct.

@mikegallay
Copy link
Author

Unfortunately, I cannot hide the content until the scroll fires. One thing to note, I am actually mapping an array of content through another render function:

{ this.props.data.map(this.renderTile.bind(this,[topBottom, bottomTop]))

I am passing the formulas I need to this function, which has the subsequent elements. I'm not sure if this has any bearing on the load order or how the positioning is calculated.

Have you come across any simple/effective ways to fire off the scroll once the content is in place? I've tried TweenMax from a position, adding scrollBy functions and a few more things, but nothing has produced an effective result. Thanks again for responding.

@gilbox
Copy link
Owner

gilbox commented Mar 20, 2017

What you can do is modify the source here so that instead of doing

const update = ....

we do

this.update = ...

then you can grab the ref of <TrackDocument

<TrackDocument ref={r => this.trackDocument = r}

Finally, you can trigger an update whenever you want by doing

this.trackDocument.update()

Try it out on your project and if it works, feel free to create a PR to add this feature.

@mikegallay
Copy link
Author

mikegallay commented Mar 20, 2017 via email

@mikegallay
Copy link
Author

mikegallay commented Mar 21, 2017

This gets me much closer, but the calculation isn't perfect and unfortunately there is still a noticeable jump. I'm thinking that it has something to do with mapping through an array and calling another function to render the elements I'm having issues with (full code below).

When I put the <Track> code within the same render call with the <TrackDocument> there doesn't seem to be an issue and everything is where it is supposed to be. Note: I tested putting everything under one render call without doing the update suggestion you recommended above and the jump effect was still there. This isn't a real solution for me since I would still need to map through an array.

So, the issue appears to be a combination of using your update suggestion and something else, which may or may not have something to do with calling another render function from within the original <TrackDocument> render function. I'm providing a little more code to show you how I've set up the functions. Notice how I pass the formulae I need to renderTile(). Let me know if you see any issues with this or have any other suggestions. Thanks!

renderTile(formulas,item, idx, collection) {
		var tileStyle = {
			background: 'url('+ item.secondaryImage +')',
			backgroundSize:'cover'
		};

		return (
			<Link
				className='tile'
				key={ item.slug }
				to={ `/work/${item.slug}` }

			>
			<Track component="div" formulas={[formulas[0],formulas[1]]}>
			{(DIV,posTopBottom, posBottomTop) =>
				<DIV
					className='tile-wrapper-scroll'
					style={ tween(scrollY, [
						[posTopBottom, { transform: translate3d(0, percent(0), 0) }],
						[posBottomTop, { transform: translate3d(0, percent(-33), 0) }]
					])}
					>
					<div className='tile-wrapper' style={tileStyle}></div>

				</DIV>

			}</Track>
				<div className="tile-inner">
					<p className="tile-office">{ `${item.office}` }</p>
					<div className="tile-copy">
						<h4 className="tile-client">{ `${item.client}` }</h4>
						<p>{ `${item.blurb}` }</p>
					</div>
				</div>

			</Link>
		);
	}

	render() {
		return (
			<TrackDocument
			 	ref={r => this.$trackDocument = r}
				formulas={[getDocumentElement, getDocumentRect, calculateScrollY, topTop, topBottom, topCenter, centerCenter, bottomBottom, bottomTop]}>
			     {(documentElement, documentRect, scrollY, topTop, topBottom, topCenter, centerCenter, bottomBottom, bottomTop) =>

				<div className={`work-tiles ${this.props.expandedTiles} ${this.props.dataReady == true ? 'dataReady' : ''}`}>
					{this.props.dataReady && this.props.data.map(this.renderTile.bind(this,[topBottom, bottomTop]))}

				</div>

			}</TrackDocument>
		);
	}

@mikegallay
Copy link
Author

mikegallay commented Mar 24, 2017

I wanted to follow up with you. I have found a solve after writing a custom fix, but after going through this process I believe a piece of what I did is what our missing element was.

Exposing that update function does work, but calling it onMount was not enough. Apparently, the timing of the onMount call doesn't give all the rendered elements enough time to actually "mount". Even with my custom solve I need to tell the page to update using a setTimeout. The timeout was only 50ms, but that was enough for the page to render using the correct scroll calculation.

In order to keep the viewer from seeing the position of the track elements jump on this update call, I simply hid them until it happened, by setting the state of another variable {onInit : true} and using it to add a class ('showElements') to my elements that controlled their opacity:

className={'work-detail-wrapper ${this.state.onInit ? 'showElements' : ''}'}

Note: the single quotes directly inside the outer-most curly brackets should be backticks. The formatting on git-hub keeps them from rendering properly.

Hopefully, this fix works for anyone who has a similar issue. Thanks for your input and feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants