cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-outspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External CSS

These stylesheets will be added in this order and before the code you write in the CSS editor. You can also add another Pen here, and it will pull the CSS from it. Try typing "font" or "ribbon" below.

Quick-add: + add another resource

Add External JavaScript

These scripts will run in this order and before the code in the JavaScript editor. You can also link to another Pen here, and it will run the JavaScript from it. Also try typing the name of any popular library.

Quick-add: + add another resource

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

            
              <div id=container>
	<div id="wrapper"></div>
	<div id="words">
		<p id="w1">My Sensitive Heart</p>
		<p id="w2">you are my guiding star</p>
		<p id="w3">my heart</p>
		<p id="w4">beats for you</p>
		<p id="w5">you send me</p>
		<p id="w6">into the sun</p>
		<p id="w7">into chaos</p>
		<p id="w8">i am all a'quiver!</p>
		<p id="w9">Play with me!<span>move your mouse</span></p>
	</div>
	<div id="UI">
		<div><strong>SHAPES:</strong></div>
			<ul>
				<li id="heart">heart</li>
				<li id="star">star</li>
				<li id="circle">circle</li>
				<li id="hallow">hallows</li>
				<li id="kiss">kiss</li>
			</ul>

		<div id="behaviours">
			<div><strong>BEHAVIOURS:</strong></div>
			<label for="wander">wander <span>(how far do you stray?)</span></label><br />
				<input id="wander" value="0.05" min="0.05" step="0.05" type="number"/><br />
			<label for="friction">friction <span>(f>1: faster, faster! f<1: slow....)</span></label><br />
				<input id="friction" value=".9" min="0.5" step="0.05" type="number"/><br />
			<label for="mouseDistance">mouse distance <span>(how far do you feel it?)</span>:</label><br />
				<input id="mouseDistance" value="100" min="0" step="5" type="number"/><br />
			<label for="mouseForce">mouse force <span>(how powerful is the effect!)</span></label><br />
				<input id="mouseForce" value="0.05" min="0" step="0.05" type="number"/><br />
			<label for="springForce">particle spring force: <span>(springy or bouncy (strict or flexible))</span></label><br />
				<input id="springForce" value="0.01" min="0" step="0.01" type="number"/><br />
		</div>
	</div>
</div>
            
          
!
            
              @import url('https://fonts.googleapis.com/css?family=Calligraffitti');
body{
	background-color: #000;
	font-family: Arial, Helvetica, sans-serif;
}
#container{
	position: relative;
}
#wrapper{
	width: 100%;
	position: absolute;
	text-align: center;
}
#words{
	pointer-events:none;
	font-family: 'Calligraffitti', cursive;
	position: absolute;
	width: 100%;
	padding: 200px 0 0 0;
	font-size: 2.8em;
	color: white;
	text-align: center;
}
#words p{
	display: none;
}
#words p#w1{
	display: block;
}
#words p span{
	display: block;
	font-size: .4em;
}
#UI{
	color: white;
	width: 200px;
	cursor: pointer;
	position: relative;
	display: none;
}
#behaviours{
	margin-top: 10px;
}
#behaviours label span{
	display: inline-block;
	font-size: .7em;
}
#behaviours input{
	width: 50px;
	margin-bottom: 10px;
	margin-top: -20px;
}
            
          
!
            
              var RUN_AS_ANIMATION=true,

