UNPKG

tsparticles

Version:

Porting of the abandoned Vincent Garreau's particles.js, converted in TypeScript. Added many new cool features and various bug fixes.

244 lines (243 loc) 9.48 kB
import { Constants } from "./Utils/Constants"; import { Utils } from "./Utils/Utils"; import { CanvasUtils } from "./Utils/CanvasUtils"; import { ColorUtils } from "./Utils/ColorUtils"; export class Canvas { constructor(container) { this.container = container; this.dimension = { height: 0, width: 0, }; this.context = null; this.generatedCanvas = false; } init() { this.size(); const container = this.container; const options = container.options; const cover = options.backgroundMask.cover; const trail = options.particles.move.trail; this.coverColor = ColorUtils.colorToRgb(cover.color !== undefined ? cover.color : options.backgroundMask.cover); this.trailFillColor = typeof trail.fillColor === "string" ? ColorUtils.stringToRgb(trail.fillColor) : ColorUtils.colorToRgb(trail.fillColor); this.paint(); } loadCanvas(canvas, generatedCanvas) { var _a; if (!canvas.className) { canvas.className = Constants.canvasClass; } if (this.generatedCanvas) { (_a = this.element) === null || _a === void 0 ? void 0 : _a.remove(); } this.generatedCanvas = generatedCanvas !== null && generatedCanvas !== void 0 ? generatedCanvas : false; this.element = canvas; this.dimension.height = canvas.offsetHeight; this.dimension.width = canvas.offsetWidth; this.context = this.element.getContext("2d"); this.container.retina.init(); this.initBackground(); } destroy() { var _a; if (this.generatedCanvas) { (_a = this.element) === null || _a === void 0 ? void 0 : _a.remove(); } if (this.context) { CanvasUtils.clear(this.context, this.dimension); } } size() { if (this.element) { this.element.width = this.dimension.width; this.element.height = this.dimension.height; } } paint() { const container = this.container; const options = container.options; if (this.context) { if (options.backgroundMask.enable && options.backgroundMask.cover) { if (this.coverColor) { this.paintBase(ColorUtils.getStyleFromColor(this.coverColor)); } else { this.paintBase(); } } else { this.paintBase(); } } } clear() { const container = this.container; const options = container.options; const trail = options.particles.move.trail; if (options.backgroundMask.enable) { this.paint(); } else if (trail.enable && trail.length > 0 && this.trailFillColor) { this.paintBase(ColorUtils.getStyleFromColor(this.trailFillColor, 1 / trail.length)); } else if (this.context) { CanvasUtils.clear(this.context, this.dimension); } } isPointInPath(path, point) { var _a, _b; return (_b = (_a = this.context) === null || _a === void 0 ? void 0 : _a.isPointInPath(path, point.x, point.y)) !== null && _b !== void 0 ? _b : false; } drawPolygonMask() { const container = this.container; const options = container.options; const context = this.context; const polygonDraw = options.polygon.draw; const polygon = container.polygon; const rawData = polygon.raw; const path = polygon.polygonPath; const path2dSupported = polygon.path2DSupported; if (context) { if (path2dSupported && path && polygon.offset) { CanvasUtils.drawPolygonMaskPath(context, path, polygonDraw.stroke, polygon.offset); } else if (rawData) { CanvasUtils.drawPolygonMask(context, rawData, polygonDraw.stroke); } } } drawLinkedLine(p1, p2, pos1, pos2, opacity) { const container = this.container; const options = container.options; const ctx = this.context; if (!ctx) { return; } let colorLine; if (container.particles.lineLinkedColor === Constants.randomColorValue) { colorLine = ColorUtils.getRandomRgbColor(); } else if (container.particles.lineLinkedColor == "mid" && p1.color && p2.color) { const sourceColor = p1.color; const destColor = p2.color; colorLine = { b: Math.floor(Utils.mix(sourceColor.b, destColor.b, p1.radius, p2.radius)), g: Math.floor(Utils.mix(sourceColor.g, destColor.g, p1.radius, p2.radius)), r: Math.floor(Utils.mix(sourceColor.r, destColor.r, p1.radius, p2.radius)), }; } else { colorLine = container.particles.lineLinkedColor; } const width = container.retina.lineLinkedWidth; CanvasUtils.drawLineLinked(ctx, width, pos1, pos2, options.backgroundMask.enable, colorLine, opacity, options.particles.lineLinked.shadow); } drawConnectLine(p1, p2) { const lineStyle = this.lineStyle(p1, p2); if (!lineStyle) { return; } const ctx = this.context; if (!ctx) { return; } CanvasUtils.drawConnectLine(ctx, this.container.retina.lineLinkedWidth, lineStyle, p1.position, p2.position); } drawGrabLine(particle, opacity, mousePos) { const container = this.container; const options = container.options; const optColor = options.particles.lineLinked.color; let lineColor = container.particles.lineLinkedColor || (typeof optColor === "string" ? ColorUtils.stringToRgb(optColor) : ColorUtils.colorToRgb(optColor)); if (lineColor == Constants.randomColorValue) { lineColor = ColorUtils.getRandomRgbColor(); } container.particles.lineLinkedColor = lineColor; let colorLine = { r: 127, g: 127, b: 127 }; const ctx = container.canvas.context; if (!ctx) { return; } if (container.particles.lineLinkedColor == Constants.randomColorValue) { colorLine = ColorUtils.getRandomRgbColor() || colorLine; } else { colorLine = container.particles.lineLinkedColor || colorLine; } const beginPos = { x: particle.position.x + particle.offset.x, y: particle.position.y + particle.offset.y, }; CanvasUtils.drawGrabLine(ctx, container.retina.lineLinkedWidth, beginPos, mousePos, colorLine, opacity); } drawParticle(particle) { const container = this.container; const options = container.options; let colorValue; const radius = particle.bubbler.radius !== undefined ? particle.bubbler.radius : particle.radius; const opacity = particle.bubbler.opacity !== undefined ? particle.bubbler.opacity : particle.opacity.value; if (particle.color) { colorValue = ColorUtils.getStyleFromColor(particle.color, opacity); } if (!this.context || !colorValue) { return; } CanvasUtils.drawParticle(this.context, particle, colorValue, options.backgroundMask.enable, radius, opacity); } paintBase(baseColor) { if (this.context) { CanvasUtils.paintBase(this.context, this.dimension, baseColor); } } lineStyle(p1, p2) { const container = this.container; const options = container.options; const connectOptions = options.interactivity.modes.connect; if (p1.color && p2.color) { const sourceRgb = p1.color; const destRgb = p2.color; const midRgb = { b: Utils.mix(sourceRgb.b, destRgb.b, p1.radius, p2.radius), g: Utils.mix(sourceRgb.g, destRgb.g, p1.radius, p2.radius), r: Utils.mix(sourceRgb.r, destRgb.r, p1.radius, p2.radius), }; if (this.context) { return CanvasUtils.gradient(this.context, p1, p2, midRgb, connectOptions.lineLinked.opacity); } } } initBackground() { const container = this.container; const options = container.options; const background = options.background; const element = this.element; if (!element) { return; } const elementStyle = element.style; if (background.color) { const color = typeof background.color === "string" ? ColorUtils.stringToRgb(background.color) : ColorUtils.colorToRgb(background.color); if (color) { elementStyle.backgroundColor = ColorUtils.getStyleFromColor(color, background.opacity); } } if (background.image) { elementStyle.backgroundImage = background.image; } if (background.position) { elementStyle.backgroundPosition = background.position; } if (background.repeat) { elementStyle.backgroundRepeat = background.repeat; } if (background.size) { elementStyle.backgroundSize = background.size; } } }