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

Horizontal parallax effect (And easing function) #32

Open
jessevdp opened this issue Mar 29, 2017 · 1 comment
Open

Horizontal parallax effect (And easing function) #32

jessevdp opened this issue Mar 29, 2017 · 1 comment

Comments

@jessevdp
Copy link

jessevdp commented Mar 29, 2017

Hi there Travis 👍

First of all I want to take a moment to thank you for the videos you create. They're very informative, clear and I can say they've helped me become a better web developer/designer.

I found your channel while looking for good CSS animation tutorials and in under a week I was addicted to your channel. I ended up watching your series "parallax on the web". Both these series answered so many questions I still had about the web design industry and thanks to you I now have a much better understanding of these (and many more) subjects.


With the "thank you" out of the way I wanted to kind of request a new part to the parallax series. In the first episode you start out by showing off a whole list of cool examples already out there. While you covered the biggest part of all the different categories you listed you didn't do all of them. The ones I would be particularly interested in would be the designs where a certain element would move along with you the entire way through the page.

Another parallax effect I was very interested in was one where a certain element would move horizontally while the user scrolled. That one I figured I could take on my own.


So I started investigating. The goal was to create an element that would move horizontally while the user scrolled the web page. The object would start "moving" as it came into view and be on the other side as it went out of view. Another requirement was that the screen size should not matter. The entire "user controlled animation" should be responsive.

Linear function 👨‍💻

I started out by creating a linear function that would do this. By emphasising the fact that the moving-element would start as it came into view and finish as it went out of view I came up with a basic mathematical function to calculate the position of this moving element. The solution I came up with would work across all screen sizes.

My idea was that there was a relation between the height and the width of the screen. If the screen was 1000px high and 500px wide the moving-element would only have to move half the amount of scrolled pixels to the right. If the screen was 600px high and 200px wide the moving-element would only have to move 1/3 of the amount of scrolled pixels to the right.

In other words: The amount of pixels we need to move the moving-element to the right would be:

(screenWidth / screenHeight) * amount_px_scrolled

To clarify myself a bit further I went ahead and created a graph. Consider the orange line in the following image:

To clarify: Take the amount of pixels scrolled since the moving-element was first visible and insert a horizontal line on that position. The point where the line you just imagined crosses the orange line is where the moving-element should be positioned horizontally.

Pretty cool huh?


While this function works pretty well: it's scalable and correct (there is no guesswork going on) I wasn't happy yet. There were still a few improvements to be made.

Easing function 👨‍💻

After watching the (as of this moment) last video in the parallax series I came to the conclusion that my boring old linear function wasn't gonna work. We needed an easing function; mainly to make sure the user can focus on the moving-element a bit better as it passes through the middle.

Unfortunately for me this was easier said than done. But I went on with the idea anyway.

I thought about what exactly I wanted to create over and over again. I drew countless images of how the element should progress as it passed through the screen, I took multiple shots at the maths behind it until it occurred to me.

Let's go back to that same image again. Consider the blue line this time.

As you can see the blue line progresses faster on the edges of the screen and stands still for a bit on the middle of the screen.

The form of the graph is quite particular. It reminded me of maths. I remembered that the function would have to be look something like this in order to get that same effect:

y = a(x-b)^3

I decided that the moving element would be positioned in the center of the page to start with. This way I could move the moving-element left or right accordingly.
Along with that I decided to give the graph a little more meaning. Consider the following image:

In this image the vertical axis represents the amount of pixels scrolled since the element came into view. This axis has a max of the screen height since after that the element will be out of view.
The horizontal axis represents the amount of pixels to move the moving-element relative to the horizontal center of the page. The maximal values of this axis would be +/- half the width of screen. After the element has moved half of the screens width away from the center it goes out of view.


With a clear image of what I wanted to create in mind it was time to solve the math. Unfortunately I'm not all that good at maths and after an attempt to solve this problem I realised I wasn't gonna succeed.

Fortunately for me, I came with the idea to post my question on math.stackexchange.com, stack-overflow's mathematical sister site. After clarifying my question a few times one of their users was able to create the mathematical function for me.

Remember that the function had to be a function that would output the moving-elements position in pixels relative to the horizontal center of the page based on the amount of pixels scrolled since the element was first visible. The function would have to be "steeper" on the edges and ease into a short stop in the middle and be usable across every possible screen size. Meaning that the mathematical function would have to be positioned based on two variables, screen height and -width.

The function they created ended up looking like this:

position = (4 * (s-width) / (s-height)^3) * (px_scrolled - ((s-height) /2 ))^3

(where "s-" is short for screen)

I've written it out in a more compact way that's impossible on GitHub:

image


This function works! I went ahead and coded it all out in JavaScript on codepen. You can check the pen out here.

The mathematical function written out in JavaScript looks like this:

var pos = ((4*win_width)/(Math.pow(win_height, 3))) * Math.pow(px_since_visible - (win_height/2),3)

Why am I telling you all this? 🙋

First of all, I'm a big believer in open source code. The general idea of open source speaks to me. For this reason I really hope that you can use the function I created in some way and possibly to share my findings with your big audience of web developers. They could all possibly benefit from this in some way.

Another side effect would be that some people might think they have a better way to handle the easing in this example. Or perhaps create a different type of easing function. Maybe one that doesn't stop in the center. I'd be very very happy to discuss ideas with people. As I said before: big believer in open source. Working together creates better solutions.

Secondly I actually hope that you'll take my idea, the horizontal easing function, and use it to perhaps kick off the parallax series again. I really enjoyed the series and as I said at the start: there is still some content you could possibly cover.

That being said I do realise that the chances of all this happening are kind of slim and I really don't want this to become me begging you. Just realise there is still people watching that "old" series.


This has become quite an article. Time for me to wrap things up. I hope you'll spread the code I created in some way, mainly because I want other people to benefit from the bit of thinking I've done.


Oh.. one last note: I'd really want to become a patreon, but unfortunately I can't seen my financial situation at this time.

Keep on hacking 👍

@Lokendra-rawat
Copy link

Lokendra-rawat commented Apr 4, 2017 via email

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