Skip to content

Instantly share code, notes, and snippets.

@moonraker22
Last active June 10, 2023 15:27
Show Gist options
  • Save moonraker22/5588a904132efd514a3b5431889a8537 to your computer and use it in GitHub Desktop.
Save moonraker22/5588a904132efd514a3b5431889a8537 to your computer and use it in GitHub Desktop.
A set of behavior creator functions for three-nebula in typescript so you get type hinting in ts
import {
Alpha,
Attraction,
Collision,
Color,
CrossZone,
Force,
Gravity,
RandomDrift,
Repulsion,
Rotate,
Scale,
Spring,
Vector3D,
ease,
} from 'three-nebula'
// Default values
export const DEFAULT_LIFE = Infinity
export const DEFAULT_ATTRACITON_RADIUS = 1000
export const DEFAULT_ATTRACTION_FORCE_SCALAR = 100
export const DEFAULT_BEHAVIOUR_EASING = ease.easeLinear
export const DEFAULT_BEHAVIOUR_EASING_TYPE = 'easeLinear'
export const DEFAULT_RANDOM_DRIFT_DELAY = 0.03
export const PARTICLE_ALPHA_THRESHOLD = 0.002
export const PARTICLE_LENGTH_SQ_THRESHOLD = 0.000004
export const DEFAULT_CROSS_TYPE = 'dead'
type easing = (t: number) => number
/**
* Behaviour that applies an alpha transition effect to particles.
* Constructs an Alpha behaviour instance.
*
* @param {number} alphaA - The starting alpha value
* @param {?number} alphaB - The ending alpha value
* @param {number} life - The life of the behaviour
* @param {function} easing - The easing equation to use for transforms
* @param {boolean} [isEnabled=true] - Determines if the behaviour will be applied or not
* @return void
*/
interface AlphaProps {
alphaA: number
alphaB?: number
life?: number | undefined
easing?: string
isEnabled: boolean
}
export const createAlpha = ({
alphaA = 1,
alphaB = 0,
life = DEFAULT_LIFE,
easing = DEFAULT_BEHAVIOUR_EASING_TYPE,
isEnabled = true,
}: AlphaProps) => new Alpha(alphaA, alphaB, life, easing, isEnabled)
/**
* Behaviour that causes particles to be attracted to a target position.
* Constructs an Attraction behaviour instance.
*
* @param {Vector3D} targetPosition - The position the particles will be attracted to
* @param {number} force - The attraction force scalar multiplier
* @param {number} radius - The attraction radius
* @param {number} [life=DEFAULT_LIFE] - The life of the particle
* @param {function} [easing=DEFAULT_BEHAVIOUR_EASING] - The behaviour's decaying trend
* @param {boolean} [isEnabled=true] - Determines if the behaviour will be applied or not
* @return void
*/
interface AttractionProps {
targetPosition: Vector3D
force: number
radius: number
life?: number | undefined
easing?: typeof ease.easeLinear
isEnabled?: boolean
}
export const createAttraction = ({
targetPosition,
force,
radius,
life = DEFAULT_LIFE,
easing = ease.easeLinear,
isEnabled = true,
}: AttractionProps) =>
new Attraction(targetPosition, force, radius, life, easing, isEnabled)
/**
* Behaviour that causes particles to move away from other particles they collide with.
* Constructs a Collision behaviour instance.
*
* @param {Emitter} emitter - The emitter containing the particles to detect collisions against
* @param {boolean} useMass - Determiens whether to use mass or not
* @param {function} onCollide - Function to call when particles collide
* @param {number} life - The life of the particle
* @param {function} easing - The behaviour's decaying trend
* @param {boolean} [isEnabled=true] - Determines if the behaviour will be applied or not
* @return void
*/
interface CollisionProps {
emitter: any
useMass: boolean
onCollide: any
life?: number | undefined
easing: string
isEnabled: boolean
}
export const createCollision = ({
emitter,
useMass,
onCollide,
life = DEFAULT_LIFE,
easing = DEFAULT_BEHAVIOUR_EASING_TYPE,
isEnabled = true,
}: CollisionProps) =>
new Collision(emitter, useMass, onCollide, life, easing, isEnabled)
/**
* A behaviour which mutates the color of a particle over time.
* Constructs a Color behaviour instance.
*
* @param {number|string} colorA - the starting color
* @param {number|string} colorB - the ending color
* @param {number} life - the life of the particle
* @param {function} easing - The behaviour's decaying trend
* @param {boolean} [isEnabled=true] - Determines if the behaviour will be applied or not
* @return void
*/
interface ColorProps {
colorA: string
colorB: string
life?: number | undefined
easing: easing
isEnabled?: boolean
}
export const createColorShift = ({
colorA,
colorB,
life = DEFAULT_LIFE,
easing = ease.easeLinear,
isEnabled = true,
}: ColorProps) => new Color(colorA, colorB, life, easing, isEnabled)
/**
* Behaviour that allows for specific functions to be called on particles when
* they interact with a zone.
* Constructs a CrossZone behaviour instance.
*
* @param {Zone} zone - the zone used to apply to particles with this behaviour
* @param {string} [crossType=DEFAULT_CROSS_TYPE] - enum of cross types, valid strings include 'dead', 'bound', 'cross'
* @param {number} life - The life of the particle
* @param {function} easing - The behaviour's decaying trend
* @param {boolean} [isEnabled=true] - Determines if the behaviour will be applied or not
*/
interface CrossZoneProps {
zone: any // One of https://github.com/creativelifeform/three-nebula/tree/master/src/zone
crossType?: string
life?: number | undefined
easing?: easing
isEnabled?: boolean
}
export const createCrossZone = ({
zone,
crossType = DEFAULT_CROSS_TYPE,
life = DEFAULT_LIFE,
easing = ease.easeLinear,
isEnabled = true,
}: CrossZoneProps) => new CrossZone(zone, crossType, life, easing, isEnabled)
/**
* Behaviour that forces particles along a specific axis.
* Constructs a Force behaviour instance.
*
* @param {number} fx - the x axis force
* @param {number} fy - the y axis force
* @param {number} fz - the z axis force
* @param {number} life - the life of the particle
* @param {function} easing - The behaviour's decaying trend
* @param {boolean} [isEnabled=true] - Determines if the behaviour will be applied or not
* @return void
*/
interface ForceProps {
fx: number
fy: number
fz: number
life?: number | undefined
easing?: easing
isEnabled?: boolean
}
export const createForce = ({
fx,
fy,
fz,
life = DEFAULT_LIFE,
easing = ease.easeLinear,
isEnabled = true,
}: ForceProps) => new Force(fx, fy, fz, life, easing, isEnabled)
/**
* Behaviour that forces particles down the y axis.
* Constructs a Gravity behaviour instance.
*
* @param {number} gravity - the force to pull the particle down the y axis
* @param {number} life - the life of the particle
* @param {string} easing - the easing equation to use
* @param {boolean} [isEnabled=true] - Determines if the behaviour will be applied or not
* @return void
*/
interface GravityProps {
gravity: number
life?: number | undefined
easing?: typeof ease.easeLinear
isEnabled?: boolean
}
export const createGravity = ({
gravity,
life = DEFAULT_LIFE,
easing = DEFAULT_BEHAVIOUR_EASING,
isEnabled = true,
}: GravityProps) => new Gravity(gravity, life, easing, isEnabled)
/**
* Behaviour that causes particles to drift to random coordinates in 3D space.
* Constructs a RandomDrift behaviour instance.
*
* @param {number} driftX - x axis drift
* @param {number} driftY - y axis drift
* @param {number} driftZ - z axis drift
* @param {number} [delay=DEFAULT_RANDOM_DRIFT_DELAY] - drift delay
* @param {number} life - The life of the particle
* @param {function} easing - The behaviour's decaying trend
* @return void
*/
interface RandomDriftProps {
driftX: number
driftY: number
driftZ: number
delay?: number
life?: number | undefined
easing?: easing
}
export const createRandomDrift = ({
driftX,
driftY,
driftZ,
delay = DEFAULT_RANDOM_DRIFT_DELAY,
life = DEFAULT_LIFE,
easing = ease.easeLinear,
}: RandomDriftProps) =>
new RandomDrift(driftX, driftY, driftZ, delay, life, easing)
/**
* Behaviour that causes particles to be repelled from a target position.
* Constructs an Repulsion behaviour instance.
*
* @param {Vector3D} targetPosition - The position the particles will be repelled from
* @param {number} force - The repulsion force scalar multiplier
* @param {number} radius - The repulsion radius
* @param {number} life - The life of the particle
* @param {function} easing - The behaviour's decaying trend
* @return void
*/
interface RepulsionProps {
targetPosition: Vector3D
force: number
radius: number
life?: number | undefined
easing?: easing
}
export const createRepulsion = ({
targetPosition,
force,
radius,
life = DEFAULT_LIFE,
easing = ease.easeLinear,
}: RepulsionProps) => new Repulsion(targetPosition, force, radius, life, easing)
/**
* Behaviour that rotates particles.
* Constructs a Rotate behaviour instance.
*
* @param {number} x - X axis rotation
* @param {number} y - Y axis rotation
* @param {number} z - Z axis rotation
* @param {number} life - The life of the behaviour
* @param {function} easing - The easing equation to use for transforms
* @param {boolean} [isEnabled=true] - Determines if the behaviour will be applied or not
* @return void
*/
interface RotateProps {
x?: number | 'random'
y?: number | 'random'
z?: number | 'random'
life?: number | undefined
easing?: easing
isEnabled?: boolean
}
export const createRotate = ({
x,
y,
z,
life,
easing = ease.easeLinear,
isEnabled = true,
}: RotateProps) => new Rotate(x, y, z, life, easing, isEnabled)
/**
* Behaviour that scales particles.
* Constructs a Scale behaviour instance.
*
* @param {number} scaleA - the starting scale value
* @param {?number} scaleB - the ending scale value
* @param {number} life - the life of the behaviour
* @param {function} easing - the easing equation to use for transforms
* @param {boolean} [isEnabled=true] - Determines if the behaviour will be applied or not
* @return void
*/
interface ScaleProps {
scaleA: number
scaleB?: number
life?: number | undefined
easing?: easing
isEnabled?: boolean
}
export const createScale = ({
scaleA = 1,
scaleB,
life,
easing = ease.easeLinear,
isEnabled = true,
}: ScaleProps) => new Scale(scaleA, scaleB, life, easing, isEnabled)
/**
* Behaviour that causes particles to spring.
* Constructs a Spring behaviour instance.
*
* @param {number} x - X axis spring
* @param {number} y - Y axis spring
* @param {number} z - Z axis spring
* @param {number} spring - Spring factor
* @param {number} friction - Spring friction
* @param {number} life - The life of the behaviour
* @param {function} easing - The easing equation to use for transforms
* @param {boolean} [isEnabled=true] - Determines if the behaviour will be applied or not
* @return void
*/
interface SpringProps {
x: number
y: number
z: number
spring: number
friction: number
life?: number
easing?: easing
isEnabled?: boolean
}
export const createSpring = ({
x,
y,
z,
spring,
friction,
life = DEFAULT_LIFE,
easing = ease.easeLinear,
isEnabled = true,
}: SpringProps) =>
new Spring(x, y, z, spring, friction, life, easing, isEnabled)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment