this.r = colorValue(min);
this.g = colorValue(min);
this.b = colorValue(min);
this.style = createColorStyle(this.r, this.g, this.b);
function colorValue(min) {
return Math.floor(Math.random() * 255 + min);
function createColorStyle(r,g,b) {
return 'rgba(' + r + ',' + g + ',' + b + ', 0.8)';
function distance2dPositions(dx, dy){
return Math.sqrt(dx*dx + dy*dy);
function distance2dCoordinates(x1, x2, y1, y2){
var dist = Math.sqrt( dx*dx + dy*dy );
var maxX = window.innerWidth;
var maxY = window.innerHeight;
function TargetedLightning(trailSize, target){
self.color = new Color(128);
self.trailSize = trailSize;
for(var i = 0; i < self.trailSize; i++){
self.trail.push({px: self.px, py: self.py});
self.deltaJumpLength = 15;
self.disturbLength = self.jumpLength * 2/ 3;
self.deltaDisturbLength = self.deltaJumpLength * 2 / 3;
self.setTarget = function(target){
self.update = function(){
var dxTarget = self.target.px - self.px;
var dyTarget = self.target.py - self.py;
var dist = distance2dPositions(dxTarget, dyTarget);
var randomAngle = Math.random() * Math.PI;
var disturbLength = self.disturbLength + Math.random() * self.deltaDisturbLength;
var jumpLength = self.jumpLength + self.deltaJumpLength * Math.random();
if(dist < (self.jumpLength + self.deltaJumpLength)){
var finalDx = ((dxTarget / dist) * jumpLength ) + disturbLength * Math.cos(randomAngle);
var finalDy = ((dyTarget / dist) * jumpLength ) + disturbLength * Math.sin(randomAngle);
self.trail.unshift({px: self.px, py: self.py});
self.draw = function(ctx){
ctx.moveTo(self.px, self.py);
for(var i = 0; i < self.trail.length; i++){
ctx.lineTo(self.trail[i].px, self.trail[i].py);
ctx.strokeStyle = self.color.style;
ctx.arc(self.target.px, self.target.py, 10, 0, Math.PI * 2, false);
ctx.strokeStyle = this.color.style;
self.reachTarget = function(){
px: Math.random() * maxX,
self.setTarget(newTarget);
self.canvas = document.querySelector('canvas');
self.ctx = self.canvas.getContext('2d');
self.canvas.width = window.innerWidth;
self.canvas.height = window.innerHeight;
self.updateAll = function(){
for(var i = 0; i < self.lightnings.length; i++){
self.lightnings[i].update();
self.drawAll = function(){
for(var i = 0; i < self.lightnings.length; i++){
self.lightnings[i].draw(self.ctx);
self.animationCycle = function(){
self.ctx.clearRect(0, 0, self.canvas.width, self.canvas.height);
requestAnimationFrame(self.animationCycle);
self.initApp = function(){
for(var i = 0; i < 2; i++){
self.lightnings.push(new TargetedLightning(15, {px: self.canvas.width / 2, py: self.canvas.height / 2}));
requestAnimationFrame(self.animationCycle);