Skip to content

Commit

Permalink
feat: improve performace
Browse files Browse the repository at this point in the history
  • Loading branch information
sheikalthaf committed Aug 24, 2023
1 parent a75de04 commit 1d880e4
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 19 deletions.
56 changes: 49 additions & 7 deletions projects/ngu/magnify/src/lib/magnify.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
OnInit,
OnDestroy,
} from '@angular/core';
import { Subscription } from 'rxjs';
import { Subject, Subscription } from 'rxjs';
import { MagnifyService } from './magnify.service';

@Directive({
Expand All @@ -28,23 +28,36 @@ export class Magnify implements OnInit, OnDestroy {
private scaleYValue = 1;
subscription: Subscription;
zSubscription: Subscription;
z$ = new Subject<boolean>();
isZoomed = false;
id = Date.now().toString();

constructor(
private el: ElementRef<HTMLImageElement>,
private renderer: Renderer2,
private ngZone: NgZone
) {}
) {
this.magnifyService.add(this.id);
}

ngOnInit() {
this.ngZone.runOutsideAngular(() => {
this.el.nativeElement.addEventListener('load', this.updateSizes, {
once: true,
});
this.init();
// this.initClick();
this.zInit();
});
}

private initClick() {
this.el.nativeElement.addEventListener('click', (ev) => {
this.isZoomed = !this.isZoomed;
this.z$.next(this.isZoomed);
});
}

private init() {
private zInit() {
this.zSubscription = this.magnifyService.z$.subscribe((res) => {
if (res) {
this.el.nativeElement.addEventListener('mouseenter', this.onMouseEnter);
Expand All @@ -58,6 +71,7 @@ export class Magnify implements OnInit, OnDestroy {
'mouseenter',
this.onMouseEnter
);
// this.onMouseEnter();
this.onMouseLeave();
}
});
Expand All @@ -73,6 +87,7 @@ export class Magnify implements OnInit, OnDestroy {
this.zSubscription?.unsubscribe();
this.subscription?.unsubscribe();
this.div?.remove();
this.magnifyService.remove(this.id);
}

updateSizes = () => {
Expand All @@ -96,20 +111,46 @@ export class Magnify implements OnInit, OnDestroy {

private getValues(rect: DOMRect, parent: DOMRect) {
let left = rect.left - parent.left;
const top = rect.top - parent.top;
let top = rect.top - parent.top;
let cWidth = rect.width;
let cHeight = rect.height;

if (!this.inline) {
left += rect.width + 40;
cWidth = 400;
cHeight = 400;
}

const width = rect.width * this.scale;
const localScale = width / rect.width;
const height = rect.height * localScale;

this.scaleXValue = (width - cWidth) / rect.width;
this.scaleYValue = (height - cHeight) / rect.height;
return { cWidth, cHeight, left, top, width, height };

if (!this.inline) {
// Determine whether to show magnified image on the left or right
const screenWidth = window.innerWidth;
const showOnLeft = left > screenWidth / 2;

left = showOnLeft ? left - cWidth - 10 : left + rect.width + 10

// Determine whether to position magnified image above or below original image
const screenHeight = window.innerHeight;
const showAbove = (top + cHeight) > screenHeight;

if (showAbove) {
top -= (cHeight - rect.height);
}
}

return {
cWidth,
cHeight,
left,
top,
width,
height
};
}

private get parentElement() {
Expand Down Expand Up @@ -177,6 +218,7 @@ export class Magnify implements OnInit, OnDestroy {
onMouseLeave = () => {
// this.el.nativeElement.removeEventListener('mousemove', this.onMouseMove);
this.subscription?.unsubscribe();
this.isZoomed = false;
this.el.nativeElement.removeEventListener('mouseleave', this.onMouseLeave);
if (this.div) this.renderer.setStyle(this.div, 'display', 'none');
};
Expand Down
45 changes: 34 additions & 11 deletions projects/ngu/magnify/src/lib/magnify.service.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,48 @@
import { Injectable, NgZone } from '@angular/core';
import { Subject } from 'rxjs';
import { Injectable, NgZone, inject } from '@angular/core';
import { Subject, Subscription } from 'rxjs';
import { KeysEvent } from './keysEvent';

@Injectable({ providedIn: 'root' })
export class MagnifyService {
keyEvents = new KeysEvent();
private keyEvents = new KeysEvent();
currentMousePosition: MouseEvent;
currentMouse$ = new Subject<MouseEvent>();
z$ = new Subject<boolean>();
private ngZone = inject(NgZone);
private zSubscription: Subscription;
private observersIds = new Set<string>();
private isConnected = false;

constructor(private ngZone: NgZone) {
constructor() {}

private onMouseMove = (ev: MouseEvent) => {
this.currentMousePosition = ev;
this.currentMouse$.next(ev);
};

add(id: string) {
this.observersIds.add(id);
if (!this.isConnected) this.connect();
}

remove(id: string) {
this.observersIds.delete(id);
if (this.observersIds.size === 0) this.disconnect();
}

private disconnect() {
document.removeEventListener('mousemove', this.onMouseMove);
this.zSubscription?.unsubscribe();
this.isConnected = false;
}

private connect() {
this.ngZone.runOutsideAngular(() => {
document.addEventListener('mousemove', (ev) => this.onMouseMove(ev));
this.keyEvents.event('z').subscribe(([res, ev]) => {
this.isConnected = true;
document.addEventListener('mousemove', ev => this.onMouseMove(ev));
this.zSubscription = this.keyEvents.event('z').subscribe(([res, ev]) => {
this.z$.next(res);
});
});
}

onMouseMove = (ev: MouseEvent) => {
this.currentMousePosition = ev;
this.currentMouse$.next(ev);
};
}
2 changes: 1 addition & 1 deletion src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
</div>

<ng-container *ngIf="isOpen">
<div class="p-4 relative flex gap-4 overflow-auto">
<div class="p-4 relative flex gap-4 overflow-auto flex-wrap">
<img
class="w-48"
src="assets/page.webp"
Expand Down

0 comments on commit 1d880e4

Please sign in to comment.