Jump to content
Search Community

Animating Object to Center of Window & Scale Based on Window Size Percentage

jh-thank-you test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

GreenSock Community,


First, thank you in advance for any help you may provide.


I am just learning how to use Greensock and web development in general, please pardon any newbie questions.


I have put together a CodePen here is what I am looking to achieve:

  • Each corner of the browser has a hyperlink with image for each section of the website. When you click on a section link that section image will move towards the center of the browser window (both vertically and horizontally centered) it will also scale up in size. The remaining section images will move out of the browser window frame (move off stage). This I have working... what I need help with is:
    • Each section image does not center properly. I have tried a couple of things based on some other forum topics found here http://greensock.com/forums/topic/13542-positioning-relative-to-center/ and here http://greensock.com/forums/topic/13802-update-height-value-dinamically-on-window-resize/
    • I would also like to scale the image to about 65% of the browser window width. I tried using the technique mentioned here http://greensock.com/forums/topic/13802-update-height-value-dinamically-on-window-resize/
      • I tried to replace "scale: 3" with "width: '65vw'" in my timeline but that did not work
    • I also noticed that sometimes the image/object does not animate anywhere near the center (sometimes going off screen) a page refresh and clicking the link again will usually correct this behavior but it seems the javascript is not calculating the proper initial window size (thus all the other math is off).
    • Also, is it possible to have the enlarged image (once it reaches its final animated position) be responsive (resize itself at the 65% vw) if the user resizes the window.
      • I tried using the the window resize function found in this codepen 

        See the Pen XdWaRv by celli (@celli) on CodePen

         but did not have any luck (likely because I was not able to sort the image size based on screen width as stated above).
    • This last question is not a GreenSock question but I figure someone in the community could guide me towards a good article or solution... after the section image is centered I want to dynamically load content below it so the user can scroll down and view the appropriate content/info. I'm hoping to help speed the page load as it will only load the content the user is looking for... I'm off  googling  on this one now but any help will be very much appreciated.

I hope that I have made things clear. Again, thank you for any help you may provide.

See the Pen ozrLOo by jh-thank-you (@jh-thank-you) on CodePen

Link to comment
Share on other sites

For anyone else who may come across this post I found an article that shows how to load content dynamically... I haven't worked my way through it yet but hopefully this will help out others. Here are the links:


part 1 - http://zurb.com/university/lessons/ajaxing-dynamic-content-with-foundation


part 2 - http://zurb.com/university/lessons/dynamically-update-your-web-pages



**** Additional Solutions for dynamically loaded content ****



This stack overflow talks about ViaJS





 Also a simpler solution - here is the code from the discussion:

<div id="topBar">
  <a href ="#" id="load_home"> HOME </a>
<div id ="content"></div>

