Система частиц, летающих по экрану на HTML5 Canvas и jQuery
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
<canvas id="js-particles" class="particles" width="1280" height="1280"></canvas> <script> var PARTICLE_QUANT = 50; var FPS = 10; var BOUNCE = -1; var PARTICLE_COLOR = 'rgb(255, 255, 10)'; var ARC_RADIUS = 2; /** * Particles lib class * * @class Particles * @constructor */ var Particles = function($element) { // if element doesnt exist in the DOM return early if ($element.length === 0) { return; } /** * A reference to the containing DOM element. * * @default null * @property {jQuery} $element * @public */ this.$element = $element; /** * Initial timestamp use to for baseline of animation loop * * @default null * @property lastTimeStamp * @type {number} * @public */ this.lastTimeStamp = null; /** * array representing particles * * @default empty array * @property lastTimeStamp * @type {array} * @public */ this.particles = []; this.init(); }; var proto = Particles.prototype; /** * Initializes the class. * Runs a single setupHandlers call, followed by createChildren and layout. * Exits early if it is already initialized. * * @method init * @private */ proto.init = function() { this.createChildren().layout().enable(); }; /** * Create any child objects or references to DOM elements. * Should only be run on initialization of the view. * * @method createChildren * @returns {Particles} * @private */ proto.createChildren = function() { this.canvas = this.$element[0]; this.context = this.canvas.getContext('2d'); this.canvasWidth = this.canvas.width; this.canvasHeight = this.canvas.height; this.lastTimeStamp = new Date().getTime(); return this; }; /** * handles layout of DOM elements * * @method layout * @returns {ParticlesController} * @private */ proto.layout = function() { window.requestAnimFrame = (function() { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame; })(); return this; }; /** * Remove any child objects or references to DOM elements. * * @method removeChildren * @returns {Particles} * @public */ proto.removeChildren = function() { this.context = null; this.canvasWidth = null; this.canvasHeight = null; this.lastTimeStamp = null; return this; }; /** * Enables the component. * Performs any event binding to handlers. * Exits early if it is already enabled. * * @method enable * @public */ proto.enable = function() { this.createParticleData(); this.renderLoop(); }; ////////////////////////////////////////////////////////////////////////////////// // HELPER METHODS ////////////////////////////////////////////////////////////////////////////////// /** * Creates particle data objects * * @method createParticleData * @private */ proto.createParticleData = function() { var i = 0; var l = PARTICLE_QUANT; for (; i < l; i++) { this.particles[i] = {}; this.setParticleData(this.particles[i]); } }; /** * Sets the base particle data * * @method setParticleData * @private */ proto.setParticleData = function(particle) { particle.x = Math.random() * this.canvasWidth; particle.y = Math.random() * this.canvasHeight; particle.vx = (Math.random()) - 0.5; particle.vy = (Math.random()) - 0.5; }; /** * Updates the particle data object * * @method update * @private */ proto.update = function() { var i = 0; var l = PARTICLE_QUANT; for (; i < l; i++) { var particle = this.particles[i]; particle.x += particle.vx; particle.y += particle.vy; if (particle.x > this.canvasWidth) { particle.x = this.canvasWidth; particle.vx *= BOUNCE; } else if (particle.x < 0) { particle.x = 0; particle.vx *= BOUNCE; } if (particle.y > this.canvasHeight) { particle.y = this.canvasHeight; particle.vy *= BOUNCE; } else if (particle.y < 0) { particle.y = 0; particle.vy *= BOUNCE; } } }; /** * Renders the particle on the canvas * * @method draw * @private */ proto.draw = function() { var i = 0; if (!this.context) { return; } this.context.clearRect(0, 0, this.canvasWidth, this.canvasHeight); this.context.strokeStyle = PARTICLE_COLOR; for (; i < PARTICLE_QUANT; i++) { var particle = this.particles[i]; this.context.save(); this.context.beginPath(); this.context.arc(particle.x, particle.y, ARC_RADIUS, 0, Math.PI * 2); this.context.stroke(); this.context.restore(); } }; /** * Creates the animation loop * * @method renderLoop * @private */ proto.renderLoop = function() { requestAnimationFrame(this.renderLoop.bind(this)); this.update(); this.draw(); }; var particles = new Particles($('#js-particles')); </script> |
1 2 3 4 |
.particles { width: 100%; height: 100%; } |