morgred
morgred

Reputation: 1117

How to handle ExpressionChangedAfterItHasBeenChecked on page scaling code that runs on window resize?

I'm working on making the content of a page scale while keeping proportions consistent according to a few usual breakpoints. I placed an event listener on the window where I run my function that calculates the X and Y of a transform-scale and transform-translate of the element that wraps my content.

How do I properly handle this? I tried setting my values in ngOnInit but that just makes my scaling variables unavailable.

I'm using this article as reference for the scaling ideas

HTML

<div id="measure-width-vw" #vpWidth></div>
<div id="measure-height-vh" #vpHeight></div>


<div id="scaledElement" class="bg-image-wrapper" #scaledElement [style.transform]="'scale(' + targetScale.X + ', ' + targetScale.Y +
    ') translate(' + targetTranslate.X + 'px, ' +  targetTranslate.Y + 'px)'">

   ... content ...

</div>

JAVASCRIPT

export class NotificationsComponent {

    @ViewChild('vpWidth') vpWidthElement: ElementRef<HTMLElement>;
    @ViewChild('vpHeight') vpHeightElement: ElementRef<HTMLElement>;
    @ViewChild('scaledElement') scaledElement: ElementRef<HTMLElement>;

    @HostListener('window:resize', ['$event'])
    onResize(event) {
        this.setScalingValues(this.scaledElement.nativeElement.offsetWidth, this.scaledElement.nativeElement.offsetHeight,
            this.vpWidthElement.nativeElement.offsetWidth, this.vpHeightElement.nativeElement.offsetHeight);
    }

    vpWidth: number;
    vpHeight: number;
    scalable: {
        height: number,
        width: number
    }
    targetScale: {
        X: number,
        Y: number
    }
    targetTranslate: {
        X: number,
        Y: number
    }
    
    ...
    
    constructor() {
        this.scalable = {
            width: 0,
            height: 0
        }
        this.targetScale = {
            X: 0,
            Y: 0
        }
        this.targetTranslate = {
            X: 0,
            Y: 0
        }
    }
    
    ngAfterViewInit(): void {
        window.dispatchEvent(new Event('resize'));
    }
    
    setScalingValues(scalableWidth, scalableHeight, vpWidth, vpHeight) {
        this.scalable.width = scalableWidth;
        this.scalable.height = scalableHeight;

        this.vpWidth = vpWidth;
        this.vpHeight = vpHeight;

        this.targetScale.X = this.vpWidth / this.scalable.width;
        this.targetScale.Y = this.vpHeight / this.scalable.height;

        this.targetScale.X = Math.min(this.targetScale.X, this.targetScale.Y);
        this.targetScale.Y = this.targetScale.X;

        this.targetTranslate.X = Math.round((this.vpWidth - (this.scalable.width * this.targetScale.X)) / 2);
        console.log(this.scalable.width);
        this.targetTranslate.Y = Math.round((this.vpHeight - (this.scalable.height * this.targetScale.Y)) / 2);
    }
}

Upvotes: 0

Views: 75

Answers (1)

Mustafa
Mustafa

Reputation: 307

onResize(event) {
    setTimeout(() => this.setScalingValues(this.scaledElement.nativeElement.offsetWidth, this.scaledElement.nativeElement.offsetHeight,
        this.vpWidthElement.nativeElement.offsetWidth, this.vpHeightElement.nativeElement.offsetHeight));
}

Upvotes: 1

Related Questions