user7210105
user7210105

Reputation:

Angular 2 and Scrollmagic

I am trying to implement scrollmagic into my Angular 2 App but I have been unsuccessful up to now. I have looked at a lot of tutorials but they haven't been able to help me. I am looking for someone who can plainly explain to me how i can get Angular 2 to work with scrollmagic. I have tried this:

I added this in my component:

import { TweenLite, TimelineMax, TweenMax } from "gsap";
import { Component, NgZone, AfterViewInit} from '@angular/core';
declare let ScrollMagic: any;

@Component({
 selector: "info-strip",
 templateUrl: "./info-strip.component.html",
 styleUrls: ["./info-strip.component.scss"],
 animations: []
})

export class InfoStripComponent {

ctrl = new ScrollMagic.Controller();
constructor(private zone: NgZone) {}
ngAfterViewInit() {
    new ScrollMagic.Scene({
        offset: 200,
        duration: 50
    })
        .setPin("#info_strip")
        .addTo(this.ctrl);
}}

`

If I write my controller and scene to the log I can see that they are valid ScrollMagic items, however my code does not seem to do anything and It does not show any errors. I want to simply create a sticky header. Please anyone help to get scrollmagic to work with angular 2

Upvotes: 1

Views: 3202

Answers (1)

Richard Matsen
Richard Matsen

Reputation: 23503

I built a test system with Angular CLI + ScrollMagic, and found one issue.

ng version info

Angular CLI: 1.5.2
Node: 6.10.3
OS: win32 x64
Angular: 5.1.2
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

@angular/cli: 1.5.2
@angular-devkit/build-optimizer: 0.0.36
@angular-devkit/core: 0.0.22
@angular-devkit/schematics: 0.0.42
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.8.2
@schematics/angular: 0.1.11
@schematics/schematics: 0.0.11
typescript: 2.4.2
webpack: 3.8.1


Steps to build

  • ng new scrollmagictest
  • yarn install
  • yarn add scrollmagic
  • yarn add gsap
  • yarn add --dev @types/gsap


Test component

Note, my ScrollMagic code may not be optimal.

app.component.ts

import { Component, AfterViewInit } from '@angular/core';
import { TweenMax, TimelineMax } from 'gsap';
import * as ScrollMagic from 'ScrollMagic';
import 'ScrollMagic/scrollmagic/minified/plugins/debug.addIndicators.min.js';
// import 'ScrollMagic/scrollmagic/minified/plugins/animation.gsap.min.js';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewInit {

  ctrl = new ScrollMagic.Controller();

  ngAfterViewInit() {
    new ScrollMagic.Scene({
      triggerElement: '.menu-trigger',
      duration: window.screen.height,
      triggerHook: 0
    })
    .setPin('#menu', { pushFollowers: false })
    .addTo(this.ctrl);
  }

}

app.component.html

<nav class="nav">
  <h1 class="header">Header</h1>
  <div class="menu-trigger">
    <ul id="menu">
      <li><a href="">ScrollMagic</a></li>
      <li><a href="">Will</a></li>
      <li><a href="">Pin</a></li>
      <li><a href="">This</a></li>
      <li><a href="">Menu</a></li>
      <li><a href="">Until</a></li>
      <li><a href="">Second</a></li>
      <li><a href="">Slide</a></li>
    </ul>
  </div>
</nav>

<section class="slide slide01">
  <h1>Content</h1>
</section>

<section class="slide slide02">
  <h1>More Content</h1>
</section>

app.component.css

body { font-family: Helvetica, Arial, sans-serif; color: rgb(70, 67, 67); }

html, body { margin: 0; height: 100%; }

.nav {
  color: rgb(255, 255, 255);
}

.nav .header {
  font-size: xx-large;
  padding: 20px 10px 20px 10px;
  color: rgb(70, 67, 67);
  background-color: rgb(212, 215, 248);
}

#menu {
  color: rgb(255, 255, 255);
  background-color: rgb(0, 0, 0);
  padding-left: 0;
  list-style: none;
  display: flex;
  width: 100%;
  justify-content: flex-start;
  margin-bottom: 0;
  margin-top: 0;
  border-bottom: 1px solid rgb(203, 189, 189);
}

#menu li {
  padding: 10px;
}

#menu li a {
  text-decoration: none;
  color: rgb(255, 255, 255);
  font-weight: bold;
}

h1, p {
  margin: 0; padding: 0;
}

.slide {
  display: flex;
  justify-content: center;
  align-items: center;
  color: #efefef;
  height: 1200px;
}

.slide01 { background-color: rgb(168, 190, 246); }
.slide02 { background-color: rgb(4, 63, 164); }

The issue I found

Note the commented-out line

// import 'ScrollMagic/scrollmagic/minified/plugins/animation.gsap.min.js';

If we try to include this plugin, webpack has a problem with connecting it to gsap.

After ng build,

ERROR in ./node_modules/ScrollMagic/scrollmagic/minified/plugins/animation.gsap.min.js Module not found: Error: Can't resolve 'TimelineMax' in ...


Resolving the problem

This post tsconfig paths not respected of 4 Nov 2017 gives a resolution, but it involves patching out node_modules/@ngtools/webpack/src/paths-plugin.js.

From the post,

FYI, for anyone else needing the pre-1.2.6 behavior, the solution I landed on is using the latest Angular/CLI/etc. and just overwriting node_modules/@ngtools/webpack/src/paths-plugin.js with https://github.com/buu700/ngtools-webpack-tmp/blob/master/src/paths-plugin.js. It's not very elegant, and could be broken by a future release, but gets the job done for now without blocking updating to Angular 5.



Alternative resolution

If you don't fancy hacking the npm-installed @ngtools/webpack/src/paths-plugin.js, here's an alternative.

Part of the build error message is

path\to\myProject\src\TweenMax.js doesn't exist

so we can (crudely) fix that by copying the gasp source files to the ./src folder.

See How to hook 3rd party scripts before serving / building an app with angular-cli, Cory Rylan shows how to use npm scripts in package.json to hook into the build process.

  • add two new npm scripts to package.json, leaving the build script as-is so it can be run as normal.
  • run the command npm run startbuild whenever you do a global npm install, or other command that might change the gasp files.
  • note, I installed copyfiles globally, for convenience.

package.json

{
  "name": "myProject",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    ...
    "startbuild": "npm run prebuild && ng build",
    "prebuild": "copyfiles -f node_modules/gsap/src/uncompressed/*.js src",
    "build": "ng build",
    ...
  },

Upvotes: 3

Related Questions