Particle Targets

June 11, 2014 · View on GitHub

A gallery for images and models rendered as particles with three.js

Demo

Dependencies

  • three.js - A Javascript 3D Library
  • WebGL Enabled Browser

Usage

Download the minified script as well as a copy of three.js and include it in your markup.

<script src="js/three.min.js"></script>
<script src="js/particlesaga.min.js"></script>

To prepare ParticleSaga scene you'll then need to define a set of targets (images and/or models) to map the particles to.

var targets = [
  {
    type: ParticleSaga.ImageTarget,
    url: 'images/excellent.png',
    options: {
      size: 3
    }
  }, {
    type: ParticleSaga.ModelTarget,
    url: 'models/unicorn.json',
    options: {
      color: {
        r: 0.8,
        g: 1,
        b: 1
      },
      scale: 1.5,
      size: 3,
      respondsToMouse: true
    }
  }
];

Next you just need to instantiate a scene with this target data and then either start a slideshow or control the sequence manually.

// The scene's context element contains the canvas
var saga = document.getElementById('saga');
		
var scene = new ParticleSaga.Scene(saga, targets, {
  numParticles: 40000,
  sort: ParticleSaga.VertexSort.leftToRight
});
    
// init will make all targets begin loading assets
// and create everything else needed in the scene.      
scene.load(function() {
  scene.setTarget(0);
  scene.startSlideshow();
});

Particle Targets

All targets need to be defined in with json and passed into the scene constructor. The definition consists of the target type, an asset URL, and a set of options. Optionally you can include a container element to assist with sizing and positioning of the particle display - the scene's context element will be used by default.

ImageTarget

ImageTargets generate particles in the XY plane based on random non-transparent pixels. The particles are scaled to fill the container using an aspect-fill scaling.

For best results you should use a high-contrast image with transparent negative space and a lot of padding around content you don't want to have cropped since it's going to be scaled to fill the container.

Example definition:

{
  type: ParticleSaga.ImageTarget,
  url: 'images/excellent.png',
  options: {
    size: 3
  }
}

Attributes

PropertyTypeDescription
typeValue must be ParticleSaga.ImageTargetThe target class (must extend ParticleSaga.AbstractTarget)
urlStringPath to the image
containerElementElement to constrain position of target with. Default is the scene's context
optionsPlainObjectOptions list to override default values described below

Options

PropertyTypeDescription
respondsToMouseBooleanWhether or not to rotate the particle system along with the mouse position. Default is false
sizeNumberSets the size of the particles. Default is 1.0

ModelTarget

ModelTargets load a json mesh file using a THREE.JSONLoader. You can find model exporters here.

Example definition:

{
  type: ParticleSaga.ModelTarget,
  url: 'models/unicorn.json',
  options: {
    color: {
      r: 0.8,
      g: 1,
      b: 1
    },
    initialMatrices: [
      new THREE.Matrix4().makeTranslation(0, -2, 0),
      new THREE.Matrix4().makeRotationY(Math.PI/2)
    ],
    respondsToMouse: true,
    scale: 1.5,
    size: 3
  }
}

Optimization: If you inspect the models used in the examples you'll notice that a lot of data have been stripped out since we only really need the vertices here.

Attributes

PropertyTypeDescription
typeValue must be ParticleSaga.ModelTargetThe target class (must extend ParticleSaga.AbstractTarget)
urlStringPath to the model json
optionsPlainObjectOptions list to override default values described below

Options

PropertyTypeDescription
colorPlainObject containing r, g, and b properties with 0-1 values
Ex/ {r: 0.5, g: 0.9, b: 1}
Particle colors
initialMatricesArray.<THREE.Matrix4>Initial transformations applied to the imported geometry. Default is []
respondsToMouseBooleanWhether or not to rotate the particle system along with the mouse position. Default is false
scaleNumberScales the intial geometry by this value. Default is 1.0
sizeNumberSets the size of the particles. Default is 1.0

MultiTarget

MultiTargets can combine a list of other targets into a single geometry to display with the main scene's particles.

Example definition:

{
  type: ParticleSaga.MultiTarget,
  container: document.getElementById('multitarget-references'),
  options: {
    size: 3
  },
  targets: [
    {
      type: ParticleSaga.ModelTarget,
      url: 'models/unicorn.json',
      container: document.getElementById('unicorn-multitarget-reference'),
      options: {
        scale: 1.2,
        color: {
          r: 0.8,
          g: 1,
          b: 0.2
        }
      }
    }, {
      type: ParticleSaga.ImageTarget,
      url: 'images/excellent.png',
      container: document.getElementById('excellent-multitarget-reference')
    }
  ]
}

Optimization: If you inspect the models used in the examples you'll notice that a lot of data have been stripped out since we only really need the vertices here.

Attributes

PropertyTypeDescription
typeValue must be ParticleSaga.MultiTargetThe target class (must extend ParticleSaga.AbstractTarget)
containerElementElement to constrain position of target with. Default is the scene's context
optionsPlainObjectOptions list to override default values described below
targetsArrayList of targets mostly identical to those above, however some properties such as size will be inherited from the MultiTarget's options instead

Options

PropertyTypeDescription
colorPlainObject containing r, g, and b properties with 0-1 values
Ex/ {r: 0.5, g: 0.9, b: 1}
Default particle colors - will be overridden by any specified model target color in the nested targets array.
respondsToMouseBooleanWhether or not to rotate the particle system along with the mouse position. Default is false
sizeNumberSets the size of the particles. Default is 1.0

Scene

The scene is the top level object that you'll be interacting with after declaring your targets in order to control the gallery.

Paramters

Attributes

PropertyTypeDescription
contextElementThe element to append canvas to and to derive max sizing from
targetsArrayList of targets as defined above
optionsPlainObjectOptions list to override default values described below

Options

PropertyTypeDescription
fovNumberCamera field of view degrees. Default is 45
maxMouseRotationNumberMax radians the mouse position can rotate the particle system's about the y-axis by in either direction. Default is π/6
mouseRotationFrictionNumberRatio of decay for how quickly the particle system will catch up to the mouse triggered rotation. Default is 0.2
numFloatingParticlesNumberNumber of particles that will appear in a random position rather than attached to a target. Default is 40
numParticlesNumberNumber of particles rendered on screen. Note that this does not have to match any other particle/vertex count - they will be evenly distributed or repeated as necessary. Default is 10000
particleRevertDelayNumberDelay in milliseconds for each particle to begin morph. Default is 0.01
revertDurationNumberMorph duration in milliseconds for each particle. Default is 800
sizeAttenuationBooleanSpecify whether particles' size will get smaller with the distance. Default is true.
slideshowDurationNumberDuration in milliseconds between each slide if slideshow is enabled. Default is 5000
sortFunctionJavascript (a, b) sort method to be applied to each target's vertices initially. See VertexSort.coffee for some quick options. Default is null

API

MethodParamsDescription
load(optional)
onAssetsLoad {Function}
Triggers loading of all initial targets with optional callback
loadTargettarget {PlainObject}, onLoad {Function}Load an individual target with an optional callback. This can also be used to load targets beyond the initial ones
destroyHalts all animation and attempts to dump all references (also calls relevant three.js dispose methods on scene children)
setTargetindex {Integer}
animated {Boolean} (default=true)
Morph to the target you supplied at that index
nextTargetanimated {Boolean} (default=true)Morph to next target (wraps around)
prevTargetanimated {Boolean} (default=true)Morph to previous target (wraps around)
startSlideshowStart interval going through each target
stopSlideshowStops interval going through each target

Build

Requires Grunt and related dependencies (Node.js and npm).

After satisfying those requirements you can install the project-specific dependencies and build as follows:

$ cd path/to/particle-saga
$ npm install
$ grunt deploy

Inspiration

Special thanks to Eric Moncada, Jeff Yamada, Brijan Powell, and Impossible Bureau. This originally came about while working on our ever-upcoming website where we wanted to showcase our team using individual models that Eric made after scanning us all with a Kinect, and then the idea of intertwining these with images came through Brijan's designs.

Example Artwork:

3D models used in examples extracted from originals by izuzf (Helm) and simon_k (Gryphon)

Images used in examples come from Wikimedia Commons Olav den helliges saga, Pomerania coat of arms