wrapper, canvas, context, width=600, height=600, Tau=Math.PI*2,
systems=[],
mouseX=0, mouseY=0, repelMouse = true,
copyCount=1, sequenceCount=0, maxSequenceCount=22, sequenceDelay=2000,
orbitting=false, orbitAngle, orbitDegrees=0, orbitSpeed=1, orbitalRadius=10, PI180=Math.PI/180, orbitVX, orbitVY,
colourInterval,
repaintColour="rgba(0,0,0, .05)",
pathObjects=[];
pathObjects.push( {pLength:0, dom:null, pcStep:0, pt:null, id:"heart", shape:"M 209.95 88.4 Q 210 86.85 210 86.5 210 86.05 210 85.6 210.65 27.5 177.7 7.25 143.7 -13.75 104.9 26 66.3 -13.75 32.3 7.25 -1.85 28.2 0.1 89.75 2.05 151.35 104.9 230 207.95 151.35 209.9 89.75 209.9 89.05 209.95 88.4 Z"} ),
pathObjects.push( {pLength:0, dom:null, pcStep:0, pt:null, id:"star", shape:"M 0 115.05 L 81.35 86.25 83.55 0 136 68.5 218.7 43.95 169.8 115.05 218.7 186.1 136 161.55 83.55 230 81.35 143.8 0 115.05 Z"} ),
pathObjects.push( {pLength:0, dom:null, pcStep:0, pt:null, id:"circle", shape:"M 220 110 Q 220 155.6 187.75 187.8 155.6 220 110 220 64.4 220 32.15 187.8 0 155.6 0 110 0 64.4 32.15 32.2 64.4 0 110 0 155.6 0 187.75 32.2 220 64.4 220 110 Z"} ),
pathObjects.push( {pLength:0, dom:null, pcStep:0, pt:null, id:"smallHeart", shape:"M 174.15 97.5 Q 174.2 96.45 174.2 96.25 174.2 95.95 174.2 95.65 174.6 57.35 152.9 44.05 130.5 30.2 104.95 56.4 79.55 30.2 57.15 44.05 34.65 57.85 35.9 98.35 37.2 138.95 104.95 190.75 172.85 138.95 174.15 98.35 174.15 97.9 174.15 97.5 Z"} ),
pathObjects.push( {pLength:0, dom:null, pcStep:0, pt:null, id:"hallow", shape:"M 220 188.7 L 219.5 187.75 Q 219.25 188.25 219.05 188.7 L 220 188.7 Z M 219.5 187.75 L 107.3 0.95 107.3 63.075 Q 107.85 63.05 108.4 63.05 116.65 63.05 124.15 64.95 140.05 68.9 152.5 81.3 170.75 99.6 170.75 125.4 170.75 139.9 165 152.05 M 219.05 188.7 L 106.95 188.7 0 188.7 107 0.45 107.3 0.95 M 106.95 188.7 L 106.95 187.75 106.9 187.75 Q 82 187.25 64.3 169.5 46 151.25 46 125.4 46 111.2 51.55 99.3 56.1 89.5 64.3 81.3 82 63.55 106.9 63.1 L 106.95 63.1 Q 107.125 63.087890625 107.3 63.075 L 107.3 187.75 Q 107.480859375 187.75 107.65 187.75 108 187.75 108.4 187.75 134.2 187.75 152.5 169.5 160.3 161.7 164.75 152.5 M 107.3 187.75 Q 107.1302734375 187.75 106.95 187.75"} ),
pathObjects.push( {pLength:0, dom:null, pcStep:0, pt:null, id:"kiss", shape:"M 220 111.85 Q 219.6 112.1 219.2 112.35 187.4 131.35 162.3 153.55 141.15 172.15 110.5 173.35 79.15 172.4 57.8 153.55 32.6 131.3 0.6 112.2 0.3 112.05 0.05 111.85 M 219.2 112.35 Q 215.5 113.85 202.2 106.5 187.95 98.5 165 71 142.4 43.9 109.9 62.05 77.35 43.9 54.75 71 31.8 98.5 17.55 106.5 4.25 113.85 0.6 112.2 M 36.3 113.85 Q 65.95 119.15 84.55 120.75 109.25 111.8 130.8 120.05 151.35 118.9 179.7 113.85 M 84.55 120.75 Q 109.25 127.95 130.8 120.05"} ),


window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    ||
          window.oRequestAnimationFrame      ||
          window.msRequestAnimationFrame     ||
          function(callback, element){
            window.setTimeout(callback, 1000 / 60);
          };
})();

var ParticleSystem = function(id){
    Object.defineProperty(this, 'colour', { value:'#FF1515', writable:true });
    Object.defineProperty(this, 'friction', { value:.9, writable:true });                // f < 1 == slows;  f > 1 == speeds up
    Object.defineProperty(this, 'height', { value:100, writable:true });
    Object.defineProperty(this, 'id', { value:id, writable:true} );
    Object.defineProperty(this, 'maxSpeed', { value:10, writable:true });
    Object.defineProperty(this, 'mouseRepelDist', { value:100, writable:true });         // Size of repel circle
    Object.defineProperty(this, 'mouseForce', { value:.05, writable:true });             // dist particle moves when influenced by mouse. lower number: blends shape more: .05 - n
    Object.defineProperty(this, 'numParticles', { value:50, writable:true }); 
    Object.defineProperty(this, 'particles', { value:[], writable:true });
    Object.defineProperty(this, 'repelMouse', { value:true, writable:true });
    Object.defineProperty(this, 'springTo', { value:true, writable:true });
    Object.defineProperty(this, 'springForce', { value:.01, writable:true });           // speed of return to spring point. tightness
    Object.defineProperty(this, 'wandering', { value:true, writable:true });
    Object.defineProperty(this, 'wander', { value:.05, writable:true });                  // bigger number - fuzzier .05 just perceptible
    Object.defineProperty(this, 'wanderMod', { value:this.wander*.5, writable:true });
    Object.defineProperty(this, 'width', { value:100, writable:true });
    Object.defineProperty(this, 'x', { value:0, writable:true });
    Object.defineProperty(this, 'y', { value:0, writable:true });
}
ParticleSystem.prototype.setWander = function(value){ this.wander = value; this.wanderMod = value*.5 }

ParticleSystem.prototype.generate = function(){
    for(var j=0; j<pathObjects.length; j+=1){
        pathObjects[j].pcStep = pathObjects[j].pLength / this.numParticles;
    }
    var pShapeArrayX, pShapeArrayY;
    for(var i=0; i<this.numParticles; i++){
        // pass in pattern points
        pShapeArrayX = [];
        pShapeArrayY = [];
        for(var p=0; p<pathObjects.length; p+=1){
            pathObjects[p].pt = pathObjects[p].dom.getPointAtLength(i*pathObjects[p].pcStep);
            pShapeArrayX.push(pathObjects[p].pt.x + ((this.width-220)/2));
            pShapeArrayY.push(pathObjects[p].pt.y + ((this.height-230)/2));
        }
        var p = new Particle("p"+i, pShapeArrayX, pShapeArrayY, this);
        this.particles.push(p);
    }
}

ParticleSystem.prototype.update = function(){
    var particle;
    for(var i=0; i<this.numParticles; i++){
        particle = this.particles[i];
        particle.pUpdate();
    }
}

ParticleSystem.prototype.pShapeMorph = function(value){
    var particle;
    for(var i=0; i<this.numParticles; i++){
        particle = this.particles[i];
        particle.pChangeSpringPoint(value);
    }
}

var Particle = function(id, x, y, parentSystem){
    Object.defineProperty(this, 'id', { value:id, writable:true });
    Object.defineProperty(this, 'shapesX', { value:x, writable:true });
    Object.defineProperty(this, 'shapesY', { value:y, writable:true });
    Object.defineProperty(this, 'x', { value:this.shapesX[0], writable:true });
    Object.defineProperty(this, 'y', { value:this.shapesY[0], writable:true });
    Object.defineProperty(this, 'sx', { value:this.x, writable:true });
    Object.defineProperty(this, 'sy', { value:this.y, writable:true });
    Object.defineProperty(this, 'vx', { value:0, writable:true });
    Object.defineProperty(this, 'vy', { value:0, writable:true });
    Object.defineProperty(this, 'densityScore', { value:1, writable:true });
    Object.defineProperty(this, 'parentSystem', { value:parentSystem, writable:true });
    return this;
}

Particle.prototype.pChangeSpringPoint = function(value){
    // change spring point - causes morph
    if(value < 0) value = 0;
    if(value >= this.x.length) value = this.x.length-1;
    this.sx = this.shapesX[value];
    this.sy = this.shapesY[value];
}

Particle.prototype.pUpdate = function(){
    
    // randomise movement slightly
    if(this.parentSystem.wandering){
        this.vx += Math.random() * this.parentSystem.wander - this.parentSystem.wanderMod;
        this.vy += Math.random() * this.parentSystem.wander - this.parentSystem.wanderMod;
    }

    // apply friction
    this.vx *= this.parentSystem.friction;
    this.vy *= this.parentSystem.friction;

    // constrain to speed bounds
    var speed = Math.sqrt(this.vx*this.vx + this.vy*this.vy);
    if (speed > this.parentSystem.maxSpeed) {
        this.vx = this.parentSystem.maxSpeed * this.vx / speed;
        this.vy = this.parentSystem.maxSpeed * this.vy / speed;
    }

    // stay attached to point
    if(this.parentSystem.springTo){
        this.vx += (this.sx - this.x) * this.parentSystem.springForce;
        this.vy += (this.sy - this.y) * this.parentSystem.springForce;
    }

    // avoid the mouse
    if(this.parentSystem.repelMouse){
        var dx = mouseX - this.x;
        var dy = mouseY - this.y;
        var dist = Math.sqrt(dx*dx + dy*dy);
        if (dist < this.parentSystem.mouseRepelDist) {
            var tx = mouseX - this.parentSystem.mouseRepelDist * dx / dist;
            var ty = mouseY - this.parentSystem.mouseRepelDist * dy / dist;
            this.vx += (tx - this.x) * this.parentSystem.mouseForce;
            this.vy += (ty - this.y) * this.parentSystem.mouseForce;
        }
    }

    // update position
    this.x += this.vx;
    this.y += this.vy;
}

