1- import { AfterViewInit , Component , ElementRef , Inject , Input , OnDestroy , PLATFORM_ID , ViewChild } from '@angular/core' ;
1+ import {
2+ AfterViewInit ,
3+ ChangeDetectionStrategy ,
4+ Component ,
5+ ElementRef ,
6+ Inject ,
7+ Input ,
8+ OnDestroy ,
9+ PLATFORM_ID , signal ,
10+ ViewChild , WritableSignal
11+ } from '@angular/core' ;
212import { CommonModule , isPlatformBrowser } from "@angular/common" ;
313
414@Component ( {
@@ -7,6 +17,7 @@ import {CommonModule, isPlatformBrowser} from "@angular/common";
717 imports : [ CommonModule ] ,
818 templateUrl : "./ngx-background-beams.component.html" ,
919 styleUrl : "./ngx-background-beams.component.scss" ,
20+ changeDetection : ChangeDetectionStrategy . OnPush ,
1021} )
1122export class NgxBackgroundBeamsComponent implements AfterViewInit , OnDestroy {
1223 @ViewChild ( 'OmBackgroundBeams' ) componentRef ! : ElementRef < HTMLElement > ;
@@ -17,29 +28,26 @@ export class NgxBackgroundBeamsComponent implements AfterViewInit, OnDestroy {
1728 throw new Error ( 'om-background-beams: gradient colors need to be exactly 3 values.' ) ;
1829 }
1930
20- this . gradientColors = colors ;
31+ this . gradientColors . set ( colors ) ;
2132 }
2233
23- gradientColors : string [ ] = [ '#18CCFC' , '#6344F5' , '#AE48FF' ] ;
24-
2534 @Input ( )
26- pathColor : string = 'rgba(255, 255, 255, 0.08) ' ;
35+ pathColor : string = '#00000025 ' ;
2736
2837 @Input ( ) pathQuantity : number = 50 ;
2938
30- paths : string [ ] = [ ] ;
31-
32- x1 : string [ ] = [ ] ;
33- x2 : string [ ] = [ ] ;
34- y1 : string [ ] = [ ] ;
35- y2 : string [ ] = [ ] ;
36-
37- delays : number [ ] = [ ] ;
38- durations : number [ ] = [ ] ;
39+ readonly gradientColors : WritableSignal < string [ ] > = signal ( [ '#18CCFC' , '#6344F5' , '#AE48FF' ] ) ;
40+ readonly paths : WritableSignal < string [ ] > = signal ( [ ] ) ;
41+ readonly x1 : WritableSignal < string [ ] > = signal ( [ ] ) ;
42+ readonly x2 : WritableSignal < string [ ] > = signal ( [ ] ) ;
43+ readonly y1 : WritableSignal < string [ ] > = signal ( [ ] ) ;
44+ readonly y2 : WritableSignal < string [ ] > = signal ( [ ] ) ;
45+ readonly delays : WritableSignal < number [ ] > = signal ( [ ] ) ;
46+ readonly durations : WritableSignal < number [ ] > = signal ( [ ] ) ;
47+ readonly inViewport : WritableSignal < boolean > = signal ( false ) ;
3948
4049 private animationFrameId ?: number ;
4150 private observer ?: IntersectionObserver ;
42- private inViewport = false ;
4351
4452 constructor (
4553 @Inject ( PLATFORM_ID ) private platformId : object
@@ -60,13 +68,13 @@ export class NgxBackgroundBeamsComponent implements AfterViewInit, OnDestroy {
6068 }
6169
6270 generatePaths ( ) : void {
63- this . paths = [ ] ;
64- this . x1 = [ ] ;
65- this . x2 = [ ] ;
66- this . y1 = [ ] ;
67- this . y2 = [ ] ;
68- this . delays = [ ] ;
69- this . durations = [ ] ;
71+ this . paths . set ( [ ] ) ;
72+ this . x1 . set ( [ ] ) ;
73+ this . x2 . set ( [ ] ) ;
74+ this . y1 . set ( [ ] ) ;
75+ this . y2 . set ( [ ] ) ;
76+ this . delays . set ( [ ] ) ;
77+ this . durations . set ( [ ] ) ;
7078
7179 const firstPath = {
7280 mX1 : - 380 , mY1 : - 189 , cX1 : - 380 , cY1 : - 189 , cX2 : - 312 , cY2 : 216 ,
@@ -78,6 +86,14 @@ export class NgxBackgroundBeamsComponent implements AfterViewInit, OnDestroy {
7886 cX3 : 495 , cY3 : - 49 , cX4 : 959 , cY4 : 78 , cX5 : 1027 , cY5 : 483
7987 } ;
8088
89+ const paths : string [ ] = [ ] ;
90+ const x1 : string [ ] = [ ] ;
91+ const x2 : string [ ] = [ ] ;
92+ const y1 : string [ ] = [ ] ;
93+ const y2 : string [ ] = [ ] ;
94+ const delays : number [ ] = [ ] ;
95+ const durations : number [ ] = [ ] ;
96+
8197 for ( let i = 0 ; i < this . pathQuantity ; i ++ ) {
8298 const t = i / ( this . pathQuantity - 1 ) ;
8399
@@ -98,16 +114,24 @@ export class NgxBackgroundBeamsComponent implements AfterViewInit, OnDestroy {
98114 `C${ cX1 } ${ cY1 } ${ cX2 } ${ cY2 } ${ cX3 } ${ cY3 } ` +
99115 `C${ cX4 } ${ cY4 } ${ cX5 } ${ cY5 } ${ cX5 } ${ cY5 } ` ;
100116
101- this . paths . push ( path ) ;
117+ paths . push ( path ) ;
102118
103- this . x1 . push ( '0%' ) ;
104- this . x2 . push ( '0%' ) ;
105- this . y1 . push ( '0%' ) ;
106- this . y2 . push ( '0%' ) ;
119+ x1 . push ( '0%' ) ;
120+ x2 . push ( '0%' ) ;
121+ y1 . push ( '0%' ) ;
122+ y2 . push ( '0%' ) ;
107123
108- this . delays . push ( Math . random ( ) * 10 ) ;
109- this . durations . push ( Math . random ( ) * 10 + 10 ) ;
124+ delays . push ( Math . random ( ) * 10 ) ;
125+ durations . push ( Math . random ( ) * 10 + 10 ) ;
110126 }
127+
128+ this . paths . set ( paths ) ;
129+ this . x1 . set ( x1 ) ;
130+ this . x2 . set ( x2 ) ;
131+ this . y1 . set ( y1 ) ;
132+ this . y2 . set ( y2 ) ;
133+ this . delays . set ( delays ) ;
134+ this . durations . set ( durations ) ;
111135 }
112136
113137 initializeIntersectionObserver ( ) {
@@ -116,10 +140,10 @@ export class NgxBackgroundBeamsComponent implements AfterViewInit, OnDestroy {
116140 clearTimeout ( observerTimeout ) ;
117141 observerTimeout = setTimeout ( ( ) => {
118142 if ( entry . isIntersecting ) {
119- this . inViewport = true ;
143+ this . inViewport . set ( true ) ;
120144 this . startAnimations ( ) ;
121145 } else {
122- this . inViewport = false ;
146+ this . inViewport . set ( false ) ;
123147 this . generatePaths ( ) ;
124148 }
125149 } , 100 ) ;
@@ -136,9 +160,9 @@ export class NgxBackgroundBeamsComponent implements AfterViewInit, OnDestroy {
136160 }
137161
138162 startAnimations ( ) : void {
139- this . paths . forEach ( ( _ , index ) => {
140- const delay = this . delays [ index ] * 1000 ;
141- const duration = this . durations [ index ] * 1000 ;
163+ this . paths ( ) . forEach ( ( _ , index ) => {
164+ const delay = this . delays ( ) [ index ] * 1000 ;
165+ const duration = this . durations ( ) [ index ] * 1000 ;
142166
143167 setTimeout ( ( ) => {
144168 this . animateGradient ( index , duration ) ;
@@ -151,17 +175,17 @@ export class NgxBackgroundBeamsComponent implements AfterViewInit, OnDestroy {
151175 const randomY2Value = 93 + Math . random ( ) * 8 ;
152176
153177 const animate = ( currentTime : number ) => {
154- if ( ! this . inViewport ) {
178+ if ( ! this . inViewport ( ) ) {
155179 return ;
156180 }
157181
158182 const elapsed = currentTime - startTime ;
159183 const progress = Math . min ( elapsed / duration , 1 ) ;
160184
161- this . x1 [ index ] = `${ progress * 100 } %` ;
162- this . x2 [ index ] = `${ progress * 95 } %` ;
163- this . y1 [ index ] = `${ progress * 100 } %` ;
164- this . y2 [ index ] = `${ progress * randomY2Value } %` ;
185+ this . x1 . update ( a => ( a [ index ] = `${ progress * 100 } %` , a ) ) ;
186+ this . x2 . update ( a => ( a [ index ] = `${ progress * 95 } %` , a ) ) ;
187+ this . y1 . update ( a => ( a [ index ] = `${ progress * 100 } %` , a ) ) ;
188+ this . y2 . update ( a => ( a [ index ] = `${ progress * randomY2Value } %` , a ) ) ;
165189
166190 this . updateGradientAttributes ( index ) ;
167191
@@ -178,19 +202,19 @@ export class NgxBackgroundBeamsComponent implements AfterViewInit, OnDestroy {
178202 updateGradientAttributes ( index : number ) : void {
179203 const gradientElement = document . getElementById ( `linearGradient-${ index } ` ) ;
180204 if ( gradientElement ) {
181- gradientElement . setAttribute ( 'x1' , this . x1 [ index ] ) ;
182- gradientElement . setAttribute ( 'x2' , this . x2 [ index ] ) ;
183- gradientElement . setAttribute ( 'y1' , this . y1 [ index ] ) ;
184- gradientElement . setAttribute ( 'y2' , this . y2 [ index ] ) ;
205+ gradientElement . setAttribute ( 'x1' , this . x1 ( ) [ index ] ) ;
206+ gradientElement . setAttribute ( 'x2' , this . x2 ( ) [ index ] ) ;
207+ gradientElement . setAttribute ( 'y1' , this . y1 ( ) [ index ] ) ;
208+ gradientElement . setAttribute ( 'y2' , this . y2 ( ) [ index ] ) ;
185209 }
186210 }
187211
188212 restartAnimation ( index : number , duration : number ) : void {
189213 setTimeout ( ( ) => {
190- this . x1 [ index ] = '0%' ;
191- this . x2 [ index ] = '0%' ;
192- this . y1 [ index ] = '0%' ;
193- this . y2 [ index ] = '0%' ;
214+ this . x1 . update ( a => ( a [ index ] = `0%` , a ) ) ;
215+ this . x2 . update ( a => ( a [ index ] = `0%` , a ) ) ;
216+ this . y1 . update ( a => ( a [ index ] = `0%` , a ) ) ;
217+ this . y2 . update ( a => ( a [ index ] = `0%` , a ) ) ;
194218
195219 this . animateGradient ( index , duration ) ;
196220 } , Math . random ( ) * 10000 ) ;
0 commit comments