From 9b29d39d89f90df977edf52f037cc3042b7e1864 Mon Sep 17 00:00:00 2001 From: Chau Tran Date: Sun, 14 Nov 2021 13:22:06 -0600 Subject: [PATCH] feat(core): add util directives and pipes --- packages/core/src/index.ts | 22 +++++++ .../core/src/lib/canvas.component.spec.ts | 13 ++-- packages/core/src/lib/canvas.component.ts | 2 +- packages/core/src/lib/color/color.module.ts | 8 +++ packages/core/src/lib/color/color.pipe.ts | 17 +++++ packages/core/src/lib/core.module.ts | 8 +-- packages/core/src/lib/fog/fog.module.ts | 8 +++ packages/core/src/lib/fog/fog.pipe.ts | 12 ++++ .../core/src/lib/math/math-constant.pipe.ts | 27 ++++++++ packages/core/src/lib/math/math.module.ts | 9 +++ packages/core/src/lib/math/math.pipe.ts | 28 ++++++++ .../core/src/lib/repeat/repeat.directive.ts | 65 +++++++++++++++++++ packages/core/src/lib/repeat/repeat.module.ts | 8 +++ 13 files changed, 215 insertions(+), 12 deletions(-) create mode 100644 packages/core/src/lib/color/color.module.ts create mode 100644 packages/core/src/lib/color/color.pipe.ts create mode 100644 packages/core/src/lib/fog/fog.module.ts create mode 100644 packages/core/src/lib/fog/fog.pipe.ts create mode 100644 packages/core/src/lib/math/math-constant.pipe.ts create mode 100644 packages/core/src/lib/math/math.module.ts create mode 100644 packages/core/src/lib/math/math.pipe.ts create mode 100644 packages/core/src/lib/repeat/repeat.directive.ts create mode 100644 packages/core/src/lib/repeat/repeat.module.ts diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 477b8b27e..ebcce7fe6 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,2 +1,24 @@ +export * from './lib/models'; + export * from './lib/core.module'; export * from './lib/canvas.component'; + +export * from './lib/services/loader.service'; + +export * from './lib/stores/animation.store'; +export * from './lib/stores/canvas.store'; +export * from './lib/stores/events.store'; +export * from './lib/stores/instances.store'; + +export * from './lib/color/color.pipe'; +export * from './lib/color/color.module'; + +export * from './lib/fog/fog.pipe'; +export * from './lib/fog/fog.module'; + +export * from './lib/math/math.pipe'; +export * from './lib/math/math-constant.pipe'; +export * from './lib/math/math.module'; + +export * from './lib/repeat/repeat.directive'; +export * from './lib/repeat/repeat.module'; diff --git a/packages/core/src/lib/canvas.component.spec.ts b/packages/core/src/lib/canvas.component.spec.ts index ea2e3ad0b..61ee83e14 100644 --- a/packages/core/src/lib/canvas.component.spec.ts +++ b/packages/core/src/lib/canvas.component.spec.ts @@ -1,20 +1,19 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { CanvasComponent } from './canvas.component'; +import { NgtCanvasComponent } from './canvas.component'; describe('CanvasComponent', () => { - let component: CanvasComponent; - let fixture: ComponentFixture; + let component: NgtCanvasComponent; + let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ CanvasComponent ] - }) - .compileComponents(); + declarations: [NgtCanvasComponent], + }).compileComponents(); }); beforeEach(() => { - fixture = TestBed.createComponent(CanvasComponent); + fixture = TestBed.createComponent(NgtCanvasComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/packages/core/src/lib/canvas.component.ts b/packages/core/src/lib/canvas.component.ts index cdfcf401e..22787a3f3 100644 --- a/packages/core/src/lib/canvas.component.ts +++ b/packages/core/src/lib/canvas.component.ts @@ -58,7 +58,7 @@ import { InstancesStore } from './stores/instances.store'; DestroyedService, ], }) -export class CanvasComponent implements OnInit { +export class NgtCanvasComponent implements OnInit { @HostBinding('class.ngt-canvas') hostClass = true; @Input() set orthographic(v: boolean) { diff --git a/packages/core/src/lib/color/color.module.ts b/packages/core/src/lib/color/color.module.ts new file mode 100644 index 000000000..d43054574 --- /dev/null +++ b/packages/core/src/lib/color/color.module.ts @@ -0,0 +1,8 @@ +import { NgModule } from '@angular/core'; +import { NgtColorPipe } from './color.pipe'; + +@NgModule({ + declarations: [NgtColorPipe], + exports: [NgtColorPipe], +}) +export class NgtColorPipeModule {} diff --git a/packages/core/src/lib/color/color.pipe.ts b/packages/core/src/lib/color/color.pipe.ts new file mode 100644 index 000000000..d416266e3 --- /dev/null +++ b/packages/core/src/lib/color/color.pipe.ts @@ -0,0 +1,17 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import * as THREE from 'three'; + +@Pipe({ + name: 'color', + pure: true, +}) +export class NgtColorPipe implements PipeTransform { + /** + * ConstructorParameters has a limitation on THREE.Color constructor overloads + */ + transform( + args: Array | [number, number, number] + ): THREE.Color { + return new THREE.Color(...args); + } +} diff --git a/packages/core/src/lib/core.module.ts b/packages/core/src/lib/core.module.ts index 89b80caf7..65026d4f9 100644 --- a/packages/core/src/lib/core.module.ts +++ b/packages/core/src/lib/core.module.ts @@ -1,10 +1,10 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; -import { CanvasComponent } from './canvas.component'; +import { NgtCanvasComponent } from './canvas.component'; @NgModule({ imports: [CommonModule], - declarations: [CanvasComponent], - exports: [CanvasComponent], + declarations: [NgtCanvasComponent], + exports: [NgtCanvasComponent], }) -export class CoreModule {} +export class NgtCoreModule {} diff --git a/packages/core/src/lib/fog/fog.module.ts b/packages/core/src/lib/fog/fog.module.ts new file mode 100644 index 000000000..317116fb4 --- /dev/null +++ b/packages/core/src/lib/fog/fog.module.ts @@ -0,0 +1,8 @@ +import { NgModule } from '@angular/core'; +import { NgtFogPipe } from './fog.pipe'; + +@NgModule({ + declarations: [NgtFogPipe], + exports: [NgtFogPipe], +}) +export class NgtFogPipeModule {} diff --git a/packages/core/src/lib/fog/fog.pipe.ts b/packages/core/src/lib/fog/fog.pipe.ts new file mode 100644 index 000000000..318f5556b --- /dev/null +++ b/packages/core/src/lib/fog/fog.pipe.ts @@ -0,0 +1,12 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import * as THREE from 'three'; + +@Pipe({ + name: 'fog', + pure: true, +}) +export class NgtFogPipe implements PipeTransform { + transform(args: ConstructorParameters): THREE.Fog { + return new THREE.Fog(...args); + } +} diff --git a/packages/core/src/lib/math/math-constant.pipe.ts b/packages/core/src/lib/math/math-constant.pipe.ts new file mode 100644 index 000000000..ea7287c77 --- /dev/null +++ b/packages/core/src/lib/math/math-constant.pipe.ts @@ -0,0 +1,27 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({ + name: 'mathConst', + pure: true, +}) +export class NgtMathConstantPipe implements PipeTransform { + transform( + value: number | 0, + keyOfMathConst: + | 'PI' + | 'E' + | 'LN2' + | 'LOG2E' + | 'LN10' + | 'LOG10E' + | 'SQRT1_2' + | 'SQRT2' + | 'random' + ): number { + if (keyOfMathConst === 'random') { + return Math.random(); + } + + return value * Math[keyOfMathConst]; + } +} diff --git a/packages/core/src/lib/math/math.module.ts b/packages/core/src/lib/math/math.module.ts new file mode 100644 index 000000000..42b05147b --- /dev/null +++ b/packages/core/src/lib/math/math.module.ts @@ -0,0 +1,9 @@ +import { NgModule } from '@angular/core'; +import { NgtMathConstantPipe } from './math-constant.pipe'; +import { NgtMathPipe } from './math.pipe'; + +@NgModule({ + declarations: [NgtMathPipe, NgtMathConstantPipe], + exports: [NgtMathPipe, NgtMathConstantPipe], +}) +export class NgtMathPipeModule {} diff --git a/packages/core/src/lib/math/math.pipe.ts b/packages/core/src/lib/math/math.pipe.ts new file mode 100644 index 000000000..77e07f9ef --- /dev/null +++ b/packages/core/src/lib/math/math.pipe.ts @@ -0,0 +1,28 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({ + name: 'math', + pure: true, +}) +export class NgtMathPipe implements PipeTransform { + transform( + value: number | number[], + keyOfMath: keyof Omit< + Math, + | 'PI' + | 'E' + | 'LN2' + | 'LOG2E' + | 'LN10' + | 'LOG10E' + | 'SQRT1_2' + | 'SQRT2' + | 'random' + > + ): ReturnType> { + const params: number[] = Array.isArray(value) ? value : [value]; + return (Math[keyOfMath] as unknown as (...args: number[]) => number)( + ...params + ) as ReturnType>; + } +} diff --git a/packages/core/src/lib/repeat/repeat.directive.ts b/packages/core/src/lib/repeat/repeat.directive.ts new file mode 100644 index 000000000..706c1cd87 --- /dev/null +++ b/packages/core/src/lib/repeat/repeat.directive.ts @@ -0,0 +1,65 @@ +import { + Directive, + Inject, + Input, + TemplateRef, + ViewContainerRef, +} from '@angular/core'; + +const MAX_VALUE = 0x10000; + +export interface RepeatContext { + $implicit: number; + isOdd: boolean; + isEven: boolean; + isFirst: boolean; + isLast: boolean; +} + +@Directive({ + selector: '[repeat][repeatOf]', +}) +export class NgtRepeatDirective { + @Input() + set repeatOf(count: number) { + const safeCount = Math.floor(Math.max(0, Math.min(count, MAX_VALUE))); + const { length } = this.viewContainer; + + if (safeCount < length) { + this.removeContainers(length - safeCount); + } else { + this.addContainers(length, safeCount); + } + } + + constructor( + @Inject(ViewContainerRef) private readonly viewContainer: ViewContainerRef, + @Inject(TemplateRef) + private readonly templateRef: TemplateRef + ) {} + + private addContainers(length: number, count: number) { + for (let index = length; index < count; index++) { + this.viewContainer.createEmbeddedView(this.templateRef, { + $implicit: index, + isFirst: index === length, + isLast: index === count - 1, + isOdd: !(index % 2), + isEven: !!(index % 2), + }); + } + } + + private removeContainers(amount: number) { + for (let index = 0; index < amount; index++) { + this.viewContainer.remove(); + } + } + + static ngTemplateContextGuard( + dir: NgtRepeatDirective, + ctx: unknown + ): ctx is RepeatContext { + return true; + } +} diff --git a/packages/core/src/lib/repeat/repeat.module.ts b/packages/core/src/lib/repeat/repeat.module.ts new file mode 100644 index 000000000..34e93a686 --- /dev/null +++ b/packages/core/src/lib/repeat/repeat.module.ts @@ -0,0 +1,8 @@ +import { NgModule } from '@angular/core'; +import { NgtRepeatDirective } from './repeat.directive'; + +@NgModule({ + declarations: [NgtRepeatDirective], + exports: [NgtRepeatDirective], +}) +export class NgtRepeatModule {}