Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
jh-thank-you

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

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

Dipscom and Blake,

 

I will try using the media queries in the CSS instead of in the Javascript. I will also add in Blake's update (didn't catch that in the last codepen).

 

Once I get a few more things worked out I will post a new codepen.

 

I will be out of the loop until early next week. I have a big project that just landed in my lap and I have a couple of heavy deadlines for Monday and Tuesday. It's a good thing to be busy with work but something has to give.

 

Enjoy you week/weekend.

 

All the best,

Jim 

 

P.S. Is there a way to add a photo or video to a post? It seems that I need the file to be uploaded already to attach them, but I'm not seeing how I can upload the files to my account in the dashboard. Thanks.

Link to comment
Share on other sites

Community,

 

I hope everyone had a great weekend.

 

I have a new codepen with some things sorted, here is the link 

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

  • Media queries for corner nav images scale based on screen size (uses whichever distance is smaller when comparing vw vs. vh)
  • Hero image scales to whichever distance is smaller when comparing vw vs. vh.
  • Added input field to show media queries are passing the right info to the CSS via a Javascript function and variable.
  • ISSUES:
    • The initial hero image scale is correct but on window resize the image does not scale properly - if the CSS is set directly in CSS it works, if the property is passed in by Javascript it does not work.
    • Tried to force vw or vh based on adding a class to the image onComplete - the CSS gets set to the added class but the image still does not scale properly.
    • Tried using a "tick" listener, like Blake had in one of his pens, to try and force a recalculation of the scale values (did not work).
    • Another issue, if you click on the nav image and have it scale up, then change the window size, when the animation plays in reverse it does not go back to its original scale/size; OR, if you change the window size before clicking a nav image it will not scale to the proper size. ONLY when you initially load the page (and not make any window size changes) does everything scale animate/scale up and reverse animate to proper position and original scale/size as expected.

I'm not sure where to go from here. I'm not getting any errors in the console but my logic must be wrong or I am missing how to make sure the the proper calculations are re-calculated on window resize. Is there a way to have have data recalculated without a screen redraw/refresh? I have an on resize window function working (as seen by the input field being passed the proper calculations on resize) but again, it doesn't have the image resize properly... If I refresh the window the proper calculations are made and applied.

 

Thanks for reading and helping.

Link to comment
Share on other sites

Dipscom/Blake,

 

I hope your week is going well.

 

Here is a new codepen 

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

 

 

I moved most of the media queries to the CSS (I also removed all queries and set the Hero Element scale to Dipscom's initial "65vw" - it made no difference).

I sorted the placeholders for the animated Gifs and the Hover State for the Gifs (everything aligns, scales and centers together).

 

The scaling issue remains. The initial hero image scale is correct but if you resize the window while the hero image is large, and centered and then click on it to trigger the reverse animation, it does not scale properly. It will either be too large or too small, dependent on if you resized the window up or down. The Hero nav element will scale back to the corner but the size will match the scale prior to the window resize.  See the attached image.

 

Thanks in advance for any help you may provide.

 

 

post-47357-0-74656700-1477535121_thumb.jpg

Link to comment
Share on other sites

As a test I forked Dipscom's original codepen - justing adding the media queries to his CSS. The scaling issue remains... Not sure how to have GreenSock to animate the hero nav element back to the corner at the new Media Query size (so it matches the scale of the other corner Nav elements). If you refresh the browser at the current window size the nav elements will all be reset at the correct size. 

 

Here is the codepen link 

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

 

Recap for those jumping in at this point. To solve this I have tried:

  • "tick" listeners etc. with functions for capturing and updating the window dimensions and setting the element size.
  • Setting the CSS scale via GreenSock.
  • Setting the CSS scale via CSS media Queries in the CSS document itself.
  • Having a class added to the element onComplete. This works but there is a jarring pop as it's calculated/adjusted to the CSS, media query assigned, size. (I'm trying to get my head wrapped around the clear methods... maybe this is the key to the problem?).

 

Here is an animated Gif showing the issue.

 

post-47357-0-04793900-1477593764_thumb.gif

 

Thanks for reading.

Link to comment
Share on other sites

