Jump to content
Search Community

Using GSAP with Angular2

TehThird test
Moderator Tag

Go to solution Solved by OSUblake,

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

Hey, I've wondered on how you can use GSAP with Angular2 if anyone here have done that.

 

I loaded the TimelineMax.min.js in my main index.html-file, but having problem importing it into a component.

 

My component look like this:


import {Component} from 'angular2/core';
//import {TweenLite} from 'gsap/src/minified/TweenLite.min.js';
//import {TimelineMax} from 'gsap/src/minified/TimelineMax.min.js';
//import {TL} from 'gsap/src/minified/TimelineMax';
import {TL} from 'gsap/src/uncompressed/timelinemax';
@Component({
    selector: 'opning',
    templateUrl: './components/opning/opning.html',
    styleUrls: ['./components/opning/opning.css']
})
export class OpenCmp {
constructor() {
console.log("played");
console.log(TL);
// console.log(TweenLite);

//    var tl = new TimelineMax();
/*var logo = $("#logo");
tl.from(logo, 4, { z: 500, y: 74, visibility: "visible" });
//tl.from(logo, 2, { left: "632px" });
tl.play();
*/
}
}
 

I installed gsap with npm install gsap so it is in my projects /node_modules/ .

 

Have tried several approaches, but i can not set tl = New TimelineMax()  in that typescript class and I dont know how to load\import it. Anyone done this with angular2 ? I used this as my starting point: https://github.com/mgechev/angular2-seed

Link to comment
Share on other sites

Hi and welcome to the GreenSock forums,

 

We haven't yet used the Angular 2.0 beta. We know plenty of folks have had success with Angular and the Angular team is largely very "GSAP-friendly". It's possible some of our community members have tried 2.0 and I am sure if they have that they would love to help you. In the meantime it might be worthwhile to also post on an Angular 2 forum. 

Link to comment
Share on other sites

  • Solution

This isn't an Angular issue. The problem is related to modules. If you are trying to import every GSAP class individually, you might want to check out this thread from a couple of days ago.

http://greensock.com/forums/topic/13441-greensock-tweenlitetweenmax-exported-globals-with-commonjs-module/

 

All GSAP classes are global, so with SystemJS you could register GSAP like this...

System.set("gsap", System.newModule({
  "default": window.com.greensock
}));

And then to use GSAP, you can just import it like this...

import {Component} from 'angular2/core';
import "gsap";

I don't know how use Angular2 yet, so I wasn't sure how to access the element, but you can see it working in the console.

http://plnkr.co/edit/0IK064Hrr0vuV6OM3DpI?p=preview

  • Like 6
Link to comment
Share on other sites

Hi and welcome to the GreenSock forums,

 

We haven't yet used the Angular 2.0 beta. We know plenty of folks have had success with Angular and the Angular team is largely very "GSAP-friendly". It's possible some of our community members have tried 2.0 and I am sure if they have that they would love to help you. In the meantime it might be worthwhile to also post on an Angular 2 forum. 

 

 

This isn't an Angular issue. The problem is related to modules. If you are trying to import every GSAP class individually, you might want to check out this thread from a couple of days ago.

http://greensock.com/forums/topic/13441-greensock-tweenlitetweenmax-exported-globals-with-commonjs-module/

 

All GSAP classes are global, so with SystemJS you could register GSAP like this...

System.set("gsap", System.newModule({
  "default": window.com.greensock
}));

And then to use GSAP, you can just import it like this...

import {Component} from 'angular2/core';
import "gsap";

I don't know how use Angular2 yet, so I wasn't sure how to access the element, but you can see it working in the console.

http://plnkr.co/edit/0IK064Hrr0vuV6OM3DpI?p=preview

 

Hey Carl and thanks, and thank you OSUBlake. I tried your code, but still cant get any animations. I tried this: 

import {Component} from 'angular2/core';
import "gsap";

@Component({
    selector: 'opning',
    templateUrl: './components/opning/opning.html',
    styleUrls: ['./components/opning/opning.css']
})
export class OpenCmp {
    constructor() {
        var tl = new TimelineMax({ delay: 1 });
        var logo = $('#logo')
        tl.from(logo, 1, { x: -200, scale: 0.1 }, 0.7);
        tl.play();
        console.log('played');
    }
}

