Skip to content

Commit aec5411

Browse files
author
Markus Block
committed
feat/update:
- updated logic and version for angular v20
1 parent 46b633c commit aec5411

File tree

4 files changed

+93
-67
lines changed

4 files changed

+93
-67
lines changed

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"name": "@omnedia/ngx-background-beams",
3-
"version": "2.0.0",
3+
"version": "3.0.0",
44
"peerDependencies": {
5-
"@angular/common": "^19.0.0",
6-
"@angular/core": "^19.0.0"
5+
"@angular/common": "^20.0.0",
6+
"@angular/core": "^20.0.0"
77
},
88
"dependencies": {
99
"tslib": "^2.3.0"

src/lib/ngx-background-beams.component.html

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,39 +17,39 @@
1717
></path>
1818

1919
<!-- Dynamic motion path generation with Angular -->
20-
<ng-container *ngFor="let path of paths; let i = index">
20+
@for (path of paths(); track $index) {
2121
<path
2222
[attr.d]="path"
2323
[attr.stroke]="pathColor"
24-
stroke-opacity="0.4"
24+
stroke-opacity="1"
2525
stroke-width="0.5"
2626
></path>
2727

2828
<path
2929
[attr.d]="path"
30-
[attr.stroke]="'url(#linearGradient-' + i + ')'"
31-
stroke-opacity="0.4"
30+
[attr.stroke]="'url(#linearGradient-' + $index + ')'"
31+
stroke-opacity="1"
3232
stroke-width="0.5"
33-
[attr.id]="'path-' + i"
33+
[attr.id]="'path-' + $index"
3434
></path>
35-
</ng-container>
35+
}
3636

3737
<!-- Definitions for gradients -->
3838
<defs>
39-
<ng-container *ngFor="let path of paths; let i = index">
39+
@for (path of paths(); track $index) {
4040
<linearGradient
41-
[attr.id]="'linearGradient-' + i"
42-
[attr.x1]="x1[i]"
43-
[attr.x2]="x2[i]"
44-
[attr.y1]="y1[i]"
45-
[attr.y2]="y2[i]"
41+
[attr.id]="'linearGradient-' + $index"
42+
[attr.x1]="x1()[$index]"
43+
[attr.x2]="x2()[$index]"
44+
[attr.y1]="y1()[$index]"
45+
[attr.y2]="y2()[$index]"
4646
>
47-
<stop [attr.stop-color]="gradientColors[0]" stop-opacity="0"></stop>
48-
<stop [attr.stop-color]="gradientColors[0]"></stop>
49-
<stop offset="32.5%" [attr.stop-color]="gradientColors[1]"></stop>
50-
<stop offset="100%" [attr.stop-color]="gradientColors[2]" stop-opacity="0"></stop>
47+
<stop [attr.stop-color]="gradientColors()[0]" stop-opacity="0"></stop>
48+
<stop [attr.stop-color]="gradientColors()[0]"></stop>
49+
<stop offset="32.5%" [attr.stop-color]="gradientColors()[1]"></stop>
50+
<stop offset="100%" [attr.stop-color]="gradientColors()[2]" stop-opacity="0"></stop>
5151
</linearGradient>
52-
</ng-container>
52+
}
5353

5454
<!-- Radial Gradient -->
5555
<radialGradient

src/lib/ngx-background-beams.component.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
.om-background-beams {
22
position: relative;
33
overflow: hidden;
4+
width: 100%;
5+
height: 100%;
46

57
.om-background-beams-background {
68
position: absolute;

src/lib/ngx-background-beams.component.ts

Lines changed: 71 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
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';
212
import {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
})
1122
export 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

Comments
 (0)