I showed how to maintain an aspect ratio. Here's a simplified version.

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

 

If a media query changes properties that are used to calculate something in your animation, you should use listeners like I showed in my last demo.

  • Like 3
Link to comment
Share on other sites

Blake,

 

Thank you for checking back in... I really appreciate the help... the wife is about ready to trade me in... I just worked through the night on this...

 

I have things working but not in a DRY way. You and Dipscom came up with such short and sweet code to make things happen! I'm not there yet with my understanding of javascript to make that happen... when you know next to nothing it takes a looooonnnnng time to get up to speed as I'm learning even what the correct questions are to ask/search for.

 

Sorry, I don't have a simplified Codepen... I have to get some sleep. Here is a link to a dev folder I threw up on the server http://herous.org/dev/index.html

 

I'm having one issue. I'm trying to get the Hero animation to tween/fade out on the return/reverse. It works fine if you just load the page and don't resize the window... all of the corner nav hero animations fade in and fade out on forward/reverse. If you resize the window it doesn't work. Near as I can tell it has to do with the insertAdjacentHTML technique I'm using to load the Gifs. I'm seeing in the DOM that the insertAdjacentHTML is firing off multiple instances on resize. Since the initial is set to an opacity of 1 the element never has a chance to fade out. I tried:

http://stackoverflow.com/questions/15291229/kill-function-after-click-event-javascript 

http://stackoverflow.com/questions/20719491/jquery-stop-event-after-running-once

http://api.jquery.com/one/

 

I have to read more about Angular JS that you suggested etc. I think insertAdjacentHTML is going to limit what I can do (or make it more difficult than it should be). 

 

Would you suggest  that I have all the GreenSock Javascript in one shot for all page sections or is it better to create modules and load only the custom js that is being used for the page/section selected?

 

Should I convert the animate Gifs to animated sprite sheets? I'm thinking the sprite sheets would allow for more control I was looking at this https://www.codeandweb.com/sprite-sheet-maker?_cawex=2  

 

Thanks again for the advice/help/guidance! I hope you have a great weekend!!

Link to comment
Share on other sites

Blake,

 

Thanks again for the new codepen. Yes, I saw how you and Dipscom were using the resize function and how your put your vars within it to have them update on resize. That part worked great, the scaling issue I was having is with the tweens/timelines that store both the starting and ending values.

 

The array approach that you both used is great, but when GSAP grabs both values and stores them (then you resize the window) no matter what I did, the value that GSAP stored prior to resize is what it would use. I tried using an onComplete and a clearProps: "width, height" in hopes that it would help. I even tried an updateTo but nothing I did would work. The link I provide this morning has all the resize issues sorted. The code is nowhere near as clean and graceful as your and Dipscom's methods.

 

Thanks. I'll keep you posted on my progress... 

Link to comment
Share on other sites

Hello Jim!

 

Apologies as I have been away from here due to "real life". I know, it sucks how it sometimes gets in the way of us nerding off here...

 

Anyways, I was having a hard time understanding why you wanted to use media queries so much and why the solution I provided wasn't good enough. I now get it that what you were referring to was the buttons in their "small" version - at the corners. You needed to adapt their sizes to accommodate different screen sizes.

 

Don't think we ...(well, I. Because this is child's play to Blake. He's part cyborg. His brain is a CPU system and the rest of him is biological)... don't struggle with this too. I have banged my head on the wall for hours today before bitting the bullet and abandoning the media queries completely.

 

Since we're this deep in the rabbit hole and handling so much with JavaScript, you might as well handle the media queries bit of it with JS.

 

I have updated my pen with a bit more logic and it is working to me. Have a look:

 

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

Link to comment
Share on other sites

Dipscom,

 

Thank you very much for the effort you put it into this. Also, as Cyborg-Blake has done, thanks for being so generous with your patience and knowledge.

 

I would gladly use either your or Blake's solution (far less code than I have used) but I was/am struggling to find a solution with the scale/alignment issue. It happens whether you scale it up or down. The animated Gif shows the issue in action back in post #29.

 

