Roman Oxman
Roman Oxman

Reputation: 397

Angular 4 animations not working with Safari iOS 9.3

I'm currently testing my app in all the possible browsers and I got to see that the angular animations don't behave as expected in Safari iOS 9.3. After hours and hours trying to solve it I come asking for a help in hand. Thanks in advance.

My code reads:

package.json

"dependencies": {
    "@angular/animations": "^4.3.2",
    "@angular/cdk": "^2.0.0-beta.8",
    "@angular/common": "^4.0.0",
    "@angular/compiler": "^4.0.0",
    "@angular/core": "^4.0.0",
    "@angular/forms": "^4.0.0",
    "@angular/http": "^4.0.0",
    "@angular/material": "^2.0.0-beta.8",
    "@angular/platform-browser": "^4.0.0",
    "@angular/platform-browser-dynamic": "^4.0.0",
    "@angular/router": "^4.0.0",
    "@ngx-meta/core": "^0.4.0-rc.2",
    "@ngx-translate/core": "^7.1.0",
    "@ngx-translate/http-loader": "^1.0.1",
    "angular2-moment": "^1.6.0",
    "core-js": "^2.4.1",
    "express": "^4.15.4",
    "lodash": "^4.17.4",
    "ng2-pdf-viewer": "^1.1.1",
    "ng2-translate": "^5.0.0",
    "rxjs": "^5.4.1",
    "web-animations-js": "^2.3.1",
    "zone.js": "^0.8.14"
},

landing.component.ts

import { Component, HostBinding, ChangeDetectionStrategy } from '@angular/core';
import { stateTransition } from '../routing.animations';

@Component({
  selector: 'cp-landing',
  templateUrl: './landing.component.html',
  styleUrls: ['./landing.component.css'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  animations: [ stateTransition() ]
})
export class LandingComponent {
  @HostBinding('@stateTransition') '';
}

routing.animations.ts

import { trigger, state, animate, style, transition } from '@angular/animations';

export function stateTransition() {
  return trigger('stateTransition', [
    state('void', style({
      transform: 'translateY(50%)',
      opacity: 0
    })),
    state('*', style({
      transform: 'translateY(0%)',
      opacity: 1
    })),
    // enter animation
    transition('void => *', animate('.5s 500ms')),
    // exit animation
    transition('* => void', animate('.5s'))
  ]);
}

I tried coming up with a Fiddle but I'm not being able to reproduce the error.

Upvotes: 8

Views: 7726

Answers (5)

Kamran Taghaddos
Kamran Taghaddos

Reputation: 594

@diopside answer is perfect, but I think the more precise answer can be this:

After many investigations, I realized that this issue happens usually for users with an iPhone 6 as they are stuck with iOS 12.

You have 2 ways to solve this issue:

1- Add "web-animation-js" to your "ployfills.ts" file that is in the "src" folder as below.

First, run this command: npm i -D web-animations-js

Second, add these lines of codes to the angular.json file.

{
...
"projects:" {
  ...
  "architect": {
    ....
    "build": {
      ...
      "scripts": [
              {
                "input": "node_modules/web-animations-js/web-animations.min.js",
                "inject": false,
                "bundleName": "web-animations-js"
              }
            ],

Third, add these lines of codes to the ployfills.ts file.

if (!('animate' in document.documentElement) || (navigator && /iPhone OS (8|9|10|11|12|13)_/.test(navigator.userAgent))) {
  const script = document.createElement('script');
  script.src = 'web-animations-js.js';
  document.head.appendChild(script);
}

2- Disable BrowserAnimationsModule for iOS as below.

Add these lines of codes to app.module.ts.

const disableAnimations =
  !('animate' in document.documentElement)
  || (navigator && /iPhone OS (8|9|10|11|12|13)_/.test(navigator.userAgent));


@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    BrowserAnimationsModule.withConfig({ disableAnimations }),

Upvotes: 0

E. Gregious
E. Gregious

Reputation: 81

The source of this issue is ngx-pdf-viewer depending on an old 1.x version of pdf.js which incorrectly polyfills web-animations on all versions of iOS (https://github.com/mozilla/pdf.js/blob/6521d2fd941f26a1b7ae9b97f71842e49f5ff241/src/shared/compatibility.js#L571-L575). This was done to fix a bug in older iOS versions but causes newer iOS versions that have a working requestAnimationFrame to break.

Upvotes: 4

Roman Oxman
Roman Oxman

Reputation: 397

Finally the error was quite too specific, the ngx-pdf-viewer library was causing this error at the moment of loading the component.

What I did to solve it was to compile the component dynamically only when the user is in desktop and I took another approach for mobile.

My code:

const template = '<pdf-viewer [src]="src"' +
                 '            [show-all]="true"' +
                 '            [zoom]="2">' +
                 '</pdf-viewer>';

const tmpCmp = Component({template: template})(class {});
const tmpModule = NgModule({
  declarations: [tmpCmp, PdfViewerComponent],
  imports: [CommonModule]}
)(class {});

this._compiler.compileModuleAndAllComponentsAsync(tmpModule)
.then((factories) => {
  const f = factories.componentFactories[0];
  const cmpRef = f.create(this._injector, [], null, this._m);
  cmpRef.instance.src = this.data.src;
  this.pdfViewerContainer.insert(cmpRef.hostView);
});

Upvotes: 2

diopside
diopside

Reputation: 3062

The web animations API requires a polyfill on Safari, I believe. And its not enabled by default. You'll just need to install the polyfill and then add a line or two to your polyfills.ts file in your app's /src folder.

See here: How to add Web Animations API polyfill to an Angular 2 project created with Angular CLI

(copying the best answer below)

Adding the polyfill with the newer, Webpack version of Angular CLI is easier:

Install with

npm install web-animations-js --save

Add to polyfills.ts:

 require('web-animations-js/web-animations.min');

It also worked if I do

 import 'web-animations-js/web-animations.min';

Upvotes: 17

Pardeep Jain
Pardeep Jain

Reputation: 86730

Try by downgrading your package with this version

"@angular/animations": "4.0.2"

Upvotes: 0

Related Questions