Based on your working HTML code and the need to use it in Angular TypeScript, here's how to properly import and use TextureAtlas in Pixi v8 + Spine v8:
TypeScript Import
The key is to import TextureAtlas from the spine-pixi package:
import * as PIXI from 'pixi.js';
import { Spine, SpineTexture, TextureAtlas } from '@esotericsoftware/spine-pixi-v8';
Complete Angular/TypeScript Implementation
Here's your working code adapted for TypeScript:
import { Component, OnInit } from '@angular/core';
import * as PIXI from 'pixi.js';
import { Spine, SpineTexture, TextureAtlas } from '@esotericsoftware/spine-pixi-v8';
@Component({
selector: 'app-spine-viewer',
template: '<div #spineContainer></div>'
})
export class SpineViewerComponent implements OnInit {
async ngOnInit() {
await this.loadSpineAnimation();
}
private async loadSpineAnimation(): Promise<void> {
// Initialize PIXI Application
const app = new PIXI.Application();
await app.init({
backgroundAlpha: 0,
resizeTo: window
});
// Append canvas to your container
const container = document.getElementById('app');
if (container) {
container.appendChild(app.canvas);
}
// File URLs
const JSON_URL = 'assets/spine/test.json';
const ATLAS_URL = 'assets/spine/test.atlas';
const PNG_URL = 'assets/spine/test/test.png';
try {
// 1) Load skeleton JSON manually
const skeletonResponse = await fetch(JSON_URL);
const skeletonJson = await skeletonResponse.json();
PIXI.Assets.cache.set('skeleton', skeletonJson);
// 2) Load atlas text manually
const atlasResponse = await fetch(ATLAS_URL);
const atlasText = await atlasResponse.text();
// 3) Load external PNG texture
const pixiTexture = await PIXI.Assets.load(PNG_URL);
// 4) Create TextureAtlas (prevents placeholder.png fetch)
const textureAtlas = new TextureAtlas(atlasText);
// 5) Replace atlas page textures with your external PNG
for (const page of textureAtlas.pages) {
// The page.name should match the first line in your .atlas file
page.setTexture(SpineTexture.from(pixiTexture.source));
}
PIXI.Assets.cache.set('atlas', textureAtlas);
// 6) Create Spine object
const spineObj = Spine.from({
skeleton: 'skeleton',
atlas: 'atlas',
scale: 1
});
// 7) Set animation and positioning
if (spineObj.skeleton.data.animations.length > 0) {
spineObj.state.setAnimation(
0,
spineObj.skeleton.data.animations[0].name,
true
);
}
spineObj.x = app.renderer.width / 2;
spineObj.y = app.renderer.height * 0.9;
app.stage.addChild(spineObj);
} catch (error) {
console.error('Error loading Spine animation:', error);
}
}
}
Alternative: Using HttpClient (Angular Way)
If you prefer using Angular's HttpClient:
import { HttpClient } from '@angular/common/http';
import { firstValueFrom } from 'rxjs';
constructor(private http: HttpClient) {}
private async loadSpineAnimation(): Promise<void> {
const app = new PIXI.Application();
await app.init({ backgroundAlpha: 0, resizeTo: window });
const container = document.getElementById('app');
if (container) {
container.appendChild(app.canvas);
}
// Load with HttpClient
const skeletonJson = await firstValueFrom(
this.http.get('assets/spine/test.json')
);
const atlasText = await firstValueFrom(
this.http.get('assets/spine/test.atlas', { responseType: 'text' })
);
PIXI.Assets.cache.set('skeleton', skeletonJson);
const pixiTexture = await PIXI.Assets.load('assets/spine/test/test.png');
const textureAtlas = new TextureAtlas(atlasText);
for (const page of textureAtlas.pages) {
page.setTexture(SpineTexture.from(pixiTexture.source));
}
PIXI.Assets.cache.set('atlas', textureAtlas);
const spineObj = Spine.from({
skeleton: 'skeleton',
atlas: 'atlas',
scale: 1
});
if (spineObj.skeleton.data.animations.length > 0) {
spineObj.state.setAnimation(0, spineObj.skeleton.data.animations[0].name, true);
}
spineObj.x = app.renderer.width / 2;
spineObj.y = app.renderer.height * 0.9;
app.stage.addChild(spineObj);
}
Key Points
- Import
TextureAtlas from @esotericsoftware/spine-pixi-v8
- The
TextureAtlas constructor prevents automatic loading of placeholder images
- Use
SpineTexture.from() to wrap the PIXI texture for Spine
- Ensure your asset paths are correct (typically in the
assets folder for Angular)
- The approach is the same as your working HTML code, just with proper TypeScript imports
This should resolve your issue with loading external textures as placeholder replacements in your Angular TypeScript project!