Your latest codepen is having the same issue but now in reverse. See a Gif showing the issue in action here http://herous.org/gsap/2016-11-05-dipsom-codepen-2.gif (sorry for the link GSAP says I only 35kb left of attachments. I think there is a 500kb limit per thread). Also, it does not hold it's large scale size on window resize (it reverts to the initial scale) see here http://herous.org/gsap/2016-11-05-dipsom-codepen-3.gif

 

Near as I can tell it's how GSAP stores the initial values for the start and end of a tween that causes the issue. I don't know how to force GSAP to update its current set of values before invoking a reverse play. This is a similar to an issue I read about in another GSAP forum thread. The only solution was to save the current state values, kill the tween then invoke a new tween. http://greensock.com/forums/topic/9670-tweenmax-updateto/. I tried this method but when I killed the tween none of the button events would work.   

 

I just discovered I now have the initial values issue happening on window resize with the reverse play for the other nav elements. Here is the scenario:

- Click corner nav, it scales up to center stage.

- Click center stage hero, it will scale back to the corner.

- Select a different corner nav it scales to center stage... all works as expected.

 

Vs.

- Click corner nav, it scales up to center stage.

     - resize the window.

- Click center stage hero, it will scale back to the corner.

- Select a different corner nav - Now - the first selected corner nav will pop to center at initial scale and tween to the corner (and other wackiness).

 

See animated gif here:

http://herous.org/gsap/show-tween-return-position-issue.gif

 

Website here:

http://herous.org/dev/index.htm

 

I'm guessing this is caused by the initial values being stored for each tween/timeline  (I'm seeing in your code you made the //Flush tween - tween = null onComplete) i will give that a try and report back. If it that doesn't work I will make a simplified codepen and post it up.

 

Update: solved this issue by calling the resize() function onReverseComplete (this flushes all the stored initial values) - all is well... off to try and solve the insertAdjacentHTML/dynamic loading of the section content. 

 

Thanks again.

 

All the best.

Link to comment
Share on other sites

Nice! Well done Jim!

 

Have a cuppa after solving that. And remember to tackle one problem at a time

 

;)

  • Like 1
Link to comment
Share on other sites

Blake / Dipscom,

 

I have things working but in a very long (not DRY) way.

 

Dipscom my final version is a of a hybrid between your and Blake's approach (I used your array math for the paths and centering and Blake's timeline creation function and my media queries to determine scale/size).

 

I have to read/learn more to get my head wrapped around the DRY approach. I understand the concept but what I'm in the process of learning is the javascript/jquery language itself. I can see how the information is being passed but what I need to learn are what are the options to work with... so much to learn... definitely in the infant stages of understanding it.

 

I will clean things up and use placeholders images for a final codepen (this to help others who may be looking for this information). I will post that up in a few days. I will also update you guys on the next phase/stage.

 

Thanks again gents, I hope you both are having a great weekend.

Link to comment
Share on other sites

http://herous.org/dev/index.html

 

I added a small screen menu animation that kicks in at certain/screen sizes.

// Determine which Landing Page Starts   =========================
 var launchLandingPage = window.matchMedia("(max-width: 500px), (max-height: 200px) and (max-width: 600px)");
    if (launchLandingPage.matches) {
      // Launch smallLandingPage
      tlSmallLandingPage.play();
    } else {
      // Launch mediumUpLandingPage
      tlSmallLandingPage.reverse();
    }

Working on the dynamically loaded page/section content next.

 

Will keep you guys updated. 

 

Thanks again for all your help!!!!!

Link to comment
Share on other sites

  • 1 month later...

Blake & Dipscom,

 

 

I wanted to wish you both all the best for the holidays, safe travels, good health and happiness for the new year!

 

All the best,

 

Jim

  • Like 1
Link to comment
Share on other sites

Thank you Jim,

 

May you have a happy holidays a great new year and code with few bugs.

 

:)

  • Like 1
Link to comment
Share on other sites

  • 1 month later...

Blake & Dipscom,

 

I hope all is well, I wanted to share my progress so far... there are still rough patches (sorting and learning as I go). Below is a link to the current dev site. Note, the Print / Advil is the only path that is fully sorted... you can still load the other sections but the client work and modal for each is not set yet.

 

