Jump to content
GreenSock

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

GSAP Inside of a responsive layout

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

Hi,

 

I have some fairly simple tweens with timelineLite like this

.fromTo('.circle-top', .5, {left: 268, top: 155, opacity:0}, {css:{left: 337, top: 83, opacity:1}, ease: Circ.easeOut }, "-=.5")
  .fromTo('.circle-bottom', .5, {left: 418, top:22, opacity:0}, {css:{left: 348, top: 92, opacity:1}, ease: Circ.easeOut }, "-=.25")

And the width of my container is 760 pixels wide, so the animation is always centered with CSS until I reach 760px wide in my browser. Then when the browser resizes to under 768 pixels, I have a simple media query which makes the animation container 540 pixels wide like this:

@media (max-width: 768px) {
.anim-container, .circle-container{width:540px !important;}
.circle-top{ left: 240px !important;  }
.circle-bottom{ left:250px !important; }
}

Also in the CSS you will see the absolutely positioned 'circle top' and 'circle bottom' switch their positions in order to stay centered in the 540px wide container (this is their end position).

 

Which works just fine. However, when the animation plays at the 540px width -- the end position is fine, but the start position from GSAP tween isn't right (as you can imagine it is relative to the wider container)

 

Questions:

1. Is there a way to simplify all of this in a responsive container to make everything scale ?

2. Doing this for every element in a responsive layout seems like it would take a very long time, since I'd need to measure the position of every element twice and probably 3x to get down to 320 pixels on mobile, there must be an easier way I'm missing ?

3. If we do it this way, is there a way to use media queries in the GSAP code to specify the' from' and 'to' positions depending on the container size or depending on the media query I set up ?

 

thanks!

Link to comment
Share on other sites

Hi celli   :)

 

Yep , there's an easy way ; you can use  xPercent and yPercent ( CSSPlugin) to positioning in responsive layout .

 

See the Pen axzmb by GreenSock (@GreenSock) on CodePen

 

See the Pen axzrw by GreenSock (@GreenSock) on CodePen

 

See the Pen 290c237a0f550288c84ed0312267f7ec by GreenSock (@GreenSock) on CodePen

  • Like 3
  • Thanks 1
Link to comment
Share on other sites

That is great! Thank you.

Link to comment
Share on other sites

Hi  Ancient Warrior,

 

I have been experimenting with the xPercent and yPercent, and I think I see what it does, but I am having some issues, and some questions that maybe you can help to answer:

 

1. Is there a way to have a Master Container, and everything inside will scale proportionately when I rescale my browser ? or will the xPercent and yPercent keep elements only fixed at the center of my container only ?

 

2. I see if I use this CSS and JS Mix:

//CSS to place origin of all elements in the center or their parent
.myClass {
  position:absolute;
  left:50%;
  top:50%;
}
 
//JS
//center all .myClass elements around their origins
TweenLite.set(".myClass", {xPercent:-50, yPercent:-50});//handles all vendor prefixes of translateX(-50%) translateY(-50%)
 
//now we can animate myElement's x/y such that its center is 100px,200px from the origin
TweenLite.to(myElement, 1, {x:100, y:200});

It will now use the elements center as the anchor point, and add these elements to the center of my conteiner which is great for animating from the center. Can I easily add this to all of my elements with an array of some sort or maybe like this: TweenLite.set(".myClass1, .myClass2, .myClass3, .myClass4, .myClass5", {xPercent:-50, yPercent:-50});

 

3. I assume that even if we can scale proportionately all elements together -- we would have a problem with fonts scaling as well ?

 

4. I guess the big question is my first question here. I see it works with rectangles in a container, and the text will wrap and not scale. but what if we had many elements inside of one container -- and when we scale the container -- we would also be scaling every element inside of that container together ?

Link to comment
Share on other sites

Okay, I managed to get something working that is responsive thanks to the {xPercent:-50, yPercent:-50} which works quite well to keep each element's anchor point at the center, combined with left:50% and top:50% in my CSS to keep elements centered within my container.

 

I think this is a better solution, than scaling the entire container and all of it's elements anyway -- but if there is a way to do that, It would be helpful to know, as it might be necessary for some things.

 

Here is the result with 3 major break points at 991px 768px and 421px. But I could have also done it fluidly I guess, as your examples show.

http://www.micelistudios.com/sandbox/gs/banner.html

 

GSAP is Fun!

  • Like 1
Link to comment
Share on other sites

Hey Celli,

 

Thanks for sharing the finished work. Very impressive!

 

Carl

Link to comment
Share on other sites

  • 1 year later...

 

 

 Is there a way to simplify all of this in a responsive container to make everything scale ?

 

as an exmple:  If you resize the width of the browser when viewing the following web page you will see that the image slider area scales: surgemarketingsolutions.co.uk

 

Here is the code i put together to handle it:

 

in the example code

$(".slider_overflow")  was my outer content wrapper

$(".slide_outer")  was my inner content wrapper (i know its named wrong! :)  )

natural_width is the width on desktop - the maximum it can be

natural_height is the height on desktop - the maximum it can be

var contentResizeTimer;
function scale_content_on_window_resize(outer, iner, natural_width, natural_height) {       
   /* 
    Here we pass in an outer wrapper and an inner wrapper. 
    Our content sits inside the inner wrapper.
    We then calculate the scale from the original height and width of the outer wrapper.
    At desktop the scale will be 1.0 but as the browser width decreases the scale will gradualy get smaller.
    The calculated scale then gets set on the inner wrapper and the height of the scaled element then gets set on the outer wrapper.
    This is to remove the borders around the scaled inner element.
   */
    var outer_width = outer.width();                        
    if (outer_width > natural_width) {
        outer_width = natural_width;
    }
    var theScale = outer_width / natural_width;
    // Calculate the actual slides height after its scaled.
    var processed_height = theScale * natural_height;
    TweenMax.to(outer, 0.2, {
        height: processed_height,
        width: "inherit",
        maxWidth: "100%",
        ease: Power4.easeOut
    });
    TweenMax.set(iner, {
        autoAlpha: 1.0,
        transition: "all 0.2s ease",
        transformOrigin: "top center",
        scale: theScale,
        marginLeft: "0px",
        marginTop: "0px"
    });
} // end function scale_content_on_window_resize

$(window).resize(function() {
    clearTimeout(contentResizeTimer);
    contentResizeTimer = setTimeout(function() {
        scale_content_on_window_resize($(".slider_overflow"), $(".slide_outer"), 1140, 560);
    }, 100);
});
scale_content_on_window_resize($(".slider_overflow"), $(".slide_outer"), 1140, 560);
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.
×