<my-app></my-app>
// app.js

const { Component, VERSION } = ng.core;

@Component({
  selector: 'my-app',
  template: `
   <h1>{{title}} </h1>
    TODO: Define your Angular ${VERSION.major} component.
  `
})
class AppComponent implements OnInit {

  bank_card;
  layoutRef: LayoutManager;
  pages: Pages;

  constructor() { }

  ngOnInit() {
    // console.log(zim);

    this.start();
  }

  /**
 * Launch the app.
 */
  start() {

    const that = this; // a reference to the parent class

    const scaling = 'full'; // makes stage the window size but does not scale content
    const frame = new Frame(scaling); // see docs for more options and info
    frame.on('ready', function() {
      zog('ready from ZIM Frame');

      const stage = frame.stage; // the HTML5 Canvas element
      const stageW = frame.width;
      const stageH = frame.height;
      frame.color = frame.white;
      const firstPage = new Container(800, 600); // The main page of the Zapp
      const secondPage = new Container(800, 600); // The 'Thank you' page
      that.pages = new Pages({
        pages: [
           // imagine pages to the left, right, up and down
           // swipe:["to page on left", "to page on right", etc.s]
           {page: firstPage, swipe: [null, null, secondPage]},
           {page: secondPage, swipe: [null, null, null, firstPage]},
        ],
        transition: 'slide',
        speed: 1000 // slower than usual for demonstration
     }).addTo(stage); // ZIM Page; see docs for more options and info

     // * This function creates all the elements and interactions that appear in the Zapp.
      that.makeZapp(frame, stage, stageH, stageW, firstPage, secondPage);

     // * This function creates the layout manager and its settings
     that.layout(frame, stage, firstPage, secondPage);

    }); // end of ready
  }

  /**
 * Main controller for the Zapp.
 */
  makeZapp(frame: Frame, stage: Stage | StageGL, stageH: number, stageW: number, container?: Container, secondPage?: Container) {

    const that = this; // reference to the parent class
    frame.loadAssets('https://i.imgur.com/kshwcNf.png'); // loads the image of the debit card

    const button = this.makeConfirmButton();

    this.makeSecondPage(secondPage);

    /* Text Area */

    const receipt = this.makeReceipt(container);
    const pinInstruction = new Label({
      text: `Enter your pin and press enter`,
      size: 20,
      font: 'helvetica',
      color: '#999999',
      // fontOptions: 'bold'
    });
    const pinArea = this.makePinArea(button, stage, container, pinInstruction);
    const pulldown = this.makePullDown(pinArea, pinInstruction, receipt, container, stage);
    const textArea = this.makeLandingArea(receipt, pulldown, container, stage);

    // const manager = new GridManager();
    // manager.add(new Grid());

    stage.update();

    frame.on('complete', function() {
      zog('complete');

      const card = frame.asset('https://i.imgur.com/kshwcNf.png'); // logo is a Bitmap
      that.bank_card = new Bitmap(card, 50, 50).center(container).sca(0.10).mov(135, -275);
      stage.update();
    });

  }


  /**
 * Creates the text that appears in the second page
 * @param secondPage the second page of the Zapp
 */
  makeSecondPage(secondPage: Container) {
    
      const that = this;
    const button = new Button(750, 50, 'END', 'red', '#808080');
    button.on('click', function() { // on() is like addEventListener()
      // or relative URL, target is available too
      that.start();
    });

      const text = new Label({
        text: `Take your cash`,
        size: 100,
        font: 'helvetica',
        color: '#999999',
        fontOptions: 'bold',
        // align: 'center'
      });

      text.center(secondPage);
      button.center(secondPage).mov(0, 150);

  }

  /**
 * Creates A Toggle Button.
 * @param container the first page
 */
  makeReceipt(container?: Container) {
    const receipt = new Toggle({
      label: 'No',
      width: 200,
      height: 45,
      shadowBlur: -1,
      backgroundColor: '#296063',
      indicatorType: 'square'
    }).change(function (e) {
      zog(e.target.toggled);
      const state = e.target.toggled;
      if (state) {
        receipt.label.text = 'Yes';
      } else {
        receipt.label.text = 'No';
      }
    });

    const instruction = new Label({
      text: `Do you want a receipt?`,
      size: 18,
      font: 'helvetica',
      color: '#999999',
      // fontOptions: 'bold'
    });

    instruction.center(container).mov(165, -40);


    return receipt;
  }

