Spirals

Jake weary will see you spin.

by Sam Fereday

HTML

<button id="start">
  Start
</button>
<div id="container"></div>

CSS

html,
body {
  height: 100%;
  padding: 0;
  margin: 0;
  overflow: hidden;
}

* {
  box-sizing: border-box;
}

#container {
  position: relative;
  height: 100%;
  width: 100%;
}

.float {
  width: 40px;
  height: 40px;
  position: absolute;
  left: 0;
  top: 0;
  border: 1px solid #333;
  background: url('https://www.floridamemory.com/fpc/prints/pr07237.jpg');
  background-size: cover;
  text-align: center;
  font-family: arial;
  color: #fff;
  cursor: pointer;
  transition: background 0.2s ease;
}
.float:hover {
  background-color: #ff0000;
}

#start {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 10;
}

JavaScript

// To avoid the immovable 'tail' effect, extra calculations will have to go in to gradually moving each float away from the center point over time. Probably can be done by having an individual increment per node, rather than a global one.
var Float = function(el, i) {
  this.i = i;
  this.x = 0;
  this.y = 0;
  this.el = el;
};

Float.prototype.setPosition = function(v) {

  this.x = v.x;
  this.y = v.y;

  this.el.style.left = v.x + 'px';
  this.el.style.top = v.y + 'px';

};

//
var FloatCollection = function(container) {
  this.nodes = [];
  this.center = {
    x: container.clientWidth / 2,
    y: container.clientHeight / 2
  }
};

FloatCollection.prototype.dist = function(v1, v2) {

  var a = v1.x - v2.x;
  var b = v1.y - v2.y;

  return Math.sqrt(a * a + b * b);

};

FloatCollection.prototype.algorithm = function(stepping, offset) {

  // temp
  let a = 1; // Tightness of spiral arcs
  let b = 1; // Space between spiral arms
  offset = offset ? offset : 0;

  stepping = stepping * 12;

  var inc = stepping ? 1 / (a + b) * stepping : 0.1;

  return {
    x: this.center.x + ((inc) * Math.cos(inc + offset)),
    y: this.center.y + ((inc) * Math.sin(inc + offset))
  }

};

FloatCollection.prototype.makeNode = function(el) {
  this.nodes.push(new Float(el, this.nodes.length));
};

var off = 0;
FloatCollection.prototype.updateNodes = function() {

  let self = this;

  off += 0.05;

  //if (off > Math.PI * 2)
    //off = 0;

  let endNode = this.nodes[this.nodes.length - 1];
  let maxDist = this.dist(this.center, {
    x: endNode.x,
    y: endNode.y
  });

  this.nodes.forEach(function(node, i) {

    let al = self.algorithm(i, off);
    node.setPosition(al);

		let n = self.dist(self.center, {
      x: node.x,
      y: node.y
    });
    
    let s = n / maxDist;
    node.el.style.transform = "scale(" + s * (Math.PI * 2) + ")";
    node.el.style.opacity = s / 0.5;

  });

};

// origin points
var a = 1;
var b = 1;
var els = 40;
var container =...