function get(id) {
    return document.getElementById(id);
}

function createCanvas(id, w, h){
    var tCanvas = document.createElement("canvas");
    tCanvas.width = w;
    tCanvas.height = h;
    tCanvas.id = id;
    return tCanvas;
}

function init(){
    var tPath;
    for(var i=0; i<pathObjects.length; i+=1){
        tPath = document.createElementNS('http://www.w3.org/2000/svg','path');
        tPath.setAttribute('d', pathObjects[i].shape);
        pathObjects[i].dom = tPath;
        pathObjects[i].pLength = tPath.getTotalLength();
    }

    wrapper = get("wrapper");
    canvas =  createCanvas("canvas", width, height);
    wrapper.appendChild(canvas);
    context = canvas.getContext("2d");

    /* Define new ParticleSystem and set values */
    var system1 = new ParticleSystem('pSys1');
    systems.push(system1);
    system1.width = width;
    system1.height = height;
    system1.maxSpeed = 3;
    system1.scalar = .3;
    system1.numParticles = 100;
    system1.x = 150;
    system1.y = 150;
    system1.setWander(1);
    system1.generate();
}

function update(){
    for(var i=0; i<systems.length; i++){
        systems[i].update();
    }
    if(orbitting){
        doOrbit();
    }
}

function draw(){
    var system;
    for(var i=0; i<systems.length; i++){
        system = systems[i];
        context.fillStyle = system.colour;
        var particle;
        for(var j=0; j<system.numParticles; j+=1) {
            particle = system.particles[j];
            context.beginPath();
            if(particle.densityScore > 0){
                context.arc(particle.x, particle.y, particle.densityScore, 0, Tau, false);
            }
            context.fill();
        }
    }
}

function animate(){
    context.fillStyle = repaintColour;
    context.fillRect(0, 0, width, height);
    update();
    draw();
    requestAnimFrame(animate);
}

function setUpEvents(){
    function getMousePos(canvas, evt) {
        var rect = canvas.getBoundingClientRect();
        return {
            x: evt.clientX - rect.left,
            y: evt.clientY - rect.top
        };
    }
    canvas.addEventListener('mousemove', function(evt) {
        var mousePos = getMousePos(canvas, evt);
        mouseX = mousePos.x;
        mouseY = mousePos.y;
    }, false);
}

function doOrbit(){
    orbitAngle = orbitDegrees * PI180;
    orbitDegrees += orbitSpeed;
    orbitVX = orbitalRadius * Math.cos(orbitAngle);
    orbitVY = orbitalRadius * Math.sin(orbitAngle);
    mouseX = orbitVX + width*.5;
    mouseY = orbitVY + height*.5;
    // expand orbit
    orbitSpeed*=1.003;
    orbitalRadius*=1.003;
}

function randomColour(){
    var r = Math.round(Math.random()*125)+130,
    g = Math.round(Math.random()*155)+100,
    b = Math.round(Math.random()*155)+100;
    return 'rgb('+r+','+g+','+b+')';
}

function clickHandler(evt){
    switch(evt.target.id){
        case "heart":
            systems[0].pShapeMorph(0);
            break;
        case "star":
            systems[0].pShapeMorph(1);
            break;
        case "circle":
            systems[0].pShapeMorph(2);
            break;
        case "hallow":
            systems[0].pShapeMorph(4);
            break;
        case "kiss":
            systems[0].pShapeMorph(5);
            break;
        case "wander":
            systems[0].setWander(evt.target.value);
            break;
        case "friction":
            systems[0].friction = evt.target.value;
            break;
        case "mouseDistance":
            systems[0].mouseRepelDist = evt.target.value;
            break;
        case "mouseForce":
            systems[0].mouseForce = evt.target.value;
            break;
        case "springForce":
            systems[0].springForce = evt.target.value;
            break;
        default:
            /* [[-_-]] */
    }
}

function enableUI(){
    get("heart").addEventListener("click", clickHandler, false);
    get("star").addEventListener("click", clickHandler, false);
    get("circle").addEventListener("click", clickHandler, false);
    get("hallow").addEventListener("click", clickHandler, false);
    get("kiss").addEventListener("click", clickHandler, false);

    get('wander').addEventListener("change", clickHandler, false);
    get('friction').addEventListener("change", clickHandler, false);
    get('mouseDistance').addEventListener("change", clickHandler, false);
    get('mouseForce').addEventListener("change", clickHandler, false);
    get('springForce').addEventListener("change", clickHandler, false);
    get('UI').style.display = "block";
}