In compiler i get this error msg:

error TS2304: Cannot find name 'TimelineMax'. 

Do I have to declare tl in any other way? I have included TimelineMax.min.js and TweenLite.min.js 

 

I also dont see animation on the plunker, tried to fiddle with it with no luck too.

Link to comment
Share on other sites

After some more fiddling i made it work in Angular2.

 

I had a ts-file loading the js. files into a html index template and i removed the gsap js files from there to just inside the index.html and then it worked, thanks to OLUBLAKE's input. Thank you for the plunker, i missed the console.log's and then understood that it actually worked. Here is a modified version with visual animation: http://plnkr.co/edit/jpbljE?p=preview of a working greensock angular2 app.  :ugeek:

  • Like 3
Link to comment
Share on other sites

  • 3 weeks later...
  • 2 months later...

Have a couple questions; 

  1. has anyone been able to use any of the built in element selectors in ng2 instead of JQuery?
  2. I'm working with the ng2 beta in es6 and when the component loads the JQuery selections are not available but are available on function click calls. I'm wondering if anyone knows if this is a similar issue as the two cpu cycle rendering with ng1?
  3. is there a two cycle solution for ng2 since I'm pretty sure ng2 doesn't contain the built in apply method from ng1?

 Sorry that these questions are a little off topic but I think people that have found this thread will most likely have the same questions.

 

Update:

A better solution for JQuery selection in ng2 is to wrap your selections with ngOnInit:

    ngOnInit() {
        let obj1 = $('h1');
        obj1 = $('h1');
        console.log('obj1 : ', obj1.length);
        TweenMax.to(obj1, 0.75, {
            autoAlpha: 0,
            ease: Power4.easeOut
        });
    }
Link to comment
Share on other sites

Hi @404Assassin

 

The DOM is hidden in Angular 2 because it can run in a bunch of different environments, web workers, server, NativeScript, etc. And please note that Angular 2 is still in beta, so some things aren't finalized, but if you are trying to target a DOM element, you can bring in a reference to the ElementRef. Check out this tutorial I made on creating a custom SVG component.

 

http://greensock.com/forums/topic/13594-greensock-tweens-in-angular-2/?p=59314

  • Like 3
Link to comment
Share on other sites

  • 3 weeks later...
  • 8 months later...

my friend figured it out how to import gsap to ng2

 

This is my angular-cli:@webpack version

 

angular-cli: 1.0.0-beta.22-1

node: 6.3.1

os: win32 x64

 

 