My next steps are to:

  • Sorting a script for dynamic link loading of the animated first image set within the Modal - basing this on att id.
  • Sort some spacing issue at small sizes for the Modal Slides
  • Create an alternate large screen presentation taking advantage of the Marker Pad, Graph Paper, Napkin and Envelop as part of the animation for the Modal also on large screens the the thumbnails will go away/be replaced by hand drawn names and doodles that will go on other side of the Section Hero Image (Marker Pad etc.)
  • Create a preference panel where visitors can choose industries that interest them, then only be presented those industries throughout their visit on the site (cookies and forms?).
  • Prepping the rest of the image content for all the client work.
  • Creating a locally running option for a Tablet ( Any suggestions on which way to approach this?)

 

Thanks, as always any suggestions or guidance is much appreciated.

 

All the best,

Jim

 

Here's the link: http://hainis.net/dev/index.html

  • Like 1
Link to comment
Share on other sites

Hey Jim,

 

Well done, it's starting to come together, isn't it?

 

I haven't got experience with offline sites to help you with the tablet option, sorry. One day, maybe.

 

It looks like it's starting to get quite complex there. The only thing I can say is to make sure you break your steps/functionalities down to the simplest logic possible, otherwise you might end up lost in the noise.

 

Also, you will probably be better off starting a new topic if you want to ask about other stuff, it helps to keep the forum organised and makes it easier for people to find answers if each thread only deals with one question.

 

Looking good man!

 

:)

  • Like 2
Link to comment
Share on other sites

Dipscom,

 

Thanks for the feedback.

 

Yes, I feel the same way with the complexity. It's part of the reason why I started to break the scripts up and only load what is needed for each section; one script loads for the section content then another loads for the modal. Still, I feel I can break it down even more, I will chip away at that at a later date, for now I want to get everything working then see how I can streamline it.

 

I do have some performance questions, once I'm done doing a bit more research I will post them as separate topics.

 

Thanks again for your encouragement, both you and Blake have been so gracious with your time and expertise, I really appreciate it.

 

I will be sure to follow up with the final site.

 

All the best,

 

Jim

  • Like 2
Link to comment
Share on other sites

  • 1 month later...

Blake and Dipscom,

 

I hope all is well.

 

A few more steps in the right direction... here is the latest http://hainis.net/dev/index.html

 

I have added a Preference and Contacts section/Tab at the bottom

I added visibility filters based on class names using Isotope for it's filtering capabilities http://isotope.metafizzy.co/

I have added local storage to the Preference Tab checkbox form -  it stores the form values and passes them on to the next djax/ajax page load so the preference/filters are persistent across all page during a user's visit to the site. I posted a how-to on the Isotope GitHub page: https://github.com/metafizzy/isotope/issues/1236

If you click on Print then Bayer client work (lock image) thumbnail a password overlay will display

- enter the correct password "BigPharma" and it will launch the client work overlay modal with the Bayer work

- if you enter an incorrect password it will cycle through several response messages

Only the Print > Advil and Print > Bayer Thumbnails are operational.

 

Next steps

  • Sort the performance issues (duplicate event handlers on the same DOM elements? Clone being created multiple times. Other... need to learn a DRY approach... need to learn how to modularize the code).
  • Sort the IF/Else Conditional statement only working on first run through with the Password Modal. SOLVED
  • Create the Video Modal

 

All the best,

Jim

  • Like 2
Link to comment
Share on other sites

I think the easiest way to do stuff like this is to use a single-page framework. I mentioned Angular earlier, but another library you may want to look at is Vue.js. It's easier than Angular, and is really popular right now. Here's a good overview on how to get started with it.

https://css-tricks.com/intro-to-vue-1-rendering-directives-events/ 

  • Like 1
Link to comment
Share on other sites

Blake thanks for the link/info. I will be sure to look into it. I'm a bit more comfortable with some things now, when you first mentioned Angular the thought of starting from scratch and learning another language was daunting... honestly, it still is, but I'm a bit more willing to try. Have a great day.  

 

Which would be worth the time investment - which would be easier to convert to a local running hybrid web app?

