Advertisement
Guest User

Untitled

a guest
Jul 22nd, 2017
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <!DOCTYPE html>
  2. <html>
  3.   <head>
  4.     <!--
  5.      
  6.       HeartRate, frame rate monitor and sketch.
  7.       Author: Corban Brook @corban
  8.      
  9.       Daniel Shiffman's flocking example ported from processing to javascript using HTML5 canvas.
  10.      
  11.       Using Vlad's mjs.js matrix and vector lib for speed
  12.    
  13.     -->
  14.    
  15.     <title>HTML5 Canvas - Flocking</title>
  16.     <script type="text/javascript" src="mjs.js"></script>
  17.     <script type="text/javascript" src="../heartrate.js"></script>
  18.    
  19.     <script type="text/javascript">
  20.  
  21.       var cvs,
  22.           ctx,
  23.           width,
  24.           height,
  25.           mouseX = 0,
  26.           mouseY = 0,
  27.           FPS = 50;
  28.  
  29.       document.addEventListener("DOMContentLoaded", init, false);
  30.  
  31.       var requestFrame = function() {};
  32.  
  33.       /* The init function creates a 2d context, runs setup and starts draw loop */
  34.       function init() {
  35.         cvs = document.getElementById("flocking");
  36.         ctx = cvs.getContext("2d");
  37.    
  38.         width = cvs.width, height = cvs.height;
  39.        
  40.         // Event Listeners for mouse
  41.         cvs.addEventListener('mouseup', mouseClicked, false);
  42.         cvs.addEventListener('mousemove', function(event) {
  43.           mouseX = event.clientX, mouseY = event.clientY;
  44.         }, false);
  45.  
  46.         window.heartRate = new HeartRate({ context: ctx, maxFPS: FPS, path: "../" });
  47.  
  48.         setup();
  49.        
  50.         function redraw() {
  51.           draw();
  52.           requestFrame();
  53.         }
  54.  
  55.         if (typeof window.mozRequestAnimationFrame === "function") {
  56.           (requestFrame = function() { window.mozRequestAnimationFrame(redraw); })();
  57.         } else if (typeof window.webkitRequestAnimationFrame === "function") {
  58.           (requestFrame = function() { window.webkitRequestAnimationFrame(redraw); })();
  59.         } else {
  60.           window.setInterval(redraw, 1000 / FPS);
  61.         }
  62.       }
  63.  
  64.      
  65.       function line(x1, y1, x2, y2) {
  66.         ctx.beginPath();
  67.         ctx.moveTo(x1, y1);
  68.         ctx.lineTo(x2, y2);
  69.         ctx.stroke();
  70.         ctx.closePath();
  71.       }
  72.  
  73.       function stroke(r, g, b, a) {
  74.         var prefix = a === undefined ? 'rgb(' : 'rgba(';
  75.         ctx.strokeStyle = prefix + Array.prototype.slice.call(arguments).join(",") + ')';
  76.       }
  77.  
  78.       function fill(r, g, b, a) {
  79.         var prefix = a === undefined ? 'rgb(' : 'rgba(';
  80.         ctx.fillStyle = prefix + Array.prototype.slice.call(arguments).join(",") + ')';
  81.       }
  82.      
  83.       //---------------------------------------------------------------------------
  84.  
  85.       var BIRD_TOTAL = 100;
  86.  
  87.       var flock;
  88.       var skip = 1;
  89.  
  90.       function setup() {
  91.         flock = new Flock();
  92.    
  93.         // Add initial flock of birds into the system
  94.         for (var i = 0; i < BIRD_TOTAL; i++) {
  95.           flock.addBird(new Bird(V3.$(width/2, height/2, 0), 2, 0.05));
  96.         }
  97.       }
  98.  
  99.       function draw() {
  100.         // Clear background
  101.         fill(240, 240, 240, 0.5);
  102.         ctx.fillRect(0, 0, cvs.width, cvs.height);
  103.        
  104.         flock.run();
  105.        
  106.         heartRate.monitor(2, 2);
  107.  
  108.         fill(40, 40, 40);
  109.         ctx.fillText(flock.birds.length + " particles", 730, 14);
  110.       }
  111.  
  112.       function mouseClicked() {
  113.         // Add 50 more birds under your mouse
  114.         for (var i = 0; i < BIRD_TOTAL; i++) {
  115.           flock.addBird(new Bird(V3.$(mouseX, mouseY, 0), 2, 0.05));
  116.         }
  117.       }
  118.  
  119.       function Flock() {
  120.         this.birds = [];
  121.       }
  122.  
  123.       Flock.prototype.run = function() {    
  124.         for (var i = 0; i < this.birds.length; i++) {
  125.           this.birds[i].run(this.birds); // Passing entire list of birds to each bird
  126.         }
  127.       };
  128.  
  129.       Flock.prototype.addBird = function(bird) {
  130.         this.birds.push(bird);
  131.       };
  132.  
  133.       function Bird(loc, maxSpeed, maxForce) {
  134.         this.loc      = V3.clone(loc);
  135.         this.vel      = V3.$(Math.random() * 2 - 1, Math.random() * 2 - 1, 0);
  136.         this.acc      = V3.$(0, 0, 0);
  137.    
  138.         this.r        = 5;
  139.         this.maxSpeed = maxSpeed;
  140.         this.maxForce = maxForce;
  141.       }
  142.  
  143.       Bird.prototype.run = function(birds) {
  144.         this.flock(birds);
  145.         this.update();
  146.         this.borders();
  147.         this.render();
  148.       };
  149.      
  150.       // if these 3 vars are defined here a strange flocking behavior occures
  151.       // whereas all birds fly to 0, 0 (top left corner)
  152.       var separation = V3.$(0, 0, 0);
  153.       var alignment = V3.$(0, 0, 0);
  154.       var cohesion = V3.$(0, 0, 0);
  155.      
  156.       var diff = V3.$();
  157.      
  158.       var neighborDistance = 2500; // 50 squared
  159.       var desiredSeparation = 625; // 25 squared
  160.  
  161.       Bird.prototype.flock = function(birds) {
  162.         // if these 3 vectors are defined here each time flock is called, it works fine.
  163.         //var separation = V3.$(0, 0, 0);
  164.         //var alignment = V3.$(0, 0, 0);
  165.         //var cohesion = V3.$(0, 0, 0);
  166.        
  167.         V3.set(separation, 0, 0, 0);
  168.         V3.set(alignment, 0, 0, 0);
  169.         V3.set(cohesion, 0, 0, 0);
  170.        
  171.         // and yes the set function does work. these vectors are all 0, 0, 0
  172.        
  173.         var sCount = 0, count = 0;
  174.  
  175.         for(var i = 0, len = birds.length; i < len; i ++) {
  176.           var d = V3.distanceSquared(this.loc, birds[i].loc);
  177.           if (d > 0) {
  178.             if (d < desiredSeparation) {
  179.               V3.sub(this.loc, birds[i].loc, diff);
  180.               V3.normalize(diff, diff);
  181.               V3.scale(diff, 1/(d/10), diff);
  182.               V3.add(separation, diff, separation);
  183.               sCount++;
  184.             }
  185.          
  186.             if (d < neighborDistance) {
  187.               V3.add(alignment, birds[i].vel, alignment);
  188.            
  189.               V3.add(cohesion, birds[i].loc, cohesion);
  190.               count++;
  191.             }
  192.           }
  193.         }
  194.        
  195.         if (sCount > 0) {
  196.           V3.scale(separation, 1/sCount, separation);
  197.           V3.scale(separation, 2.0, separation); // weight separation
  198.          
  199.           V3.add(this.acc, separation, this.acc);
  200.         }
  201.        
  202.         if (count > 0) {
  203.           V3.scale(alignment, 1/count, alignment);
  204.           V3.limit(alignment, this.maxForce, alignment);
  205.          
  206.           V3.scale(cohesion, 1/count, cohesion);
  207.           cohesion = this.steer(cohesion, false);
  208.          
  209.           V3.add(this.acc, alignment, this.acc);
  210.           V3.add(this.acc, cohesion, this.acc);
  211.         }
  212.       };
  213.  
  214.       Bird.prototype.update = function() {
  215.         // Update velocity
  216.         V3.add(this.vel, this.acc, this.vel);
  217.    
  218.         // Limit speed
  219.         V3.limit(this.vel, this.maxSpeed, this.vel);
  220.         V3.add(this.loc, this.vel, this.loc);
  221.        
  222.         // Reset acceleration to zero
  223.         V3.set(this.acc, 0, 0, 0);
  224.       };
  225.  
  226.       Bird.prototype.seek = function(target) {
  227.         V3.add(this.acc, this.steer(target, false), this.acc);
  228.  
  229.       };
  230.  
  231.       Bird.prototype.arrive = function(target) {
  232.         V3.add(this.acc, this.steer(target, true), this.acc);
  233.       };
  234.  
  235.       var desired = V3.$();
  236.       var steer = V3.$();
  237.  
  238.       Bird.prototype.steer = function(target, slowDown) {
  239.         //var steer = V3.$(0, 0, 0);
  240.         //var desired = V3.sub(target, this.loc);
  241.         V3.set(steer, 0, 0, 0);
  242.         V3.sub(target, this.loc, desired);
  243.         var d = V3.length(desired);
  244.        
  245.         if (d > 0) {
  246.           V3.normalize(desired, desired);
  247.        
  248.           if (slowDown && d < 100) {
  249.             V3.scale(desired, this.maxSpeed*(d/100), desired);
  250.           } else {
  251.             V3.scale(desired, this.maxSpeed, desired);
  252.           }
  253.          
  254.           V3.sub(desired, this.vel, steer);
  255.           V3.limit(steer, this.maxForce, steer);
  256.         }
  257.        
  258.         return steer;
  259.       };
  260.  
  261.       Bird.prototype.borders = function() {
  262.         var r = this.r, loc = this.loc;
  263.  
  264.         if (loc[0] < -r)         { loc[0] = width + r; }
  265.         if (loc[1] < -r)         { loc[1] = height + r; }
  266.         if (loc[0] > width + r)  { loc[0] = -r; }
  267.         if (loc[1] > height + r) { loc[1] = -r; }
  268.       };
  269.  
  270.       Bird.prototype.render = function() {
  271.         var theta = V3.heading2D(this.vel) + Math.PI/2;
  272.         ctx.save(); // push matrix
  273.           ctx.translate(this.loc[0], this.loc[1]);
  274.           ctx.rotate(theta);
  275.           line(0, this.r, 0, 0);
  276.         ctx.restore(); // pop matrix
  277.       };
  278.     </script>
  279.   </head>
  280.   <body>
  281.     <canvas id="flocking" width="800" height="600"></canvas>
  282.     <p>Click to add more particles. Push your browser to the limit. -- @corban</p>
  283.   </body>
  284. </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement