UNPKG

jparticles

Version:

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

200 lines (199 loc) 7.47 kB
"use strict"; 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 }); require("./polyfill"); var config_1 = __importDefault(require("./config")); var constants_1 = require("./constants"); var events_1 = __importDefault(require("./events")); var utils_1 = require("../utils/index"); var Base = /** @class */ (function () { function Base(defaultConfig, selector, options) { // (粒子)数据集 this.elements = []; // Canvas 是否从 DOM 中移除了 this.isCanvasRemoved = false; // 是否暂停运动了 this.isPaused = false; // 事件中心,文档参考 https://taro-docs.jd.com/taro/docs/apis/about/events/ this.eventEmitter = new events_1.default(); // 特效是否支持运行 this.isRunningSupported = false; // 对于不支持运行特效的浏览器(如 IE8)将不支持创建特效 if (!constants_1.isRuntimeSupported) return; this.container = utils_1.isElement(selector) ? selector : document.querySelector(selector); this.isRunningSupported = !!this.container; if (this.container) { this.options = utils_1.merge({}, config_1.default, defaultConfig, options); this.canvas = document.createElement('canvas'); this.ctx = this.canvas.getContext('2d'); this.container.innerHTML = ''; this.container.appendChild(this.canvas); // 缓存颜色获取函数,提高性能 this.getColor = this.makeColorMethod(); } } /** * 引导程序 */ Base.prototype.bootstrap = function () { if (this.isRunningSupported) { this.setCanvasDimension(); this.observeCanvasRemoved(); this.resizeEvent(); this.init(); this.draw(); } }; /** * 清除整个画布 */ Base.prototype.clearCanvasAndSetGlobalAttrs = function () { var _a = this, ctx = _a.ctx, canvasWidth = _a.canvasWidth, canvasHeight = _a.canvasHeight; ctx.clearRect(0, 0, canvasWidth, canvasHeight); ctx.globalAlpha = this.options.opacity; }; /** * 生成 "getColor" 函数 */ Base.prototype.makeColorMethod = function () { var color = this.options.color; var colorLength = Array.isArray(color) ? color.length : 0; if (utils_1.isString(color)) { return function () { return color; }; } if (colorLength === 0) { return utils_1.randomColor; } return function () { return color[Math.floor(Math.random() * colorLength)]; }; }; /** * 设置画布尺寸 */ Base.prototype.setCanvasDimension = function () { var dpr = window.devicePixelRatio; var width = utils_1.getNumberValueOfStyle(this.container, 'width') || constants_1.defaultCanvasWidth; var height = utils_1.getNumberValueOfStyle(this.container, 'height') || constants_1.defaultCanvasHeight; this.canvasWidth = width; this.canvasHeight = height; // 设置设备分辨率,防止在高清屏显示模糊(Mac OS) this.canvas.width = width * dpr; this.canvas.height = height * dpr; this.canvas.style.width = width + 'px'; this.canvas.style.height = height + 'px'; this.ctx.scale(dpr, dpr); }; /** * 监听画布从 DOM 中被移除时,做后期清理操作,如销毁事件等 */ Base.prototype.observeCanvasRemoved = function () { var _this = this; utils_1.observeElementRemoved(this.canvas, function () { // 当 Canvas 从 DOM 中被移除 // 1、停止 requestAnimationFrame,避免性能损耗 _this.isCanvasRemoved = true; // 2、移除绑定事件 if (_this.resizeHandler) { window.removeEventListener('resize', _this.resizeHandler); } // 3、触发销毁回调事件 _this.eventEmitter.trigger(constants_1.EVENT_NAMES.DESTROY); // 4、移除所有事件 _this.eventEmitter.off(); }); }; /** * 简单包装 window.requestAnimationFrame */ Base.prototype.requestAnimationFrame = function () { if (!this.isPaused && !this.isCanvasRemoved) { window.requestAnimationFrame(this.draw.bind(this)); } }; /** * 窗口尺寸调整事件 */ Base.prototype.resizeEvent = function () { var _this = this; if (this.options.resize) { // 窗口尺寸改变处理函数,对应调整(粒子)位置 this.resizeHandler = function () { var preCW = _this.canvasWidth; var preCH = _this.canvasHeight; // 重设画布尺寸 _this.setCanvasDimension(); // 缩放比例 var scaleX = _this.canvasWidth / preCW; var scaleY = _this.canvasHeight / preCH; // 通用处理逻辑,重新计算粒子坐标 _this.elements.forEach(function (element) { if (utils_1.isPlainObject(element)) { ; element.x *= scaleX; element.y *= scaleY; } }); // 触发窗口缩放事件,可自定义更多逻辑 _this.eventEmitter.trigger(constants_1.EVENT_NAMES.RESIZE, scaleX, scaleY); _this.isPaused && _this.draw(); }; window.addEventListener('resize', this.resizeHandler); } }; /** * 暂停运动 */ Base.prototype.pause = function () { if (this.isRunningSupported && !this.isCanvasRemoved && !this.isPaused) { this.isPaused = true; } }; /** * 开启运动 */ Base.prototype.open = function () { if (this.isRunningSupported && !this.isCanvasRemoved && this.isPaused) { this.isPaused = false; this.draw(); } }; /** * 当 Canvas 从 DOM 中移除时触发的销毁回调事件 * @param args 参数集合 */ Base.prototype.onDestroy = 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.DESTROY], args)); // 让事件支持链式操作 return this; }; /** * 窗口尺寸改变时触发的回调事件 * @param args 参数集合 */ Base.prototype.onResize = 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.RESIZE], args)); // 让事件支持链式操作 return this; }; return Base; }()); exports.default = Base;