jparticles
Version:
A lightweight, efficient and easy-to-use Canvas library for building some cool particle effects.
180 lines (179 loc) • 6.05 kB
JavaScript
;
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 __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var base_1 = __importDefault(require("./base"));
var constants_1 = require("./constants");
var utils_1 = require("../utils/index");
var validShapeTypes = ['circle', 'triangle', 'star', 'image'];
/**
* 生成形状数据
* @param shape 形状类型
*/
function generateShapeData(shape) {
if (utils_1.isString(shape)) {
// 处理「圆形」和「三角形」
if (shape === 'circle' || shape === 'triangle') {
return { type: shape };
}
// 处理「星形」,默认五角星
if (constants_1.regExp.shapeStar.test(shape)) {
var result = shape.split(':');
return {
type: 'star',
sides: Number(result[1]) || 5,
dent: Number(result[2]) || 0.5,
};
}
// 处理「Base64 格式」或「HTTP 地址图片」
if (constants_1.regExp.http.test(shape) ||
constants_1.regExp.imageBase64.test(shape)) {
var dataRef_1 = {
type: 'image',
isImageLoaded: false,
};
utils_1.loadImage(shape, function (image) {
dataRef_1.isImageLoaded = true;
dataRef_1.source = image;
});
return dataRef_1;
}
// 提示错误
// eslint-disable-next-line no-console
console.warn("Shape value of " + shape + " is invalid.");
}
try {
// 处理 CanvasImageSource 类型
if (shape instanceof HTMLImageElement ||
shape instanceof HTMLVideoElement ||
shape instanceof HTMLCanvasElement ||
shape instanceof ImageBitmap ||
shape instanceof OffscreenCanvas) {
return {
type: 'image',
isImageLoaded: true,
source: shape,
};
}
}
catch (_err) {
// eslint-disable-next-line no-console
console.warn('Your browser does not support [CanvasImageSource](https://developer.mozilla.org/en-US/docs/Web/API/CanvasImageSource), please upgrade it.');
}
// 错误的数据:不显示
return {
type: 'image',
isImageLoaded: false,
};
}
/**
* 绘制「星形」形状
* https://programmingthomas.wordpress.com/2012/05/16/drawing-stars-with-html5-canvas/
*
* @param ctx 绘图环境
* @param x 中心点 X 坐标
* @param y 中心点 Y 坐标
* @param r 半径
* @param p 边数(number of points)
* @param m 插入半径的分数
*/
function drawStar(ctx,
// 中心点 X 坐标
x,
// 中心点 Y 坐标
y,
// 半径
r,
// 边数(number of points)
p,
// 插入半径的分数
m) {
ctx.translate(x, y);
ctx.moveTo(0, 0 - r);
for (var i = 0; i < p; i++) {
ctx.rotate(Math.PI / p);
ctx.lineTo(0, 0 - r * m);
ctx.rotate(Math.PI / p);
ctx.lineTo(0, 0 - r);
}
}
var Shape = /** @class */ (function (_super) {
__extends(Shape, _super);
function Shape() {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* 获取形状数据
*/
Shape.prototype.getShapeData = function () {
var shape = this.options.shape;
var defaultShapeData = { type: 'circle' };
if (!shape) {
return defaultShapeData;
}
if (utils_1.isArray(shape)) {
var length_1 = shape.length;
if (length_1) {
var value = shape[Math.floor(Math.random() * length_1)];
return generateShapeData(value);
}
return defaultShapeData;
}
return generateShapeData(shape);
};
/**
* 绘制形状
*/
Shape.prototype.drawShape = function (data) {
var _a = data.shape, type = _a.type, isImageLoaded = _a.isImageLoaded, source = _a.source, sides = _a.sides, dent = _a.dent;
if (validShapeTypes.indexOf(type) === -1) {
return;
}
if (type === 'image' && (!isImageLoaded || !source)) {
return;
}
this.ctx.save();
// 旋转渲染
this.ctx.translate(data.x, data.y);
this.ctx.rotate(data.rotate * constants_1.piBy180);
if (type === 'image') {
var width = data.r * 2;
this.ctx.drawImage(source, 0, 0, source.width || width, source.height || width, -data.r, -data.r, width, width);
}
else {
this.ctx.beginPath();
switch (data.shape.type) {
case 'circle':
this.ctx.arc(0, 0, data.r, 0, constants_1.doublePi);
break;
case 'triangle':
drawStar(this.ctx, 0, 0, data.r, 3, 0.5);
break;
case 'star':
drawStar(this.ctx, 0, 0, data.r, sides, dent);
break;
}
this.ctx.fillStyle = data.color;
this.ctx.fill();
}
this.ctx.restore();
};
return Shape;
}(base_1.default));
exports.default = Shape;