UNPKG

jparticles

Version:

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

283 lines (282 loc) 10.2 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 constants_1 = require("./common/constants"); var easing_1 = __importDefault(require("./common/easing")); var utils_1 = require("./utils/index"); var wave_1 = __importDefault(require("./wave")); var plainOptionsWL = [ 'font', 'textColor', 'textFormatter', 'borderRadius', ]; var WaveLoading = /** @class */ (function (_super) { __extends(WaveLoading, _super); function WaveLoading(selector, options) { var _this = _super.call(this, selector, utils_1.merge({}, WaveLoading.defaultConfig, options)) || this; // 当前进度 _this.progress = 0; // 是否立即完成 _this.isCompletedImmediately = false; // 立即完成时的进度步进值 _this.fastStepValue = 1; return _this; } /** * 初始化数据和运行程序 */ WaveLoading.prototype.init = function () { this.halfCH = this.canvasHeight / 2; // WaveLoading methods this.setOffsetTop(this.canvasHeight); this.setCanvasStyle(); // Wave methods this.ownResizeEvent(); this.optionsNormalize(); this.loadMaskImage(); this.createDots(); // WaveLoading resize 事件需要放到 Wave 的后面 this.waveLoadingResizeEvent(); }; /** * 设置 offsetTop 值 * @param top 高度值 */ WaveLoading.prototype.setOffsetTop = function (top) { var offsetTop = this.options.offsetTop; if (Array.isArray(offsetTop)) { offsetTop.forEach(function (_item, i, arr) { arr[i] = top; }); } else { this.options.offsetTop = top; } }; /** * 设置画布 CSS 样式 */ WaveLoading.prototype.setCanvasStyle = function () { this.canvas.style.borderRadius = this.options.borderRadius; }; /** * 绘制入口:计算进度,绘制波纹等 */ WaveLoading.prototype.draw = function () { this.calcProgress(); if (this.progress < 100) { this.mainDrawing(); this.requestAnimationFrame(); } else { this.progress = 100; this.mainDrawing(); this.eventEmitter.trigger(constants_1.EVENT_NAMES_WAVE_LOADING.FINISHED); } }; /** * 绘制图案 */ WaveLoading.prototype.mainDrawing = function () { var _this = this; this.eventEmitter.trigger(constants_1.EVENT_NAMES_WAVE_LOADING.PROGRESS, this.progress); this.calcOffsetTop(); this.clearCanvasAndSetGlobalAttrs(); // 调用 Wave 方法 this.renderMaskMode(function () { _this.drawWaves(); }); // 调用 WaveLoading 方法 this.drawText(); }; /** * 绘制进度文本 */ WaveLoading.prototype.drawText = function () { var _a = this, ctx = _a.ctx, canvasWidth = _a.canvasWidth, halfCH = _a.halfCH, progress = _a.progress; var _b = this.options, font = _b.font, textFormatter = _b.textFormatter, textColor = _b.textColor; if (!utils_1.isString(textFormatter) || !textFormatter) return; // 替换文本模板真实值 var text = textFormatter.replace(/%d/g, String(Math.floor(progress))); ctx.save(); ctx.font = font; var textWidth = ctx.measureText(text).width; var x = (canvasWidth - textWidth) / 2; ctx.textBaseline = 'middle'; ctx.fillStyle = textColor; ctx.font = font; ctx.fillText(text, x, halfCH); ctx.restore(); }; /** * 计算进度值 */ WaveLoading.prototype.calcProgress = function () { // 立即完成逻辑,采用快速步进值计算进度 if (this.isCompletedImmediately) { this.progress += this.fastStepValue; this.fastStepValue += 0.5; return; } // 悬停 99% 时,跳出计算,减少性能损耗 if (this.progress >= WaveLoading.progressThreshold) return; if (!this.startTime) { this.startTime = Date.now(); } // x: percent complete percent complete: elapsedTime / duration // t: elapsed time elapsed time: currentTime - startTime // b: beginning value start value // c: change in value finish value // d: duration duration var time = Date.now() - this.startTime; var percent = time / this.options.duration; if (percent <= 1) { this.progress = easing_1.default[this.options.easing]( // x, t, b, c, d percent, time, 0, 100, this.options.duration); // 1、防止 progress 超出 100 // 2、通过 easing 函数返回的值可能悬停 99.7,加 0.9 让进度达到阈值 if (this.progress + 0.9 >= WaveLoading.progressThreshold) { this.progress = WaveLoading.progressThreshold; } } }; /** * 根据进度计算波纹 offsetTop 值 */ WaveLoading.prototype.calcOffsetTop = function () { // 退出以提高性能 if (!this.isCompletedImmediately && this.progress >= WaveLoading.progressThreshold) { return; } var maxCrestHeight = Math.max.apply(Math, this.options.crestHeight); var top = this.progress === 100 ? -maxCrestHeight : Math.ceil(((100 - this.progress) / 100) * this.canvasHeight + maxCrestHeight); this.setOffsetTop(top); }; /** * 窗口尺寸调整事件 */ WaveLoading.prototype.waveLoadingResizeEvent = function () { var _this = this; this.onResize(function () { _this.halfCH = _this.canvasHeight / 2; if (_this.progress === 100) { _this.draw(); } }); }; /** * 方法:动态设置属性值 */ WaveLoading.prototype.setOptions = function (newOptions) { if (!this.isRunningSupported || !utils_1.isPlainObject(newOptions)) return; // 调用 Wave 更新项 _super.prototype.setOptions.call(this, newOptions); for (var property in newOptions) { if (Object.hasOwnProperty.call(newOptions, property) && plainOptionsWL.indexOf(property) !== -1) { var newValue = newOptions[property]; this.options[property] = newValue; if (property === 'borderRadius') { this.setCanvasStyle(); } } } }; /** * 方法:让进度立即加载完成 */ WaveLoading.prototype.done = function () { if (this.isRunningSupported && !this.isCompletedImmediately) { this.isCompletedImmediately = true; } }; /** * 事件:进度每次改变的时候触发 */ WaveLoading.prototype.onProgress = 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_WAVE_LOADING.PROGRESS], args)); return this; }; /** * 事件:进度加载到 100% 后触发 */ WaveLoading.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_WAVE_LOADING.FINISHED], args)); return this; }; WaveLoading.defaultConfig = { num: 1, // [font style][font weight][font size][font family] // 文本样式,同css一样,必须包含 [font size] 和 [font family] font: 'normal 400 16px Arial', // 文本颜色 textColor: '#333', // 进度文本模板 textFormatter: 'loading...%d%', fill: true, line: false, // 填充的背景色 fillColor: '#27C9E5', // 画布外边框圆角 borderRadius: '50%', // 线条横向偏移值,距离canvas画布左边的偏移值 // (0, 1)表示容器宽度的倍数,0 & [1, +∞)表示具体数值 offsetLeft: 0, // 波峰高度,(0, 1)表示容器高度的倍数,0 & [1, +∞)表示具体数值 crestHeight: 4, // 波纹个数,即正弦周期个数 crestCount: 1, // 波浪的运动速度 speed: 0.3, // 加载到 99% 的时长,单位毫秒(ms) // 用时越久,越慢加载到 99%。 duration: 5000, // 加载过程的运动效果, // 目前支持匀速(linear),先加速再减速(swing),两种 easing: 'swing', }; // 进度阈值 WaveLoading.progressThreshold = 99.99; return WaveLoading; }(wave_1.default)); exports.default = WaveLoading;