Link to comment
Share on other sites

Yeah, Angular can be pretty daunting to start off with, that's why I think Vue.js might be a better fit. Angular is also being phased out for a new version which is a complete rewrite, and has some issues when it comes to integrating with GSAP.

 

So what do you mean by a hybrid app? One that can run as a native app too?

 

BTW, you said were you beginner when you started this project, but I can tell you that you're not anymore. You've definitely leveled up! 

Link to comment
Share on other sites

Blake,

 

Thanks for that compliment, it is kind of you to say... I feel like I'm getting my head wrapped around things a bit more but as I look at the code that I started with I feel like it is spaghetti compared to what you and Dipscom have showed me.  

 

I was reading about, Native vs. Web vs Hybrid Apps https://www.mobiloud.com/blog/native-web-or-hybrid-apps/ 

 

I'm thinking more along the lines of a Web App - where I put the webpage into a wrapper of sorts (no browser toolbar etc) it will run on anything Android/Apple/Windows... kind of like the flash projectors of old... where everything is wrapped into one self-contained package with no outside dependencies.

 

As always, I appreciate the help and guidance. Have a great evening/day.

Link to comment
Share on other sites

Everybody starts off with spaghetti code. Using something like Angular, Vue, React, etc can definitely help clean some of that code up. Instead of starting out with a bunch of elements that you manipulate with JavaScript/jQuery, you start out with a view model that describes what should be displayed. Basically a JSON object. The framework then constructs the view (html) based on that object using some custom elements and attributes.

 

Look at this example. 99% of the JS code is a JSON object. All the important stuff is in the HTML.

See the Pen 1ea58bb4356f60a8515dc85d9f4be5b4 by osublake (@osublake) on CodePen

 

Another important thing a framework like that can do is routing. Instead of reloading the entire page, it just reloads a section of it, so your app's state is preserved. See how you can change the ratings here, go to another page, come back, and the rating doesn't get reset.

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

 

And about the hybrid app stuff, that just talking about using something like phonegap/cordova, which is a wrapper around the device's native web view. So anything that you can do with normal html/css/javascript will work. There are also specialized frameworks like Ionic, which is based on Angular, and does a good job of emulating the native UI of a device. Android and iOS apps look a little different.

 

.

  • Like 1
Link to comment
Share on other sites

Blake,

 

Clean and Concise and looks so much easier to maintain.

 

Looks like (almost) everything I have been struggling to create is already baked in with these frameworks.

 

  1. I'm using dJax for partial page loads - I'm having trouble making sure things bind properly despite using the djaxLoaded function that the developer has baked in... I'm still learning what to do in this case. - I'm guessing this is what you mean by "routing".
     
  2. - I added filtering for client industry type with Metafizzy's Isotope -  in the spirit of sharing/helping I posted up a small how-to for others with filter persistence across AJAX page loads https://github.com/metafizzy/isotope/issues/1236 - Is this baked in with Angular, Vue or React? I noticed if I stay within the app navigation, the rating remains the same... If I jump to another domain and hit the back button the rating is lost. I used a local storage solution for the Isotope filter settings to get around that issue. It would be great if the frameworks handles all that already. By the way, it put a smile on my face to see Street Fighter as your characters for the search filter example.
     
  3. The section-content.js captures the ID of the DOM element that has been clicked and passes it on to the custom-modal.js. This allowed me to use one set of functions for all the thumbnails.  I'm not sure if I am doing this in the cleaniest/simplest way possible, do you have any good how to articles about making the code modular? Meaning I write a block of functions that get called to do something from a main script. Is this the proper way to work with the code? Or is it better to keep everything in one JS file? My thought is by breaking everything up into blocks it will help to organize it and two I only call/bring in what is needed as the user interacts with the site.

For now I'm going to get all the assets into this this template — just so have something to show my work.

 

Based on your suggestion I'm going to start a fresh build with one of these frameworks. I will add in the bits that I'm happy with from this learning experience. My goal is to see if I can simplify things and in turn speed things up. Also, thanks for posting up your suggestions in the other thread on Speed/Performance.

 

All the best,

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.
×