$(document).ready( function() {
   $("#load_home").on("click", function() {

Another Stack Overflow talks about pjax




Link to comment
Share on other sites

Your calculations are off because you're using values from different coordinate spaces. Somebody had a similar issue...



I would start from the center of the screen, and go from there.

See the Pen QKQgyy?editors=0010 by osublake (@osublake) on CodePen


There are some good examples of responsive animations in this thread. 


  • Like 4
Link to comment
Share on other sites



Thanks for the response, I will look over the links and report back.


....went down the rabbit hole with the first link... just saw your codepen (second link)... THANK YOU!


Going through your code now and trying to figure out how to keep the image fixed to the corner on window resize like it was before... You have the centering spot on, it looks great!!!

Link to comment
Share on other sites



This is awesome surprise... I just got back in from teaching class and prepping for work tomorrow... I was going to call it quits for tonight as I have to get up early for work tomorrow. I 'm glad I decided to check the forum. This is perfect!!!! I will be sure to share the final product with you and the rest of the GreenSock Community/Team.


It has been a slow process for me as I have so much to learn. From a design standpoint I know what I want to accomplish, it is a whole other story trying to sort the code to make it happen.


Again, thank you! Have a great weekend.

Link to comment
Share on other sites



I have made some progress thanks to Blake's codepen and forum links (Thank you again Blake).


Here is the codepen:   

See the Pen OREYEj by jh-thank-you (@jh-thank-you) on CodePen


I have three things I am trying to sort:

  • 1 - Keep Animation/Placed Object where it is currently on window resize
    • Blake's codepen had the ability to resize the window and the current animation or positioned elements remain at there current place/state (and scaled nicely/responsive). From what I can tell it is done through this bit of code:
      •   var progress = tl.progress();
          var reversed = tl.reversed();
          buildTimeline(progress, reversed);
      • I'm thinking I need to nest - .add() -  the timelines to be  able to use Blake's approach. I tried to follow this thread ( http://greensock.com/forums/topic/8516-multiple-timelines-or-nested-timeline/) but I didn't have much success due to my lack of understanding how the function is being called (I have so much to learn).
        • I can share code for this but I don't think it is anywhere near what it should be - so I stripped it out of the codepen. 
  • 2 - I'm trying to set media queries to adjust the scale and placement or the corner navigation elements - I am conditionally setting this through the queries
    • I am trying to keep the Nav elements in each corner at a readable size.
    • I am applying scale to the element based on Blake's solution of scaling the object in the timeline.
      • var mediaQuerySmall = window.matchMedia("(max-height: 200px)");    
        if (mediaQuerySmall.matches) {      
              configScale = .22
        TweenLite.set(print, {  xPercent: -50,
          yPercent: -50,
          rotation: 15,
          scale: configScale
        • http://greensock.com/forums/topic/11172-using-media-queries-in-tweenmax/
        • I'm having issues with the media queries being applied - sometimes the scale/size gets calculated properly sometimes it doesn't - sometimes a window refresh will force the calculations sometimes it will not (I tried looking at this thread - Sorry can't find my link/bookmark will update later ).
        • I tried setting the queries both in CSS or in the Javascript (I remember another thread saying something about GSAP will not know when CSS changes something so it is better to have GSAP set things instead).
        • I also tried setting a function for on load and resize based on this stackoverflow topic - http://stackoverflow.com/questions/1974788/combine-onload-and-onresize-jquery
          • Note: I commented this out in the javascript file - this way someone can see what I did wrong.
  • 3 - After a corner Nav element is selected I want it to scale up to a size based on a percentage of the browser window width. I tried changing scale in the timeline to - width: "65vw" but this had no effect.
Thank you in advance for any help you may provide.
Link to comment
Share on other sites



Okay... here is another codepen -  


I have broken out each timeline into its own function based on which corner Nav element you select a different timeline will play.


I have a progress() and reversed() added to each function with a var assigned for each. This seems to sort the issue of all the elements popping back to the corners (going back to the beginning of the timeline) on window resize.


Where I am running into trouble is if I select a Nav corner and have it animate to center stage (then perform a window resize) I get the other nav elements (which animated off stage) popping back into the corners. Also, if I click on the center Nav element, to play the animation in reverse, the nav elements do not go back to the corners (or scale properly). So I solved one issue but created another set of issues. Note: if I click on the center stage Nav element and let it play in reverse to the corner and then resize the window the other corner Nav elements behave as expected.


I haven't tried to sort the scale/size of the selected Nav element (based on a percentage of the browser window size yet - will try to set something like "65vw"). I'm trying to sort one thing at a time.

  • UPDATE - Blake used "space = 200" for his calculation for the image size to be scaled up to... I'm trying to set scale based on a percentage vs a fixed pixel amount. The code below works to scale the image up to 65 percent of the initial window width or height but it doesn't recalculate properly when you resize the window. This seems to be the same issue, I guess, as the corner Nav elements with the initial value being referenced vs having a new number generated/referenced on window resize.  (I'm trying to learn/understand kill vs clear etc. from the docs http://greensock.com/forums/topic/8917-all-the-methods-to-kill-a-tween/)
    • var vw = $(window).width();
      var vh = $(window).height();
      var space = Math.min(vw * .35, vh * .35);
      // var space = 200;

Thanks in advance for any help you may provide.


PS - I'm thinking this GreeSock post may have the answer http://greensock.com/forums/topic/11188-how-to-update-tween-variable-on-window-resize/


also looking at http://greensock.com/forums/topic/9066-update-var-when-window-is-resized/

Link to comment
Share on other sites

Okay, a little bit of sleep and hopefully some fresh thinking...


Although not what I wanted:

  • the reverse animations from what I can tell are being fired properly and the x and y placement/path calculations are correct...
  • the thing is if I resize the window this change is not being adjusted for in the way the math is being calculated for x and y...
  • it's basically using the stored value/amount from the previous finished state... which is why if I let things animate back to the corners before a window resize everything works as desired.

All that said, my thinking is:

  • instead of using the .reversed for .click I should just use a .from timeline/tween from the current position on each element to the corners of the browser window.
  • I'm now reading the forums about how to ad a new click events to each element...
    • this approach would require me adding four (4) more functions with a timeline that has 4 tweens for each Nav corner element
    • in that function I will need to have a way to calculate the corner values
      • or can I simply set this with something like "top: 0, left: 0," or use xPercent and yPercent as found here http://greensock.com/forums/topic/10106-xpercent-ypercent/
      • can I use xPercent and yPercent in a bezier path - can I use a mix of point types on the path, meaning can one point be a numeric value or variable or xPercent and yPercent?  see https://greensock.com/docs/#/HTML5/GSAP/Plugins/BezierPlugin/ - Short answer - Yes.
        • "While it is most common to use x and y (or left and top) properties for Bezier tweens, you can use any properties (even ones that are function-based getters/setters)."
    • am I right with this approach, or is there a cleaner way to accomplish this - (some kind of method to calculate the new corner coordinates)?

Thanks for looking (even more for helping).

Link to comment
Share on other sites

Having issues when using jquery 2.1.4 and above (Zurb Foundation needs 2.1.4).


Here is a codepen using v2.1.3 


This has corner nav using GSAP and jquery v2.1.3
- After a nav element is selected it will scale up and center in the window
- If you resize the window the selected Nav element (now larger and centered in the window) will scale down with the window.
- Need to work with Zurb Foundation v6.x which requires jquery v2.1.4 which is causing an issue - instead of the hero Nav element staying centered on window resize it pops to the corner where it originally started. See codepen link using jquery v2.1.4
Here is a codepen using v2.1.4 

See the Pen QKVjJo by jh-thank-you (@jh-thank-you) on CodePen

Update: seems to be an issue with Zurb Foundation 6.x - a conflict... not sure where - there are no errors in the console.
Link to comment
Share on other sites

Sorry, I've been away. You've posted several things, so where are you now?


If you're using a CSS framework like Foundation, you need to make sure that it's not trying to animate the same properties you are trying to animate with GSAP.


For media queries, look at these demos...

See the Pen vExQEy by osublake (@osublake) on CodePen

See the Pen 7f3b39b23861664c3ecc399e23112b2a by osublake (@osublake) on CodePen


And this thread...



Do you have a link to an up-to-date version of what you're working on?

  • Like 3
Link to comment
Share on other sites



No apologies necessary, you are being very gracious with you time and expertise. After spending time on the forum reading through the various posts it is clear that the GSAP team cares about the community and really goes above and beyond. That said, I joined the club and consider it money well spent to support such a great product/team. Thank you!



In this codepen 

  • I broke each timeline into its own function.
  • I was able figure out how you were able to make the hero (center stage) element scale on window resize.
    • I am trying a different method (vs your 200px) to calculate the space around a hero Nav element so that it scales to 65% of window width or window height. It works great on the initial scale but on window resize it is not adhering to 65%​. Is it possible to set a the CSS property of 65vw or 65vh onComplete? 
    •  var x = -vw / 2;
       var y = -vh / 2;
      // var space = 200; 
      var space = Math.min(vw * .35, vh * .35); var ratio = 1;
    • The current problem I'm having is when you resize the window the other nav elements that animated off screen pop back into frame (not desired)
    • To try and remedy this I have the non-selected Nav elements to animate offscreen and finally set the display to "none". So now even though they pop back into the corners no one can see them. 
  • I removed the reverse call on the hero element. I need to learn how to clear the initial function and set a new play on click which would play a new timeline that creates a new path back to each respective corner. I'm reading about onComplete, I think this may be the answer I need.
  • My next step is to create a set of new timelines and tweens to create the reverse paths. I'm thinking this would force a new set of calculations for the path points (maybe I'm wrong with this thinking... not sure at this point).
  • My last step will be to load an animated gif on top of the hero Nav element along with the respective section items (again I'm thinking onComplete applies here). By the way the responsive 3up and 2up grid examples you provided links to will work well for these section pages. Thanks!
  • Finally, I have been keeping detailed notes on the process and providing links to other forum articles in hopes of helping out any other newbies like myself that may come across this thread... not sure if this is a desired practice.


    Thanks again for your help.

  • Like 1
Link to comment
Share on other sites

Here's a good thread about toggling animations using DRY principles (Don't Repeat Yourself).



Using techniques from that thread, I added a function that will create a card object to keep things logically grouped together. So now instead of updating stuff in 4 different places, you only have to do it in 1 place.


I also added another wrapper element which allow you to animate x,y properties from two different origins. So there are now 2 separate animations. An enter animation, when the element moves to the center, and a leave animation, when the element moves offscreen. Both of these animations can run at the same time so you don't have to recalculate anything.


Check it out...

See the Pen d127c412f8cad38a272bcbecf68e1638?editors=0010 by osublake (@osublake) on CodePen


About loading content via AJAX, are you trying to make a single-page application (SPA)? If you're using Foundation, you should look into Angular. That is what Foundation for Apps is based on.


Here's a simple demo showing page how to animate page changes using the router Foundation uses. If you click the launch preview icon in the top-right corner, you will see the url changing.




  • Like 3
Link to comment
Share on other sites

Thanks Blake, looking over and reading your links now... I will report back later.


 As for what I'm trying to build, it's a portfolio site for myself. I'm not sure if I would consider it a SAP at this point (maybe I should).

Update: The SAP link you provided is an interesting read. My approach does seem to lean towards SAP. 


I was reading about techniques to deliver content on request vs on page load (unless needed). I'm trying to keep the pages light and hopefully have them load fairly fast. I was thinking AJAX or techniques like it would be a good solution. This seems like a practical approach for the way the way I thinking about structuring the site.


Nav/Landing Page


• Grid/thumbnail examples

- selected example (full screen modal approach)


• Grid/thumbnail examples

- selected example (full screen modal approach)


• Grid/thumbnail examples

- selected example (full screen modal approach)


• Grid/thumbnail examples

- selected example (full screen modal approach)

Link to comment
Share on other sites

AJAX is asynchronous so you have to wait for it load. Not that it's slow, it's just annoying having to trigger stuff like animations in a callback.


I would just put your HTML in a string and append it using jQuery or insertAdjacentHTML for vanilla. That's how I do all my templates with Angular.


Check out my mystery SVG animation.

See the Pen f9ad0aafc2fa585e60e4b9642ac716b3 by osublake (@osublake) on CodePen


I have a hidden script in there that is loading this file, which contains a variable with the markup as a string.



SVG, HTML, doesn't matter, it's just XML-based markup.

  • Like 1
Link to comment
Share on other sites

Hello, hello!


May I butt in? Not to say much obviously, because you have Blake. And anyone who's got Blake got no problems.


I have been following this discussion and got somewhat interested in what was going on. So, I decided to have a stab at it following the base that Blake had given.


That, was a few days ago. Much has happened and you two seem to be getting along famously. ;)


In any case, I wanted to share how I approached the idea. I thought it would be better to just create Tweens, rather than timelines. Dunno, just because there's nothing chained here so it just felt more natural. And, because, at the time that I started this, you were creating and destroying a load of timelines all the time.


Well, enough of rambling. Codepen bellow. I will change the visual of it at some stage, I am quite happy with the code I ended up with so, if nobody's against it, my pen will be left public.


See the Pen ?editors=0010 by dipscom (@dipscom) on CodePen


ps: Jim, have a look, it might help you with your responsiveness as it will take vw and vh as units without having to keep recalculating extra stuff.

  • Like 3
Link to comment
Share on other sites

Blake and Dipscom,


Thank you, sorry for the delayed response. I will definitely look at the links and examples you provided.


I'm in the process of of trying to pick apart Blake's last codepen... I have so much to learn... I'm in the early infant stages of understanding Javascript and at this point I feel like I have jumped into the deep end... anyways...


Thank you gents, I will post back my findings. I REALLY appreciate the help!

  • Like 1
Link to comment
Share on other sites



I'm missing something in your SVG example.


I understand that the JS is appending the body element with mySvg, but how/where is it getting it from? I'm not seeing any external links listed in the codepen source to the SVG code. How is the var "hidden" and called up/appended?



Ahh... missed this in the head "<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/106114/svg-string.js"></script>"



Thank you again for all your time and patience.

Link to comment
Share on other sites


Ahh... missed this in the head "<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/106114/svg-string.js"></script>"



Haha! That's why I called it the mystery SVG animation. I got @Carl with it, and he tweeted it as a challenge.



Just let me know if you don't understand anything. I tried to leave to links to the stuff that might be unfamiliar to somebody just starting out. I know that jQuery's extend and map methods can be a little confusing to understand at first, but they are really powerful.


And @Dipscom's version looks really nice. I've found that trying to make animations responsive is usually not worth the effort. His approach to creating the tweens on demand seems to work really well. 


But even better approach would be additive animations. Check out this craziness...

See the Pen mepBam by osublake (@osublake) on CodePen


Well, that's not a feature of GSAP yet, but I'm hoping it will be one day it will be. Voice your opinion if you like the idea. 



I know I'm not the only that likes the idea. I was surprised to find out this morning that Robert Penner liked a bunch of my demos from that thread. If you don't know who he is, he's the creator of the easing functions that are used in practically every animation/tweening library.



  • Like 1
Link to comment
Share on other sites

Hey @Dipscom,


I just wanted to point something out about your switch statement. Technically, there's nothing wrong with it, but your break statements will never be reached as return will exit immediately, so they are kind of redundant. Same thing for returning null for the default case as every function in JavaScript returns undefined by default. If you're checking for a falsy value, null and undefined are the same. 


So you could rewrite it like this, making it a little cleaner.

switch(trg.id) {
  case "print": return print;
  case "broadcast": return broadcast;
  case "outdoor": return outdoor;
  case "online": return online;


  • Like 3
Link to comment
Share on other sites

Hey @Dipscom,


I just wanted to point something out about your switch statement. Technically, there's nothing wrong with it, but your break statements will never be reached as return will exit immediately, so they are kind of redundant. Same thing for returning null for the default case as every function in JavaScript returns undefined by default. If you're checking for a falsy value, null and undefined are the same. 


Ah, good catch Blake.


Now let us all pretend I did that on purpose to test you, yes? And we can say you conquered the challenge. Deal? Nothing to do with the fact that I completely missed that the return would exit before the break statement.

  • Like 1
Link to comment
Share on other sites



I hope all is well. Thank you for the updates. I'm learning a lot thanks to the both of you but I have to admit I'm in way over my head. I burned the midnight oil last night trying to get my head wrapped around this. I'm creating a codepen now... I'm working with Zurb's Yeti Launch... I have to sort the page partials and redo all the links... I will post something within the hour. 


Dipscom, your solution works great for the animation and setting the scaled up image size based on vw... Blake your version works great for maintaining aspect ratio of the images and it was easier for me to break out where I needed to make changes to load in my own custom images/sizes.


Dipscom, I tried to make a variable that gets passed to the CSS based on media queries.... I have that part working... now I'm trying to figure out how to pass that to the CSS in the tween and still maintain the aspect ratio of the image to be scaled up or down.


Found these - they may help with aspect ratio:




also testing out this method for aspect ratio:



...and yet another:




...will post a codepen link soon.





Link to comment
Share on other sites

Blake and Dipscom,


Here is a new code pen: 

See the Pen GjYPPY by jh-thank-you (@jh-thank-you) on CodePen



It's a bit messy (...cough). I did spend a lot of time learning how to write the logic (I'm guessing at what I should call it) for the variable that is getting sent to the tween. I was able to sort the scale issue with this but I am stilling have issues with the media queries kicking in (I'm seeing that the number is being calculated on screen resize - I made a little data input field so you can see it in action).

// Determine which is greater vw or vh

var space = function() {
if(vw < vh) {
  space = "vw";}
else {space = "vh"}; 


// several media queries to determine the percentage of the scale

var mediaQuerySmall = window.matchMedia("(max-height: 200px)");
    if (mediaQuerySmall.matches) {      
      configScale = 20
// see codepen for full query list

// Create a variable that will be passed to the CSS in the tween
// It will also be passed to the DOM via an input field
var configSize = configScale + space;

  var txt = document.getElementById("t1");
  txt.value = '"' + configScale + space + '"';

(I had a tired smile on my face at 4 in the morning when this code actually worked!)

Update: Spoke too soon, it works with the initial call but if I start off with a full desktop screen and try to reduce the window size it does not scale down.

Not sure what the issue is... sometimes it works great, sometimes the hero image does not scale down or up on window resize.


Sorry for the mess - I have images (animated gifs that load via a delay) - they overlay the base nav image in each corner. Right now they are a different size than the base images - I'm scaling them at a different size - I'm trying to maintain readability at smaller sizes but also keep them from getting too big in relation to the hero element on the larger window size. I'm guessing I could create 3 sets of images that are built the same size as the base image - it would make it easier to align and scale with the base image but it adds to page load and the amount of DOM calls.


For the nav base images, It looks like I will need to set the padding and margins via media queries, but before I started doing that I wanted to share where I am at. You guys will certainly know of a cleaner more succinct way of approaching this. 



Dipscom's solution sets scale to 80vw and 80vh and width... I changed the width to a variable and passed that to the CSS in the tween...

var configSizeLarge = configScale + 25 + space;

and used this code to maintian the aspect ration within the div.

Update: I'm going to change this...  I will create a variable that will pass in a different value for each media query... 90vw on small, 65vw on medium, and  50vw on large.

/* ****************************************************** */
/* ****** Nav Maintain Image Aspect Ratio on Scale ****** */
/* ****************************************************** */
.media-type > img {

I'm not sure how to set the aspect ratio in Javascript so I went with what I know.


Thanks for taking the time to read through all this. I hope I edged things along, I know it's not as elegant as your solutions but I'm learning.

Link to comment
Share on other sites

Hey Jim,


I am not too sure if you need to set so many things with JavaScript. I am not following why you would want to control the image's aspect ratio with JS. Images have intrinsic image ratios so, you really don't need to be handling that with JS, CSS wizardry will do the trick. 


I can see why you would want to control how large the container div gets relative to the screen size but other than that, the feeling I am getting is that you might be going a bit too deep into this rabbit hole.

  • Like 1
Link to comment
Share on other sites



I came across a forum post that was talking about how GreenSock doesn't know what CSS is doing (not passing along the info/coordinates)... there was a discussion about having GreenSock set things this way it knows where everything is and can animate accordingly.


Not having the images show properly in the last codepen was bothering me so I forked it and moved the images back into the divs via the html page rather than CSS background image. Using the CSS centering technique did the trick I had to update the CSS targeting the Nav image...

/* ****************************************************** */
/* ****** Nav Maintain Image Aspect Ratio on Scale ****** */
/* ****************************************************** */
.media-type > img {

#centerImg {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);

For centering -  other newbies look at





 I just need to:

  • sort the titles and get them to move in relation to their respective background image. I'm hoping this part can all be done in CSS (I will more than likely create a set of title images that are the same size the respective background image so I can get the alignment nailed down).
  • Figure out how to get the media queries to recalculate/redraw the scale... from the input field I can see the variable is changing but GreenSock is not recalculating the size, it seems to be storing the initial calculation. Any idea what is going on? Do I need to set these with GreenSock/Javascript or should I use CSS for maintaining the scale based on screen size. What is the proper/preferred way?


Getting closer... will report back soon.


Thanks again!!!!


Here is the current codepen link 

See the Pen dpQvjV by jh-thank-you (@jh-thank-you) on CodePen

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.
  • Create New...