src/initializer/BodySprite.js
import {
DEFAULT_JSON_MATERIAL_PROPERTIES,
DEFAULT_MATERIAL_PROPERTIES,
SUPPORTED_MATERIAL_BLENDING_MODES,
} from './constants';
import Initializer from './Initializer';
import { INITIALIZER_TYPE_BODY_SPRITE as type } from './types';
import { withDefaults } from '../utils';
/**
* Sets the body property to be a THREE.Sprite on initialized particles.
*
* NOTE The texture map MUST be set on the SpriteMaterial in the TextureLoader.load
* callback. Not doing so will cause WebGL buffer errors.
*/
export default class BodySprite extends Initializer {
/**
* Constructs a BodySprite initializer.
*
* @param {object} THREE - The Web GL API we are using eg., THREE
* @param {string} texture - The sprite texture
* @param {object} materialProperties - The sprite material properties
* @throws {Error} If the TextureLoader fails to load the supplied texture
* @return void
*/
constructor(
THREE,
texture,
materialProperties = DEFAULT_MATERIAL_PROPERTIES,
isEnabled = true
) {
super(type, isEnabled);
const { Sprite, SpriteMaterial, TextureLoader } = THREE;
/**
* @desc The material properties for this object's SpriteMaterial
* NOTE This is required for testing purposes
* @type {object}
*/
this.materialProperties = withDefaults(
DEFAULT_MATERIAL_PROPERTIES,
materialProperties
);
new TextureLoader().load(
texture,
map => {
/**
* @desc The texture for the THREE.SpriteMaterial map.
* @type {Texture}
*/
this.texture = map;
/**
* @desc THREE.SpriteMaterial instance.
* @type {SpriteMaterial}
*/
this.material = new SpriteMaterial({
...{ map },
...this.materialProperties,
});
/**
* @desc THREE.Sprite instance.
* @type {Sprite}
*/
this.sprite = new Sprite(this.material);
},
undefined,
error => {
throw new Error(error);
}
);
}
/**
* Sets the particle body to the sprite.
*
* @param {Particle} particle - The particle to set the body of
* @return void
*/
initialize(particle) {
particle.body = this.sprite;
}
/**
* Creates a BodySprite initializer from JSON.
*
* @param {object} json - The JSON to construct the instance from
* @param {object} THREE - The Web GL API we are using eg., THREE
* @param {string} json.texture - The sprite texture
* @param {object} json.materialProperties - The sprite material properties
* @return {BodySprite}
*/
static fromJSON(json, THREE) {
const {
texture,
materialProperties = DEFAULT_JSON_MATERIAL_PROPERTIES,
isEnabled = true,
} = json;
const ensureMappedBlendingMode = properties => {
const { blending } = properties;
return {
...properties,
blending: blending
? SUPPORTED_MATERIAL_BLENDING_MODES[blending]
: SUPPORTED_MATERIAL_BLENDING_MODES[
DEFAULT_JSON_MATERIAL_PROPERTIES.blending
],
};
};
return new BodySprite(
THREE,
texture,
withDefaults(
DEFAULT_JSON_MATERIAL_PROPERTIES,
ensureMappedBlendingMode(materialProperties)
),
isEnabled
);
}
}