So many thoughts in the head

canvas, js. 黑夜,街道,路灯,药房

by schrodingers

HTML

<canvas id="c"></canvas>

CSS

body {
  overflow: hidden;
}

JavaScript

var c = document.getElementById("c");
c.width = window.innerWidth;
c.height = window.innerHeight;
var s = c.width,
  ctx = c.getContext('2d'),

  opts = {
    //    text: '`1234567890-=qwertyuiop[]asdfghjkl;zxcvbnm,./¬!"£$%^&*()_+ASDFGHJKL:@~ZXCVBNM<>?|QWERTYUIOP{}',
    text: "黑夜 街道 路灯 药房 莫名的昏暗灯光 哪怕再活四分之一个世纪 一切仍将如此 没有终场",
    count: 150,
    baseStartDist: 100,
    addedStartDist: 60,
    startY: 100,
    endY: -200,
    gravity: .03,
    baseVel: 2,
    addedVel: 0.5,
    angleVariation: .2,
    middleAttraction: .003,
    templateColor: 'hsla(hue,80%,50%,.5)',
    vanishPoint: {
      x: s / 2,
      y: s / 2
    },
    focalLength: 250,
    depth: 250
  },

  particles = [],
  tick = 0,
  tau = 6.2831853071795864769252867665590057683943387987502116419498891846156328125724179972560696506842341359; //  e^(i*tau/2) + cos( tau ) 


function Particle() {
  this.canvas = document.createElement('canvas');
  this.canvas.width = 40;
  this.canvas.height = 40;
  this.ctx = this.canvas.getContext('2d');
  this.ctx.font = '40px monospace';
  this.reset();
}
Particle.prototype.reset = function() {
  var radius = opts.baseStartDist + opts.addedStartDist * Math.random(),
    ang = Math.random() * tau,
    velAng = ang + tau / 4 + opts.angleVariation * (Math.random() * 2 - 1),
    vel = opts.baseVel + opts.addedVel * Math.random();

  this.x = radius * Math.cos(ang);
  this.y = opts.startY;
  this.z = radius * Math.sin(ang);

  this.vx = vel * Math.cos(velAng);
  this.vy = 0;
  this.vz = vel * Math.sin(velAng);

  var character = opts.text[opts.text.length * Math.random() | 0],
    color = opts.templateColor.replace('hue', tick + ang / tau * 180);

  this.ctx.clearRect(0, 0, 40, 40);
  this.ctx.fillStyle = color;
  this.ctx.fillText(character, -2, 40);
}
Particle.prototype.step = function() {

  this.x += this.vx -= this.x * opts.middleAttraction;
  this.y += this.vy -= opts.gravity;
  this.z += this.vz -= this.z * opts.middleAttraction;

  var radius = 1 - Math.sqrt((this.y...