Attraction / Repulsion

Some fizz dix wiff free jay ese

by soulwire

HTML

<script src="https://raw.github.com/mrdoob/three.js/master/build/three.min.js"></script>
<script src="https://raw.github.com/soulwire/sketch.js/master/js/sketch.js"></script>
<div id="container"></div>

SCSS

html, body {
    overflow: hidden;
    margin: 0;
}

CoffeeScript

# requires:
# Three:  https://raw.github.com/mrdoob/three.js/master/build/three.min.js
# Sketch: https://raw.github.com/soulwire/sketch.js/master/js/sketch.js

class Particle extends THREE.Vector3

    constructor: ( @x = 0, @y = 0, @z = 0, @mass = 1.0, @behaviors = [], @fixed = no ) ->

        super

        @reset @x, @y, @z

    reset: ( @x = 0, @y = 0, @z = 0 ) ->

        @acc = new THREE.Vector3
        @vel = new THREE.Vector3

        @maxForce = random 5, 10
        @maxSpeed = random 5, 10

        # set a random initial velocity
        @randomise 0.2

    randomise: ( num ) ->

        @vel.x += random -num, num
        @vel.y += random -num, num
        @vel.z += random -num, num

    update: ->

        # apply behaviors
        behavior.apply @ for behavior in @behaviors

        # limit force
        @acc.setLength @maxForce if do @acc.length > @maxForce

        # apply force
        @vel.addSelf @acc

        # limit velocity
        @acc.setLength @maxSpeed if do @vel.length > @maxSpeed

        # apply velocity
        @.addSelf @vel

        # apply drag
        @vel.multiplyScalar 0.995

        # reset force
        @acc.set 0, 0, 0

class Attractor extends THREE.Vector3

    constructor: ( @x = 0, @y = 0, @z = 0, @strength = 5000, @color = 0xFF00FF ) ->
        
        super

        # create a mesh to visually debug the attractor
        geometry = new THREE.SphereGeometry 20, 12, 12
        material = new THREE.MeshLambertMaterial { color: @color }
        
        @mesh = new THREE.Mesh geometry, material
        @mesh.position = @

        @wiggle = random 0.001, 0.005

    update: ( now ) ->

        @x += 2 * sin now * @wiggle
        @y += 2 * cos now * @wiggle * 0.8

    apply: ( particle ) ->

        # delta between points
        delta = @.clone().subSelf particle

        # squared distance between points
        distanceSq = Math.max 1, do delta.lengthSq

        # this just respawns the particle when it gets close
       ...