function sequencer(){
    sequenceCount++;
    switch(sequenceCount){
        case 2:
            sequenceDelay=3000;
            systems[0].colour = '#CACAF8';
            get("w"+(copyCount++)).style.display="none";
            get("w"+copyCount).style.display="block";
            systems[0].pShapeMorph(1);
            break;
        case 3:
            sequenceDelay=3000;
            systems[0].colour = '#FF1515';
            get("w"+(copyCount++)).style.display="none";
            get("w"+copyCount).style.display="block";
            systems[0].pShapeMorph(0);
            break;
        case 4:
            sequenceDelay=500;
            systems[0].colour = '#69359c';
            systems[0].pShapeMorph(3);
            break;
        case 5:
            sequenceDelay=500;
            systems[0].colour = '#FF1515';
            systems[0].pShapeMorph(0);
            break;
        case 6:
            sequenceDelay=500;
            systems[0].colour = '#69359c';
            get("w"+(copyCount++)).style.display="none";
            get("w"+copyCount).style.display="block";
            systems[0].pShapeMorph(3);
            break;
        case 7:
            sequenceDelay=600;
            systems[0].colour = '#FF1515';
            systems[0].pShapeMorph(0);
            break;
        case 8:
            sequenceDelay=500;
            systems[0].colour = '#69359c';
            systems[0].pShapeMorph(3);
            break;
        case 9:
            sequenceDelay=1000;
            systems[0].colour = '#FF1515';
            systems[0].pShapeMorph(0);
            break;
        case 10:
            sequenceDelay=3500;
            systems[0].pShapeMorph(2);
            get("w"+(copyCount++)).style.display="none";
            get("w"+copyCount).style.display="block";
            break;
        case 11:
            sequenceDelay=1200;
            get("w"+(copyCount++)).style.display="none";
            get("w"+copyCount).style.display="block";
            mouseX = width * .5;
            mouseY = height * .5;
            systems[0].mouseForce = 7;
            systems[0].mouseRepelDist = 175;
            systems[0].springForce = .1;
            systems[0].setWander(.05);
            break;
        case 12:
            sequenceDelay=9000;
            orbitting=true;
            break;
        case 13:
            sequenceDelay=10000;
            systems[0].colour = randomColour();
            colourInterval = setInterval( function(){systems[0].colour = randomColour();}, 500 );
            get("w"+(copyCount++)).style.display="none";
            get("w"+copyCount).style.display="block";
            break;
        case 14:
            sequenceDelay=2000;
            clearInterval(colourInterval);
            systems[0].colour = '#FFFFFF';
            break;
        case 15:
            sequenceDelay=300;
            systems[0].colour = '#FF1515';
            get("w"+(copyCount++)).style.display="none";
            get("w"+copyCount).style.display="block";
            orbitting=false;
            systems[0].pShapeMorph(0);
            mouseX = width * .5;
            mouseY = height * .5;
            break;
        case 16:
            sequenceDelay=300;
            systems[0].mouseForce = 6;
            systems[0].mouseRepelDist = 150;
            break;
        case 17:
            sequenceDelay=300;
            systems[0].mouseForce = 4;
            systems[0].mouseRepelDist = 100;
            break;
        case 18:
            sequenceDelay=7000;
            systems[0].mouseForce = 0.05;
            systems[0].mouseRepelDist = 100;
            systems[0].friction = 1.01;
            mouseX = 0;
            mouseY = 0;
            break;
        case 19:
            sequenceDelay=300;
            get("w"+(copyCount++)).style.display="none";
            get("w"+copyCount).style.display="block";
            systems[0].friction = .9;
            systems[0].springForce = .01;
            setUpEvents();
            break;
        case 20:
            sequenceDelay=2000;
            break;
        case 21:
            sequenceDelay=5000;
            enableUI();
            break;
        case 22:
            get("w"+copyCount).style.display="none";
            break;
        default:
            /* [[-_-]] */
    }
    if(sequenceCount < maxSequenceCount){
        setTimeout(function(){ sequencer(); }, sequenceDelay);
    }
}

init();
animate();
if(!RUN_AS_ANIMATION){
    setUpEvents();
    enableUI();
}
else{
    setTimeout(function(){ sequencer(); }, sequenceDelay);
}
            
          
!
999px
Loading ..................

Console