nativescript-angular
nativescript-angular copied to clipboard
Animation freeze then router change with clearHistory: true
I have NativeScript Angular application And have Animation Endless rotation of points in a circle
import { AfterViewInit, Component, ElementRef, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { Label } from '@nativescript/core/ui/label';
import { AbsoluteLayout } from '@nativescript/core/ui/layouts/absolute-layout';
import { GridLayout } from '@nativescript/core/ui/layouts/grid-layout';
import * as application from 'tns-core-modules/application';
import { Color } from 'tns-core-modules/color';
import { Page } from 'tns-core-modules/ui/page';
import { DeviceService, FooterService, LoggerService } from '../../services';
import { AnimationDefinition } from '@nativescript/core/ui/animation';
import * as animationModule from '@nativescript/core/ui/animation';
import { RouterExtensions } from 'nativescript-angular/router';
@Component({
selector: 'app-body-wrapper',
templateUrl: './body-wrapper.component.html',
styleUrls: ['./body-wrapper.component.scss']
})
export class BodyWrapperComponent implements OnInit, OnDestroy, AfterViewInit {
public static circleStep: number = 200;
public static circleStartRadius: number = 640;
public static circleSizes: number[] = [32, 22, 12];
public static circleColors: string[] = ['#fb9c00', '#003aa1', '#ffffff'];
@Input('pageTitle') public readonly pageTitle: string;
@Input('footerStatus') public readonly footerStatus: boolean;
@Input('animation') public readonly animation: boolean;
@ViewChild('mainWrapper', { static: true }) public readonly mainWrapper: ElementRef;
@ViewChild('animateLayout', { static: true }) public readonly animateLayout: ElementRef;
private _pageWrapper: AbsoluteLayout;
private _allAnimations: any = {};
private _allInterface: Label[] = [];
constructor(
private readonly _page: Page,
private readonly _deviceService: DeviceService,
private readonly _footerService: FooterService,
private readonly _loggerService: LoggerService,
private readonly _router: RouterExtensions
) {
// this._page.actionBarHidden = true;
if (!this._deviceService.device.isIOS) {
const window: any = application.android.startActivity.getWindow();
window.setStatusBarColor(new Color('#f88600').android);
}
if (this._deviceService.device.deviceType !== 'Tablet') {
BodyWrapperComponent.circleStep = 100;
BodyWrapperComponent.circleStartRadius = 320;
BodyWrapperComponent.circleSizes = [16, 11, 6];
}
}
public ngOnDestroy(): void {
if (this._allAnimations) {
for (const key in this._allAnimations) {
for (const key2 in this._allAnimations[key]) {
if ((this._allAnimations[key][key2] as animationModule.Animation).isPlaying)
this._allAnimations[key][key2].cancel();
this._allAnimations[key][key2] = null;
}
}
}
if (this._pageWrapper) {
for (let i: number = 0; i < this._pageWrapper.getChildrenCount(); i++) {
this._pageWrapper.removeChild(this._pageWrapper.getChildAt(i));
}
}
for (let item of this._allInterface) {
item = null;
}
}
public ngAfterViewInit(): void {
if (this.animation) {
setTimeout(() => {
this._pageWrapper = this.animateLayout.nativeElement;
for (let i: number = 0; i < 4; i++) {
this._createWrapper(i);
}
}, 1000)
}
}
private _randomIntFromInterval(min: number, max: number): number {
return Math.floor(Math.random() * (max - min + 1) + min);
}
private _createWrapper(index: number): void {
// console.log('fire->call', index);
let height: number = (this.mainWrapper.nativeElement as GridLayout).getMeasuredHeight() / this._deviceService.device.screen.mainScreen.scale;
if (height === 0) {
height = this._deviceService.device.screen.mainScreen.heightDIPs
}
let offset: number = 0;
if (this._deviceService.device.isIOS) {
offset = application.ios.window.safeAreaInsets.top;
}
const section: Label = new Label();
section.borderColor = '#003aa1';
section.borderWidth = 1;
section.width = BodyWrapperComponent.circleStep * (index + 1) + BodyWrapperComponent.circleStartRadius;
section.height = BodyWrapperComponent.circleStep * (index + 1) + BodyWrapperComponent.circleStartRadius;
section.borderRadius = BodyWrapperComponent.circleStep * (index + 1) + BodyWrapperComponent.circleStartRadius;
section.top = height / 2 - section.height / 2 - offset;
section.left = this._deviceService.device.screen.mainScreen.widthDIPs / 2 - section.width / 2;
this._pageWrapper.addChild(section);
this._allInterface.push(section);
for (let i: number = 0; i < 3; i++) {
this._createCircle(i, index);
}
}
private _createCircle(circleIndex: number, wrapperIndex: number): void {
let offset: number = 0;
if (this._deviceService.device.isIOS) {
offset = application.ios.window.safeAreaInsets.top;
}
let height: number = (this.mainWrapper.nativeElement as GridLayout).getMeasuredHeight() / this._deviceService.device.screen.mainScreen.scale;
if (height === 0) {
height = this._deviceService.device.screen.mainScreen.heightDIPs
}
const angle: number = this._randomIntFromInterval(0, 360);
const radius: number = (BodyWrapperComponent.circleStep * (wrapperIndex + 1) + BodyWrapperComponent.circleStartRadius) / 2;
const circlePosition: { x: number; y: number } = this._getPosition(radius, angle);
const startPosition: { x: number; y: number } = {
x: this._deviceService.device.screen.mainScreen.widthDIPs / 2,
y: height / 2 - offset
};
const circleSize: number = BodyWrapperComponent.circleSizes[circleIndex];
const circle: Label = new Label();
circle.width = circleSize;
circle.height = circleSize;
circle.borderRadius = circleSize;
circle.backgroundColor = BodyWrapperComponent.circleColors[circleIndex];
circle.translateX = startPosition.x + circlePosition.x - circleSize / 2;
circle.translateY = startPosition.y + circlePosition.y - circleSize / 2;
circle.opacity = 0;
this._pageWrapper.addChild(circle);
this._animateCircle(circle, angle, circleIndex, wrapperIndex, this._randomIntFromInterval(10, 200));
this._allInterface.push(circle);
}
private _getPosition(radius: number, angle: number): { x: number; y: number } {
return {
x: radius * Math.cos((angle * Math.PI) / 180),
y: radius * Math.sin((angle * Math.PI) / 180)
};
}
private _animateCircle(circle: Label, angle: number, circleIndex: number, wrapperIndex: number, duration: number): void {
let newAngle: number = angle + 0.5;
if (newAngle > 360) {
newAngle = 0;
}
let height: number = (this.mainWrapper.nativeElement as GridLayout).getMeasuredHeight() / this._deviceService.device.screen.mainScreen.scale;
if (height === 0) {
height = this._deviceService.device.screen.mainScreen.heightDIPs
}
let offset: number = 0;
if (this._deviceService.device.isIOS) {
offset = application.ios.window.safeAreaInsets.top;
}
const radius: number = (BodyWrapperComponent.circleStep * (wrapperIndex + 1) + BodyWrapperComponent.circleStartRadius) / 2;
const startPosition: { x: number; y: number } = {
x: this._deviceService.device.screen.mainScreen.widthDIPs / 2,
y: height / 2 - offset
};
const circleSize: number = BodyWrapperComponent.circleSizes[circleIndex];
const circlePosition: { x: number; y: number } = this._getPosition(radius, angle);
const animateSettings: AnimationDefinition = {
translate: {
x: startPosition.x + circlePosition.x - circleSize / 2,
y: startPosition.y + circlePosition.y - circleSize / 2
},
iterations: 1,
duration,
target: circle
}
if (circle.opacity === 0) {
animateSettings.opacity = 1;
}
if (!this._allAnimations[wrapperIndex]) {
this._allAnimations[wrapperIndex] = {};
}
if (this._allAnimations[wrapperIndex][circleIndex]) {
(this._allAnimations[wrapperIndex][circleIndex] as animationModule.Animation).cancel();
(this._allAnimations[wrapperIndex][circleIndex] as animationModule.Animation) = null;
}
// Animation
(this._allAnimations[wrapperIndex][circleIndex] as animationModule.Animation) = new animationModule.Animation([animateSettings]);
(this._allAnimations[wrapperIndex][circleIndex] as animationModule.Animation).play().then(() => {
this._animateCircle(circle, newAngle, circleIndex, wrapperIndex, duration);
}).catch(() => {
this._loggerService.log('stop');
});
}
}
On page change - the application hangs
this._router.navigate ([item.url], {
clearHistory: true,
transition: {
name: 'slideLeft'
}
});
But if you remove clearHistory: true then everything is fine
But if you remove the history clearing, this will not be a good result of the application.
How can this problem be corrected?
Thank you in advance
3DtuningProduction how are you? do you solve this?.
if you reply to me I will be grateful to you and I can send money by PayPal.