Skip to content

Commit 86be9cc

Browse files
committed
update scroll controls component to use NgtHtml
1 parent 341c775 commit 86be9cc

File tree

5 files changed

+68
-53
lines changed

5 files changed

+68
-53
lines changed

libs/core/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export * from './lib/canvas';
22
export * from './lib/directives/args';
33
export { NgtCamera, NgtComputeFunction, NgtDomEvent, NgtThreeEvent } from './lib/events';
4+
export * from './lib/html';
45
export * from './lib/instance';
56
export * from './lib/loader';
67
export { addAfterEffect, addEffect, addTail } from './lib/loop';

libs/core/src/lib/html.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import {
2+
AbstractType,
3+
DestroyRef,
4+
Directive,
5+
ElementRef,
6+
inject,
7+
InjectionToken,
8+
Provider,
9+
ProviderToken,
10+
Type,
11+
} from '@angular/core';
12+
import { HTML } from './renderer';
13+
import { injectStore } from './store';
14+
import { NgtAnyRecord } from './types';
15+
16+
const NGT_HTML_DOM_ELEMENT = new InjectionToken<'gl' | HTMLElement>('NGT_HTML_DOM_ELEMENT');
17+
18+
export function provideHTMLDomElement(): Provider;
19+
export function provideHTMLDomElement<
20+
TDeps extends Array<ProviderToken<any>>,
21+
TValues extends {
22+
[K in keyof TDeps]: TDeps[K] extends Type<infer T> | AbstractType<infer T> | InjectionToken<infer T> ? T : never;
23+
},
24+
>(deps: TDeps, factory: (...args: TValues) => HTMLElement): Provider;
25+
export function provideHTMLDomElement(...args: any[]) {
26+
if (args.length === 0) {
27+
return { provide: NGT_HTML_DOM_ELEMENT, useFactory: () => 'gl' };
28+
}
29+
30+
return { provide: NGT_HTML_DOM_ELEMENT, useFactory: args.pop(), deps: args };
31+
}
32+
33+
@Directive()
34+
export abstract class NgtHTML {
35+
static [HTML] = true;
36+
37+
protected store = injectStore();
38+
protected destroyRef = inject(DestroyRef);
39+
protected host = inject<ElementRef<HTMLElement>>(ElementRef);
40+
protected domElement = inject(NGT_HTML_DOM_ELEMENT, { self: true, optional: true });
41+
42+
constructor() {
43+
if (this.domElement === 'gl') {
44+
Object.assign(this.host.nativeElement, {
45+
__ngt_dom_parent__: this.store.snapshot.gl.domElement.parentElement,
46+
});
47+
} else if (this.domElement) {
48+
Object.assign(this.host.nativeElement, { __ngt_dom_parent__: this.domElement });
49+
}
50+
51+
this.destroyRef.onDestroy(() => {
52+
delete (this.host.nativeElement as NgtAnyRecord)['__ngt_dom_parent__'];
53+
});
54+
}
55+
}

libs/core/src/lib/renderer/utils.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,6 @@ export const enum NgtRendererClassId {
1616
injectorFactory,
1717
}
1818

19-
// export function kebabToPascal(str: string): string {
20-
// // split the string at each hyphen
21-
// const parts = str.split('-');
22-
//
23-
// // map over the parts, capitalizing the first letter of each part
24-
// const pascalParts = parts.map((part) => part.charAt(0).toUpperCase() + part.slice(1));
25-
//
26-
// // join the parts together to create the final PascalCase string
27-
// return pascalParts.join('');
28-
// }
29-
3019
export function kebabToPascal(str: string): string {
3120
if (!str) return str; // Handle empty input
3221

libs/soba/controls/src/lib/scroll-controls.ts

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@ import {
33
afterNextRender,
44
ChangeDetectionStrategy,
55
Component,
6-
CUSTOM_ELEMENTS_SCHEMA,
7-
DestroyRef,
6+
Directive,
87
ElementRef,
98
inject,
109
input,
1110
model,
1211
untracked,
1312
} from '@angular/core';
14-
import { extend, HTML, injectBeforeRender, injectStore, NgtAnyRecord, pick } from 'angular-three';
13+
import { injectBeforeRender, injectStore, NgtHTML, pick, provideHTMLDomElement } from 'angular-three';
1514
import { easing } from 'maath';
1615
import { injectAutoEffect } from 'ngxtension/auto-effect';
1716
import { mergeInputs } from 'ngxtension/inject-inputs';
@@ -280,23 +279,14 @@ export class NgtsScrollControls {
280279
}
281280
}
282281

