|
| 1 | +import { CUSTOM_ELEMENTS_SCHEMA, Component, Input } from '@angular/core'; |
| 2 | +import { NgtArgs, NgtSignalStore, extend, injectNgtRef } from 'angular-three'; |
| 3 | +import { GridMaterial } from 'angular-three-soba/shaders'; |
| 4 | +import * as THREE from 'three'; |
| 5 | +import { Mesh, PlaneGeometry } from 'three'; |
| 6 | + |
| 7 | +extend({ Mesh, GridMaterial, PlaneGeometry }); |
| 8 | + |
| 9 | +export interface NgtsGridState { |
| 10 | + /** Cell size, default: 0.5 */ |
| 11 | + cellSize: number; |
| 12 | + /** Cell thickness, default: 0.5 */ |
| 13 | + cellThickness: number; |
| 14 | + /** Cell color, default: black */ |
| 15 | + cellColor: THREE.ColorRepresentation; |
| 16 | + /** Section size, default: 1 */ |
| 17 | + sectionSize: number; |
| 18 | + /** Section thickness, default: 1 */ |
| 19 | + sectionThickness: number; |
| 20 | + /** Section color, default: #2080ff */ |
| 21 | + sectionColor: THREE.ColorRepresentation; |
| 22 | + /** Follow camera, default: false */ |
| 23 | + followCamera: boolean; |
| 24 | + /** Display the grid infinitely, default: false */ |
| 25 | + infiniteGrid: boolean; |
| 26 | + /** Fade distance, default: 100 */ |
| 27 | + fadeDistance: number; |
| 28 | + /** Fade strength, default: 1 */ |
| 29 | + fadeStrength: number; |
| 30 | + /** Material side, default: THREE.BackSide */ |
| 31 | + side: THREE.Side; |
| 32 | + /** Default plane-geometry arguments */ |
| 33 | + args?: ConstructorParameters<typeof THREE.PlaneGeometry>; |
| 34 | +} |
| 35 | + |
| 36 | +@Component({ |
| 37 | + selector: 'ngts-grid', |
| 38 | + standalone: true, |
| 39 | + template: ` |
| 40 | + <ngt-mesh ngtCompound [ref]="gridRef" [frustumCulled]="false"> |
| 41 | + <ngt-grid-material |
| 42 | + [transparent]="true" |
| 43 | + [side]="gridSide()" |
| 44 | + [cellSize]="gridCellSize()" |
| 45 | + [sectionSize]="gridSectionSize()" |
| 46 | + [cellColor]="gridCellColor()" |
| 47 | + [sectionColor]="gridSectionColor()" |
| 48 | + [cellThickness]="gridCellThickness()" |
| 49 | + [sectionThickness]="gridSectionThickness()" |
| 50 | + [fadeDistance]="gridFadeDistance()" |
| 51 | + [fadeStrength]="gridFadeStrength()" |
| 52 | + [infiniteGrid]="gridInfiniteGrid()" |
| 53 | + [followCamera]="gridFollowCamera()" |
| 54 | + /> |
| 55 | + <ngt-plane-geometry *args="gridArgs()" /> |
| 56 | + </ngt-mesh> |
| 57 | + `, |
| 58 | + imports: [NgtArgs], |
| 59 | + schemas: [CUSTOM_ELEMENTS_SCHEMA], |
| 60 | +}) |
| 61 | +export class NgtsGrid extends NgtSignalStore<NgtsGridState> { |
| 62 | + @Input() gridRef = injectNgtRef<THREE.Mesh>(); |
| 63 | + @Input() set cellSize(cellSize: NgtsGridState['cellSize']) { |
| 64 | + this.set({ cellSize }); |
| 65 | + } |
| 66 | + |
| 67 | + @Input() set cellThickness(cellThickness: NgtsGridState['cellThickness']) { |
| 68 | + this.set({ cellThickness }); |
| 69 | + } |
| 70 | + |
| 71 | + @Input() set cellColor(cellColor: NgtsGridState['cellColor']) { |
| 72 | + this.set({ cellColor }); |
| 73 | + } |
| 74 | + |
| 75 | + @Input() set sectionSize(sectionSize: NgtsGridState['sectionSize']) { |
| 76 | + this.set({ sectionSize }); |
| 77 | + } |
| 78 | + |
| 79 | + @Input() set sectionThickness(sectionThickness: NgtsGridState['sectionThickness']) { |
| 80 | + this.set({ sectionThickness }); |
| 81 | + } |
| 82 | + |
| 83 | + @Input() set sectionColor(sectionColor: NgtsGridState['sectionColor']) { |
| 84 | + this.set({ sectionColor }); |
| 85 | + } |
| 86 | + |
| 87 | + @Input() set followCamera(followCamera: NgtsGridState['followCamera']) { |
| 88 | + this.set({ followCamera }); |
| 89 | + } |
| 90 | + |
| 91 | + @Input() set infiniteGrid(infiniteGrid: NgtsGridState['infiniteGrid']) { |
| 92 | + this.set({ infiniteGrid }); |
| 93 | + } |
| 94 | + |
| 95 | + @Input() set fadeDistance(fadeDistance: NgtsGridState['fadeDistance']) { |
| 96 | + this.set({ fadeDistance }); |
| 97 | + } |
| 98 | + |
| 99 | + @Input() set fadeStrength(fadeStrength: NgtsGridState['fadeStrength']) { |
| 100 | + this.set({ fadeStrength }); |
| 101 | + } |
| 102 | + |
| 103 | + @Input() set side(side: NgtsGridState['side']) { |
| 104 | + this.set({ side }); |
| 105 | + } |
| 106 | + |
| 107 | + @Input() set args(args: NgtsGridState['args']) { |
| 108 | + this.set({ args }); |
| 109 | + } |
| 110 | + |
| 111 | + readonly gridCellSize = this.select('cellSize'); |
| 112 | + readonly gridSectionSize = this.select('sectionSize'); |
| 113 | + readonly gridFadeDistance = this.select('fadeDistance'); |
| 114 | + readonly gridFadeStrength = this.select('fadeStrength'); |
| 115 | + readonly gridCellThickness = this.select('cellThickness'); |
| 116 | + readonly gridSectionThickness = this.select('sectionThickness'); |
| 117 | + readonly gridInfiniteGrid = this.select('infiniteGrid'); |
| 118 | + readonly gridFollowCamera = this.select('followCamera'); |
| 119 | + readonly gridCellColor = this.select('cellColor'); |
| 120 | + readonly gridSectionColor = this.select('sectionColor'); |
| 121 | + readonly gridSide = this.select('side'); |
| 122 | + readonly gridArgs = this.select('args'); |
| 123 | + |
| 124 | + constructor() { |
| 125 | + super({ |
| 126 | + cellSize: 0.5, |
| 127 | + sectionSize: 1, |
| 128 | + fadeDistance: 100, |
| 129 | + fadeStrength: 1, |
| 130 | + cellThickness: 0.5, |
| 131 | + sectionThickness: 1, |
| 132 | + infiniteGrid: false, |
| 133 | + followCamera: false, |
| 134 | + cellColor: '#000000', |
| 135 | + sectionColor: '#2080ff', |
| 136 | + side: THREE.BackSide, |
| 137 | + args: [1, 1, 1], |
| 138 | + }); |
| 139 | + } |
| 140 | +} |
0 commit comments