UNPKG

jparticles

Version:

A lightweight, efficient and easy-to-use Canvas library for building some cool particle effects.

195 lines (194 loc) 7.55 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __spreadArray = (this && this.__spreadArray) || function (to, from) { for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) to[j] = from[i]; return to; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var shape_1 = __importDefault(require("./common/shape")); var utils_1 = require("./utils/index"); var constants_1 = require("./common/constants"); var Snow = /** @class */ (function (_super) { __extends(Snow, _super); function Snow(selector, options) { var _this = _super.call(this, Snow.defaultConfig, selector, options) || this; // 下雪的开始时间 _this.startTime = Date.now(); // 当存在持续时间参数时,雪花是否全部降落 _this.isFinished = false; _this.bootstrap(); return _this; } /** * 初始化数据和运行程序 */ Snow.prototype.init = function () { this.createSnowflakes(); }; /** * 创建单个雪花,包含大小、位置、速度等信息 */ Snow.prototype.createSnowflake = function () { var _a = this.options, maxR = _a.maxR, minR = _a.minR, maxSpeed = _a.maxSpeed, minSpeed = _a.minSpeed, spin = _a.spin, spinMaxSpeed = _a.spinMaxSpeed, spinMinSpeed = _a.spinMinSpeed; var r = utils_1.randomInRange(maxR, minR); return { r: r, x: Math.random() * this.canvasWidth, y: -r, vx: utils_1.randomSpeed(maxSpeed, minSpeed), // 半径越大,垂直速度越快,这样比较有近快远慢的层次效果 vy: Math.abs(r * utils_1.randomSpeed(maxSpeed, minSpeed)), color: this.getColor(), swingAt: Date.now(), shape: this.getShapeData(), // 定义粒子的旋转角度 rotate: spin ? utils_1.randomInRange(0, 360) : 0, // 粒子的旋转速度 rotateSpeed: utils_1.randomSpeed(spinMaxSpeed, spinMinSpeed), }; }; /** * 随机创建雪花 */ Snow.prototype.createSnowflakes = function () { var count = Math.max(0, Math.ceil(Math.random() * this.options.num)); while (count--) { this.elements.push(this.createSnowflake()); } }; /** * 绘图 * 设计一种模式(解耦逻辑混杂),当触发 resize 事件调用 draw 方法时: * 如果是暂停 -> 调用 elements 的重新绘制 drawShape() * 如果是运动中 -> 正常逻辑,内部不考虑暂停逻辑 */ Snow.prototype.draw = function () { var _this = this; var _a = this, canvasWidth = _a.canvasWidth, canvasHeight = _a.canvasHeight, isPaused = _a.isPaused; var _b = this.options, maxR = _b.maxR, swing = _b.swing, swingInterval = _b.swingInterval, swingProbability = _b.swingProbability, duration = _b.duration; this.clearCanvasAndSetGlobalAttrs(); this.elements.forEach(function (snowflake, i, array) { var x = snowflake.x, y = snowflake.y, r = snowflake.r; // 更新旋转角度 _this.updateElementRotate(snowflake); _this.drawShape(snowflake); // 暂停(isPaused)且窗口改变(resize)的时候也会调用绘图方法 // 所以需要运动的判断需要在内部 if (isPaused) { return; } snowflake.x += snowflake.vx; snowflake.y += snowflake.vy; // 变换飘落方向,根据一定的几率 if (swing && Date.now() - snowflake.swingAt > swingInterval && // 半径越小,变换几率越小 Math.random() < (r / maxR) * swingProbability) { snowflake.swingAt = Date.now(); snowflake.vx *= -1; } if (x + r < 0 || x - r > canvasWidth) { // 雪花从侧边出去 => 删除 // 有持续时间 ? 不添加 : 添加一个新雪花 duration ? array.splice(i, 1) : array.splice(i, 1, _this.createSnowflake()); } else if (y - r > canvasHeight) { // 雪花从底部出去 => 删除 array.splice(i, 1); } }); if (isPaused) { return; } // 当有 duration 参数时,判断持续时间是否用完 // 没有 duration 参数时,一直可用 var timeEnd = duration ? Date.now() - this.startTime > duration : false; if (!timeEnd && Math.random() > 0.9) { // 添加雪花 this.createSnowflakes(); } if (this.elements.length) { this.requestAnimationFrame(); } else { this.isFinished = true; this.eventEmitter.trigger(constants_1.EVENT_NAMES_SNOW.FINISHED); } }; /** * 更新元素自旋数据 */ Snow.prototype.updateElementRotate = function (element) { if (!this.options.spin || this.isPaused) { return; } // 更新旋转角度 element.rotate += element.rotateSpeed; // 大于等于 360 度时,回到 0-360 范围,避免变量数值一直累计超过 MAX_SAFE_INTEGER if (element.rotate >= 360) { element.rotate = element.rotate - 360; } }; /** * 方法:当存在持续时间时,再次下雪 */ Snow.prototype.fallAgain = function () { if (this.isRunningSupported && !this.isCanvasRemoved && !this.isPaused && this.isFinished) { this.isFinished = false; this.startTime = Date.now(); this.createSnowflakes(); this.draw(); } }; /** * 事件:当存在持续时间时,雪花全部降落后触发的事件 */ Snow.prototype.onFinished = function () { var _a; var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } (_a = this.eventEmitter).on.apply(_a, __spreadArray([constants_1.EVENT_NAMES_SNOW.FINISHED], args)); return this; }; Snow.defaultConfig = { num: 6, color: '#fff', maxR: 6.5, minR: 0.5, maxSpeed: 0.6, minSpeed: 0.1, swing: true, swingInterval: 2000, swingProbability: 0.06, spin: false, spinMaxSpeed: 5, spinMinSpeed: 1, }; return Snow; }(shape_1.default)); exports.default = Snow;