  /**
 * Creates the PIN input area.
 * @param button a ZIM button; this action completes a transaction
 * @param stage a createjs stage
 * @param page a ZIM container; the main page of the app
 * @param pinInstruction the instruction for inputing a PIN
 */
  makePinArea(button: Button, stage: Stage, page: Container, pinInstruction: Label) {
    const pinArea = new TextArea({
      width: 750,
      height: 90,
      corner: 10,
      backgroundColor: '#E5E5E5',
      borderWidth: 0,
      size: 50,
      padding: 20,
      password: true,
      placeholder: '__   __   __   __'
    });

    pinArea.on('change', function() {
      // label.text = textArea.text;
      button.center(page).mov(0, 230);
      button.animate ({props:{alpha: 0, scale: 0}, time: 300, from: true});
      setTimeout(() => {
        button.text = 'CONTINUE';
      }, 1000);
      stage.update();
    });
    pinArea.on('input', function() {
      // label.text = textArea.text;
      page.removeChild(pinInstruction);
      stage.update();
    });



    pinArea.tag.style.textAlign = 'center'; // etc.

    return pinArea;
  }

  /**
 * Create the elements that show when the app opens for the first time.
 * @param receipt a ZIM Toggle; for choosing to get a receipt
 * @param pulldown the list of account types
 * @param container a ZIM container; the main page of the app
 * @param stage a createjs stage
 */
  makeLandingArea(receipt: Toggle, pulldown: List, container: Container, stage: Stage) {
    let width = 750;
    let height = 90;
    let size = 50;
    const that = this;

    const greeting = new Label({
      text: 'Hello, John',
      size: 45,
      font: 'helvetica',
      color: '#666666',
      fontOptions: 'bold'
    });
    const info = new Label({
      text: `
      Account Number`,
      size: 15,
      font: 'helvetica',
      color: '#999999',
      // fontOptions: 'light'
    });
    const accNumber = new Label({
      text: `0078698675`,
      size: 25,
      font: 'helvetica',
      color: '#999999',
      fontOptions: 'bold'
    });

    greeting.center(container).mov(-250, -270);
    info.center(container).mov(-325, -230);
    accNumber.center(container).mov(-300, -200);

    const textArea = new TextArea({
      width: 750,
      height: 250,
      corner: 10,
      backgroundColor: '#D2F1FC',
      borderWidth: 0,
      size: 200,
      padding: 15,
      spellCheck: false,
      placeholder: '$ '
    });

    const instruction = new Label({
      text: `Enter the amount you want and press the 'tab' button`,
      size: 20,
      font: 'helvetica',
      color: '#999999',
      fontOptions: 'normal'
    });



    textArea.on('change', function() {
      // label.text = textArea.text;
      pulldown.center(container).mov(-225, 49);
      receipt.center(container).mov(200);
      pulldown.animate({props: {alpha: 0, scale: 0}, time: 700, from: true});
      receipt.animate({props: {alpha: 0, scale: 0}, time: 700, from: true});
      // zog('changed');
      // zog(container.children, container.getChildIndex(pulldown));
      textArea.animate({
        props: {heightOnly: height},
        time: 500

      });
      // zog(textArea.tag);
      textArea.tag.style.height = '70px'; // etc.
      textArea.tag.style.top = '-6px'; // etc.
      textArea.tag.style.fontSize = '61px'; // etc.
      // textArea.height = 90; // etc.
      // textArea.width = 750; // etc.
      container.removeChild(instruction);
      
      stage.update();
    });

    textArea.on('input', function() {
      container.removeChild(instruction);
      stage.update();
    });

     // to set scrollBars on TextArea use CSS on the TextArea tag property:
     textArea.tag.style.fontFamily = 'helvetica'; // etc.
     textArea.tag.style.fontWeight = 'bold'; // etc.
     textArea.tag.style.color = '#426063'; // etc.

     textArea.center(container).mov(0, -30);
     instruction.center(container).mov(0, -130);


     return textArea;
  }


  /**
 * Creates a drop down list of bank account types.
 * @param pinArea the input element for typing a secret PIN
 * @param pinInstruction the instruction for inputing a PIN
 * @param receipt a ZIM Toggle; for choosing to get a receipt
 * @param page a ZIM container; the main page of the app
 * @param stage a createjs stage
 */
  makePullDown(pinArea: TextArea, pinInstruction: Label, receipt: Toggle, page: Container, stage: Stage) {
    const list = [{'ACCOUNT TYPE': ['Savings', 'Current']}];

    function getList (account: []) {
      return account = list[0];
    }

     const accounts = new List({
      width: 300,
      list: list.find(getList),
      viewNum: 3, // this number will change the size of the list elements (default is 5)
      pulldown: true,
      currentSelected: true,
      selectedColor: '#29ABE2',
      rollBackgroundColor: '#29ABE2',
      backgroundColor: '#296063',
      // corner: 25,
      // selectedIndex: 1,
      // excludeCustomTap: true,
      // close: true,
      });

      accounts.change(function (e) {
        // zog(accounts.selected.text);
        let text = 'selected account';
        text = accounts.selected.text;
        accounts.first().text = text;
        pinArea.center(page).mov(0, 130);
        pinInstruction.center(page).mov(0, 110);
        pinArea.animate({props: {alpha: 0}, time: 700, from: true});
        zog(page.children);
        page.swapChildren(accounts, pinArea);
        page.swapChildren(accounts, receipt);
        stage.update();
      });

      return accounts;
  }


  /**
 * creates the confirm button and its interactions.
 */
  makeConfirmButton() {
    const that = this;
    const button = new Button(750, 50, 'PIN OK', '#17C127', '#808080');
    button.on('click', function() { // on() is like addEventListener()
      // or relative URL, target is available too
      that.pages.go(1, 'left', 'slide', 500);
    });

    // button.pos(100, 450);

    return button;
    // will position and scale the code in the resize function at bottom
  }

  /**
 * Controls how the interface resizes on various devices.
 * @param frame the input element for typing a secret PIN
 * @param stage a createjs stage
 * @param firstPage a ZIM container; the main page of the app
 * @param secondPage a ZIM container; the main page of the app
 */
  layout(frame: Frame, stage: Stage | StageGL, firstPage?: Container, secondPage?: Container) {
    // these would be containers with your content
    // make sure that bounds are set on containers
    // you may want to hard code bounds for clarity
    // const header = new Rectangle(800, 600, 'blue');
    // const content = new Rectangle(1200, 200, 'green');
    // const footer = new Rectangle(1200, 200, 'blue');
    /// stage.addChild(header);

    // make the Layout - more useful for FULL scale mode
    const layout = new Layout({
       holder: stage,
       regions: [
          {object: firstPage, marginTop: 10, maxHeight: 90, width: 10, valign: 'bottom'},
       ],
       lastMargin: 5
    });
    const secondLayout = new Layout({
       holder: stage,
       regions: [
          {object: secondPage, marginTop: 10, maxHeight: 90, width: 10, valign: 'bottom'},
       ],
       lastMargin: 5
    });

    // add to LayoutManager to resize or dispose all layouts together
    // disposing only removes keyboard events to show boundaries
    const manager = new LayoutManager();
    manager.add(layout);
    manager.add(secondLayout);

    this.layoutRef = manager;

    frame.on('resize', function() {
       manager.resize();
       stage.update();
    });

    stage.update();
  }

}


// main.js
const { BrowserModule } = ng.platformBrowser;
const { NgModule } = ng.core;
const { CommonModule } = ng.common;

@NgModule({
  imports: [
    BrowserModule,
    CommonModule,
  ],
  declarations: [AppComponent],
  bootstrap: [AppComponent],
  providers: []
})
class AppModule {}

const { platformBrowserDynamic } = ng.platformBrowserDynamic; 

platformBrowserDynamic()
  .bootstrapModule(AppModule)
  .catch(err => console.error(err));

console.log('hola');
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.2.1/rxjs.umd.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/core-js/2.5.7/core.js
  3. https://unpkg.com/@angular/core@9.1.1/bundles/core.umd.js
  4. https://cdnjs.cloudflare.com/ajax/libs/zone.js/0.8.26/zone.min.js
  5. https://unpkg.com/@angular/common@9.1.1/bundles/common.umd.js
  6. https://unpkg.com/@angular/compiler@9.1.1/bundles/compiler.umd.js
  7. https://unpkg.com/@angular/platform-browser@9.1.1/bundles/platform-browser.umd.js
  8. https://unpkg.com/@angular/platform-browser-dynamic@9.1.1/bundles/platform-browser-dynamic.umd.js
  9. https://zimjs.org/cdn/1.3.0/createjs.js
  10. https://zimjs.org/cdn/10.9.0/zim.js