This is how we do it:

  1.  just install gsap to project
    npm install gsap --save
    

     

  2.  point the module at import area in *.ts component (doesn't need to use import)

    const TweenMax = require('gsap').TweenMax;

     

  3.  

     play it in your *.ts component, maybe on click event handler

    var photo = document.getElementById("iconlibrary");
    TweenMax.to(photo, 1.5, {x:"+200", repeat:-1, yoyo: true});

Hope it will be usefull~

  • Like 3
Link to comment
Share on other sites

  • 3 weeks later...

Started experimenting with this again and but made a github this time with an angular 2 quickstart wich i made with the angular-cli: https://github.com/ekstremedia/eks-app

 

Working demo with gsap and bootstrap 4. Will work more on it later.

 

But in this app I need to do:

declare var ease, TimelineMax,TweenMax,Power4,Power1,Power2,Power3,Bounce, Elastic:any;

On the components where i will use gsap to make compiler happy.. and im not sure if my solution is good but im open for tips! 

Link to comment
Share on other sites

You have to do that because you don't have any definitions installed for GSAP. Install them, and the errors go away.

Thanks for the reply, but can you be more specific? Im not a pro in this, just learning. But would really want to know what you mean by installing the definitions.

Link to comment
Share on other sites

Definitions are how TypeScript understands libraries that aren't written in TypeScript. Angular2 is written in TypeScript, so you don't need definitions for it. GSAP isn't, so TypeScript needs definitions to understand the types used by GSAP.  

 

There's a whole repo for these definitions, and there's one for GSAP (although it's not an official one)...

https://github.com/DefinitelyTyped/DefinitelyTyped

 

Just search around the internet. Installing definitions is very common as pretty much everybody has to do it, so there are a lot of resources. In fact, I wrote about installing definitions here for VS Code, although it might be a little out of date...

https://greensock.com/forums/topic/13575-code-hinting-for-gsap-products/?p=56801

 

.

  • Like 4
Link to comment
Share on other sites

  • 3 months later...

I am having issues importing SplitText as it was not included in package when installed through 'npm'.

So, I pasted in to the package folder manually.

 

And I tried this in Hero component:

import { SplitText } from 'gsap/SplitText';

 

But this is giving error:

 

TypeError: __WEBPACK_IMPORTED_MODULE_1_gsap_SplitText__.SplitText is not a constructor at HeroComponent

 

I also add the variable in typings.d.ts along with other variable declaration like TweenMax, Power, ease etc. but it didn't help.

Starting fresh doesn't help as mentioned here.

 

Is anyone having issues like this.

Kindly Help!

 

Link to comment
Share on other sites

Did you make sure you took the SplitText.js file from the "commonjs-flat" folder? You didn't use the one from /uncompressed/ or /minified/, right? 

 

I'm not familiar with webpack or what exactly that error means - might be worth asking the Webpack folks. 

Link to comment
Share on other sites

3 hours ago, GreenSock said:

Did you make sure you took the SplitText.js file from the "commonjs-flat" folder? You didn't use the one from /uncompressed/ or /minified/, right? 

 

I'm not familiar with webpack or what exactly that error means - might be worth asking the Webpack folks. 

Yes, I used file from "commonjs-flat" folder. I used the uncompressed and minified files and put them in respective folders.

 

Following works, but now the text in the tag disappears (will figure that out...hopefully)  

import from 'gsap/SplitText';

 

Thanks!

Link to comment
Share on other sites

You don't need all those folders, just so you know. It sounds like all you need is the commonjs-flat folder. 

 

That import statement doesn't look valid (or at least it appears odd) because you're not creating a reference at all. 

 

Perhaps OSUblake will chime in with some suggestions, as I know he's more familiar with these build systems and Angular. Sorry, I wish I had a better answer for you. 

 

And you said the text in the tag disappears? That's tough to troubleshoot blind. If you need any help with that, please create a reduced test case in codepen or something like that so that we can poke around and see what's going on. 

Link to comment
Share on other sites

I just saw that error on Plunker using SystemJS, so it's not isolated to webpack. Unfortunately, it crashed before I could save it.

 

For some reason, it's not being exported correctly. It should be like this...

import SplitText from 'gsap/SplitText';

var split = new SplitText(myElement);

 

When I saw the compiled code, it was adding default to it. So it looked like this.

var SplitText_1 = require('gsap/SplitText')

var split = new SplitText_1.default(myElement)

 

I added braces just to see what would happen, and there was a correct looking name, but that's when it crashed.

import { SplitText } from 'gsap/SplitText';

var split = new SplitText(myElement);


// Compiled to...
var SplitText_1 = require('gsap/SplitText')

var split = new SplitText_1.SplitText(myElement)

 

I remember a similar issue for somebody using browserify, but I can't find it. If I remember correctly, it was reversed from this. The person was use braces for their imports when they shouldn't have, which was adding the default name to their imports. 

 

Not sure what's up. It seems like SplitText has a different scope.

  • Like 1
Link to comment
Share on other sites

Use the following syntax to import plugins/utilities with TypeScript.

import * as SplitText from "gsap/SplitText";

// Or
import SplitText = require("gsap/SplitText");

 

This post explains why.

 

And the reason importing like this didn't cause an error...

import "gsap/SplitText";

 

... is because GSAP makes everything global, and you didn't name the import, so you were using the global, which would be like this.

var split = new window.SplitText(myElement);

 

 

  • Like 2
Link to comment
Share on other sites

  • 5 weeks later...

Thanks a lot for your help on import issue!

 

I figured out the issue with disappearing text. It was happening as I was Splitting the text on ngOnInit() method but doing it on ngAfterViewInit() solved it.

 

Now, I am really stuck in finding the problem with animations on scrolling.

 

This is the link of the site that I am working on. I am using ScrollMagic for animating images and text with TimeLineMax.

 

In Google Chrome the scrolling is very slow; the FPS is around 25-30 on desktop and on mobile scrolling is pretty much dead.

However, in Firefox there is no issue in scrolling but animations doesn't happen smoothly and it shows "will-change memory consumption" warning in console. I have included the snapshot for it.

 

Can you please help/guide me on how to resolve this? 

Screen Shot 2017-06-19 at 4.12.50 PM.png

Link to comment
Share on other sites

Hi @jnalvit

 

That's a pretty impressive looking site. Very nice!

 

Angular has a lot of issues when it comes to animations. :angry:

 

One performance gotcha in Angular is just running an animation. GSAP uses requestAnimationFrame, which is a browser event that automatically runs inside the Angular Zone. Once handled, Angular will perform change detection, calling ngAfterViewChecked, which may happen up to 60 times per second.

 

I don't know if this will improve anything, but if you're not animating a property on your component, you should set that animation up to run outside Angular.

constructor(private ngZone: NgZone) {}

ngOnInit() {
  this.ngZone.runOutsideAngular(() => {
    // setup your animations to run outside Angular
  });
}

 

But I think most of your performance problems are related to your CSS. This is very bad.

img {
  will-change: transform!important;
}

 

That's causing Firefox to run out of memory because you're creating too many rendering layers. Once you go over that limit, Firefox cancels all the will-change optimizations.

 

The only time I would recommend using will-change is for certain scaling animations. Check out this thread.

Dealing with will-change in Chrome has been issue for the past year...

https://greensock.com/will-change

 

If you want to move something onto it's own rendering layer, you can set force3D to true.

// You only have to call force3D on an element once
TweenLite.set(foo, {
  force3D: true
})

 

Another problem I see in your CSS is that you have transitions set to all. This is going to cause GSAP and CSS to fight over the animation. You need to be specific about which properties you want transitions on, and make sure you're not animating the same property with GSAP.

.wrapper {
  transition: all .35s cubic-bezier(.215,.61,.355,1);
}

 

 

  • Like 1
Link to comment
Share on other sites

I'm wondering whether the new release of Angular, with it's improved hooks for animation, removes some of the historical issues with GSAP?  I'm unfortunately only getting started so I can't tell if it helps or not!

 

https://www.yearofmoo.com/2017/06/new-wave-of-animation-features.html

 

It seems you can set your own animations to elements - if GSAP could be made to handle those, it could stop the 'fighting' between the two frameworks I've heard mentioned...

Link to comment
Share on other sites

Hi @OSUblake,

Thanks a lot for providing the awesome feedback. I am glad you're here for help.

 

One thing that I noticed is, when the browser window is resized to smallest size (~400px) or when debugging with mobile preview on Chrome, all the animations and scrolling runs very smoothly.

 

Animations has improved on desktop. I believe I am still doing it wrong somewhere. :|

 

I have updated the CSS and using NgZone for running animation code. Below is the code for homepage animation. I am doing it in a similar way for all pages.

 

// A Node is the list-item containing Image + Description for each product on the page 
ngAfterViewInit() {

  this.nodes = this.eleRef.nativeElement.querySelector('.category-list').querySelectorAll('li');

  this.nodes.forEach(node => {

    let nodeF = node.querySelector('.filler'),
        nodeT = node.querySelector('.text'),
        tl = new TimelineMax();

    if (nodeF != null && nodeT != null) {

      this.ngZone.runOutsideAngular(() => {
        
        this.scene = new ScrollMagic.Scene({
          triggerElement: node,
          reverse: false
        })
        .setTween(tl
          .fromTo(nodeF, 1, 
                  {force3D: true, x: 0, ease: Power0.easeInOut}, 
                  {force3D: true,  xPercent: '101' }, "trigger")
          .fromTo(nodeT, 0.5, 
                  {force3D: true, opacity: -1, x: -20 }, 
                  {force3D: true,  opacity: 1, x: 0 }, "-=0.8", "trigger"))
        .addTo(this.controller);
      });
      
    }
  });
}

 

Now, I am using "will-change" only for the <span class="filler"> tag that rolls over the image to give a reveal effect. 

 

Thank again for helping me so far :)

@glinkot Thank you for your suggestion. I will definitely look into it :)

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