283-
@Component({
284-
selector: 'ngt-group[ngts-scroll-canvas]',
285-
standalone: true,
286-
template: `
287-
<ng-content />
288-
`,
289-
schemas: [CUSTOM_ELEMENTS_SCHEMA],
290-
changeDetection: ChangeDetectionStrategy.OnPush,
291-
})
282+
@Directive({ selector: 'ngt-group[ngts-scroll-canvas]', standalone: true })
292283
export class NgtsScrollCanvas {
293284
private host = inject<ElementRef<Group>>(ElementRef);
294285
private scrollControls = inject(NgtsScrollControls);
295286
private store = injectStore();
296287
private viewport = this.store.select('viewport');
297288

298289
constructor() {
299-
extend({ Group });
300290
injectBeforeRender(() => {
301291
const group = this.host.nativeElement;
302292

@@ -310,31 +300,18 @@ export class NgtsScrollCanvas {
310300
}
311301
}
312302

313-
@Component({
303+
@Directive({
314304
selector: 'div[ngts-scroll-html]',
315305
standalone: true,
316-
template: `
317-
<ng-content />
318-
`,
319-
changeDetection: ChangeDetectionStrategy.OnPush,
320-
host: {
321-
style: 'position: absolute; top: 0; left: 0; will-change: transform;',
322-
},
306+
host: { style: 'position: absolute; top: 0; left: 0; will-change: transform;' },
307+
providers: [provideHTMLDomElement([NgtsScrollControls], (scrollControls) => scrollControls.fixed)],
323308
})
324-
export class NgtsScrollHtml {
325-
static [HTML] = true;
326-
309+
export class NgtsScrollHtml extends NgtHTML {
327310
private scrollControls = inject(NgtsScrollControls);
328-
private host = inject<ElementRef<HTMLDivElement>>(ElementRef);
329-
private store = injectStore();
330311
private size = this.store.select('size');
331312

332313
constructor() {
333-
// assigning dom parent so that the Renderer knows where to attach the element
334-
Object.assign(this.host.nativeElement, {
335-
__ngt_dom_parent__: this.scrollControls.fixed,
336-
});
337-
314+
super();
338315
injectBeforeRender(() => {
339316
if (this.scrollControls.delta > this.scrollControls.eps()) {
340317
this.host.nativeElement.style.transform = `translate3d(${
@@ -344,9 +321,5 @@ export class NgtsScrollHtml {
344321
}px,${this.scrollControls.horizontal() ? 0 : this.size().height * (this.scrollControls.pages() - 1) * -this.scrollControls.offset}px,0)`;
345322
}
346323
});
347-
348-
inject(DestroyRef).onDestroy(() => {
349-
delete (this.host.nativeElement as NgtAnyRecord)['__ngt_dom_parent__'];
350-
});
351324
}
352325
}

libs/soba/src/controls/scroll-controls.stories.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ChangeDetectionStrategy, Component, CUSTOM_ELEMENTS_SCHEMA, input, signal, Signal } from '@angular/core';
22
import { Meta } from '@storybook/angular';
3-
import { HTML, injectStore, NgtSize } from 'angular-three';
3+
import { injectStore, NgtHTML } from 'angular-three';
44
import {
55
NgtsScrollCanvas,
66
NgtsScrollControls,
@@ -82,13 +82,10 @@ class Suzanne {
8282
mes.
8383
</h1>
8484
`,
85-
8685
changeDetection: ChangeDetectionStrategy.OnPush,
8786
})
88-
class HtmlContent {
89-
static [HTML] = true;
90-
91-
canvasSize = input.required<NgtSize>();
87+
class HtmlContent extends NgtHTML {
88+
canvasSize = this.store.select('size');
9289
}
9390

9491
@Component({
@@ -102,7 +99,7 @@ class HtmlContent {
10299
</ngt-group>
103100
104101
<div ngts-scroll-html style="width: 100%; color: #ec2d2d">
105-
<scroll-html-content [canvasSize]="canvasSize()" />
102+
<scroll-html-content />
106103
</div>
107104
</ngts-scroll-controls>
108105
`,

0 commit comments

Comments
 (0)