Framework entegrasyonları · Angular + Three
Şablon → Object3D Haritası: İki Ağacın Diplomasisi
Angular görünüm ağacı ile Three Object3D ağacı aynı şey değildir. Bu sayfa şablon / bileşen girdilerinin sahne grafına nasıl bağlandığını anlatır: HTML semantiği değil · Three ↔ Angular eşleme.
Holodepth bu yaprağı Angular template sözdizimi dersi veya R3F JSX katalog turunun kopyası olarak yazmaz. R3F haritası Deklaratif sahne grafı yaprağındadır (JSX intrinsikleri). Host kapısı Host & kök sözleşmesi yaprağındadır. Object3D matematik teorisi Three omurgasındadır. NgZone karesi sonraki Angular yaprağındadır. glTF node spekü format izleklerindedir.
Sayfayı bitirdiğinizde şu cümleyi kurabilmelisiniz: «Angular view ile Object3D iki ayrı ağaçtır. @Input sahne alanına bilinçli yazılır. @for kimliği remount üretebilir. İç içe host bileşenleri group diplomasisidir. Şablonda görünmez etmek ile grafıtan düşürmek farklıdır. Sonraki kapı kare döngüsü & NgZone'dur.»
Bu sayfanın sınırı · komşu konularla ayrım
Bu sayfa Angular + Three'de şablon → Object3D haritasını anlatır:
- İki ağaç diplomasisi · input → alan yazımı
- Liste kimliği / remount · iç içe bileşen = group
- visible vs remove · kütüphane yapı taşı sınırı
- Üç yazım profili
Bilinçli olarak dışarıda bırakılan konular:
- Host / ElementRef / SSR → Host & kök sözleşmesi
- R3F JSX katalog / args / attach → R3F · Deklaratif sahne grafı
- NgZone / rAF → Kare döngüsü & NgZone
- OnDestroy dispose → Yükleme & OnDestroy
- Pointer bağları → Pointer bağları & picking
- Angular template 101 · glTF şema · Three Object3D matematik
Kısa ayrım: Bu sayfa «şablon sahneye nasıl map olur?» · R3F deklaratif «JSX kataloğa nasıl map olur?» · Host «kapı nerede?» · NgZone «map sonrası kim her kare iter?».
İki ağaç: view ve Object3D
Angular, bileşen/şablon ağacını change detection ile yaşatır. Three,
Scene altındaki Object3D parent zincirini render eder. Holodepth:
şablonda «iç içe yazmak» otomatik parent zinciri demek değildir;
siz (veya kütüphane) add / group bileşeni ile bağı
kurarsınız.
R3F bu bağı reconciler ile gizler. Angular + Three'de bağ çoğu zaman açık veya ince sarmalayıcıdır. «Çalıştı» ile «hangi ağaçta yaşadı?» sorusunu ayırın.
Aynı ekranda iki soyağacı; karıştırmak yetim mesh üretir.
Üç yazım stili
Holodepth pratikte üç stil görür (ürün birini seçer):
- Servis merkezli: şablon yalnız canvas host; tüm Object3D TypeScript'te kurulur.
- Bileşen merkezli: her parça bir Angular component;
ngOnInit/view hazır olunca kendini scene'e ekler. - Kütüphane kataloglu: angular-three benzeri yapı taşları şablonda yer alır; altta yine Object3D üretilir.
Bu sayfa stilleri yarıştırmaz; harita disiplininin üçünde de geçerli olduğunu mühürler: kim parent, kim input yazar, kim destroy'da çıkar.
@Input → sahne alanı
Angular @Input() (veya input signal) DOM attribute'u
değildir; ürünün Object3D alanına köprüdür:
position, visible, renk, yoğunluk.
Holodepth: input değişimini her CD'de körce yeni Vector3 allocate
etmek GC üretir; mevcut nesneye set edin veya seyrek
güncelleyin.
| Girdi | Sahne etkisi | Tuzak |
|---|---|---|
| Konum / dönüş | position.set / quaternion |
Her CD yeni dizi → gürültü |
| Görünürlük | visible bayrağı |
Hâlâ raycast / maliyet taşıyabilir |
| Varlık kapısı | @if ile bileşeni yok et | Dispose unutulursa sızıntı |
R3F'deki args/attach üçlüsü JSX katalog dilidir. Angular'da eşdeğer soru: kurucu parametresi component input mu, yoksa serviste sabit mi?
İç içe bileşen = group diplomasi
Şablonda <app-assembly><app-part/></app-assembly>
yazmak, content projection ile çocukları DOM'a yerleştirir. Object3D
tarafında çocuk mesh'in parent'ı assembly group olmalı; aksi hâlde
dünya uzayında «kardeş gibi» uçuşurlar. Holodepth: montaj bileşeni
kendi THREE.Group'unu yaratır; çocuklar bu group'a
add eder (veya kütüphane bunu yapar).
Projection (ng-content) view ağacını düzenler; sahne
parent'ını otomatik vermez. İki ağaç diplomasisini burada unutmayın.
@for kimliği ve remount
@for (item of items; track item.id) Angular view
kimliğidir. Track bozulursa bileşen yeniden doğar; Object3D de çoğu
kalıpta yeniden yaratılır → flicker, state kaybı, dispose yükü.
Holodepth: track'i ürün kimliğine bağlayın; index track'i kalabalıkta
pahalıdır.
Binlerce benzer öğe için şablon döngüsü yerine instance kaçışı (Zone / performans yaprağı ve Three instancing) düşünülür. Bu sayfa eşik sinyalini koyar, matematiği açmaz.
Gizle ≠ grafıtan çıkar
visible = false çizimi kesebilir ama nesneyi grafta
tutar. @if (show) ile bileşeni yok etmek grafıtan düşürme
+ yaşam sonu demektir. Holodepth ürün cümlesi: geçici gizleme mi, ömür
sonu mu? Ikisini karıştırmak hem picking hem bellek sürprizi üretir.
Şablon yalan söyleyebilir; Object3D hâlâ oradadır.
CD'den sahneye itiş
Input değişince Object3D'yi güncellemek doğrudur; her CD turunda tüm sahneyi yeniden kurmak değildir. Holodepth: kurulum bir kez (view hazır), güncelleme diff ile. Sürekli itiş ve Zone maliyeti sonraki yaprakta derinleşir; burada yalnız «map ≠ her tur rebuild» kuralı mühürlenir.
Kütüphane yapı taşı sınırı
angular-three ve benzerleri R3F'ye yakın şablon katalogları sunabilir. Holodepth: yapı taşını ezber demeti saymayın; altında yine Object3D ve parent kuralı vardır. Katalog API'si değişebilir; iki ağaç diplomasisi kalır. Host sözleşmesini kütüphaneye tamamen teslim etmek teşhisi zorlaştırır.
Güvenli harita: simüle bağ
Örnekler öğretim amaçlıdır. Angular CLI / signal API varyantları öğretilmez. Host'ta bir Scene olduğu varsayılır.
Simüle · parça bileşeni group'a kendini ekler.
import {
Component, Input, OnChanges, OnDestroy, SimpleChanges,
} from '@angular/core'
import * as THREE from 'three'
@Component({
selector: 'app-part-node',
template: '', // Görünür DOM yok · yalnızca Object3D üretir
})
export class PartNodeComponent implements OnChanges, OnDestroy {
/** Ebeveyn Object3D (montaj group). Host / parent sağlar. */
@Input({ required: true }) parent!: THREE.Object3D
@Input() offset: [number, number, number] = [0, 0, 0]
@Input() selected = false
private mesh?: THREE.Mesh
private readonly mat = new THREE.MeshStandardMaterial({
color: '#9aa6b8', metalness: 0.2, roughness: 0.45,
})
ngOnChanges(changes: SimpleChanges): void {
if (!this.parent) return
if (!this.mesh) {
this.mesh = new THREE.Mesh(new THREE.BoxGeometry(1, 0.35, 0.6), this.mat)
this.mesh.name = 'part-node'
this.parent.add(this.mesh)
}
if (changes['offset'] && this.mesh) {
const [x, y, z] = this.offset
this.mesh.position.set(x, y, z)
}
if (changes['selected']) {
this.mat.color.set(this.selected ? '#5ec8ff' : '#9aa6b8')
}
}
ngOnDestroy(): void {
if (!this.mesh) return
this.parent?.remove(this.mesh)
this.mesh.geometry.dispose()
// Materyal paylaşımı varsa dispose politikası OnDestroy yaprağında.
this.mat.dispose()
this.mesh = undefined
}
}
Simüle · montaj group + şablon yerleştirme notu.
import { Component, Input, OnDestroy, OnInit } from '@angular/core'
import * as THREE from 'three'
/**
* Template örneği (ayrı dosyada):
* @for (p of parts; track p.id) {
* <app-part-node [parent]="group" [offset]="p.offset" [selected]="p.id === selectedId" />
* }
* track = ürün kimliği · index track kullanmayın.
*/
@Component({
selector: 'app-assembly',
templateUrl: './assembly.component.html',
})
export class AssemblyComponent implements OnInit, OnDestroy {
@Input({ required: true }) scene!: THREE.Scene
@Input() parts: { id: string; offset: [number, number, number] }[] = []
@Input() selectedId: string | null = null
/** Çocukların parent'ı · şablon [parent]="group" ile beslenir */
readonly group = new THREE.Group()
ngOnInit(): void {
this.group.name = 'assembly'
this.scene.add(this.group)
}
ngOnDestroy(): void {
this.scene.remove(this.group)
// Çocuk part'lar kendi ngOnDestroy ile çıkar.
}
}
Güvenlik: kullanıcı string'ini mesh.name / eval yolu
yapmayın. Offset dizilerini doğrulamadan GPU'ya yazmayın. @for
listesini kimliği belirsiz stringlerden üretmeyin.
Harita tuzakları
- DOM hiyerarşisi = parent sanmak: add unutulur.
- Her CD'de new Mesh: mezarlık.
- track index: yanlış remount.
- visible ile @if karışımı: tutarsız ömür.
- Paylaşılan materyal dispose: komşu ölür.
- Projection = otomatik group: yanılgı.
- R3F attach ezberi: Angular'da aynı API yok.
Üç harita profili
-
01 · Harita
Servis merkezli
- Şablon
- Yalnız host canvas
- Ağaç
- TS'te Scene kurumu
- Risk
- God-service şişmesi
-
02 · Harita
Parça bileşenleri
- Şablon
- @for + app-part-node
- Parent
- Group input zorunlu
- Risk
- track / remount
-
03 · Harita
Katalog kütüphane
- Şablon
- Yapı taşı etiketleri
- Disiplin
- İki ağacı yine bilin
- Risk
- Sihir sanmak
Holodepth perspektifleri
İki ağacı ayrı konuşun
View hiyerarşisi ile Object3D parent aynı cümlede varsayılmamalı.
Kur bir kez, güncelle diff ile
Her CD rebuild, Angular Three'nin klasik tuzaklarındandır.
track = ürün kimliği
Index track kalabalıkta pahalı ve yanıltıcıdır.
Teşhis maddeleri
- Parent Object3D bilinçli mi veriliyor?
- Input değişimi allocate mi, set mi?
- @for track ürün kimliği mi?
- visible vs @if politikası net mi?
- Projection sahne parent'ı sanılmış mı?
- Kurulum CD yağmuruna mı bağlanmış?
- Kütüphane soyutlaması teşhisi engelliyor mu?
- R3F attach veya glTF şema bu sayfaya sızmış mı?
Holodepth içgörüsü
«Şablonda yazdım ama sahnede yok» çoğu zaman CSS değil, iki ağaç diplomasisinin kopukluğudur. Önce parent'ı sorun, sonra input'u.
Sonraki kapı: kare & NgZone
Harita durağanı anlatır; canlı ürün her karede mutasyon ister. Sonraki sayfa Kare döngüsü & NgZone tik ile Zone vergisini anlatır. Yükleme / picking / kaçış sonraki yapraklardadır.