@tsparticles/effect-trail 4.0.0-alpha.8 → 4.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/827.min.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";(this.webpackChunk_tsparticles_effect_trail=this.webpackChunk_tsparticles_effect_trail||[]).push([[827],{827(t,a,i){i.d(a,{TrailDrawer:()=>r});var e=i(303);let l={a:1,b:0,c:0,d:1};class r{_container;constructor(t){this._container=t}drawAfter(t){let{context:a,drawPosition:i,drawRadius:r,drawScale:n,particle:h,transformData:o}=t,s=this._container,d=r*e.double,c=s.retina.pixelRatio,f=h.trail;if(!f||!h.trailLength)return;let g=h.trailLength*n+r;if(f.push({color:a.fillStyle||a.strokeStyle,position:{x:i.x,y:i.y},transformData:o}),f.length<3)return;let x=Math.floor(g);f.length>x&&f.splice(0,f.length-x);let p=Math.min(f.length,g),u={width:s.canvas.size.width*n+d,height:s.canvas.size.height*n+d};a.save(),a.lineCap="butt",a.lineJoin="round";for(let t=p-2;t>0;t--){let i=f[t+1],r=f[t],o=f[t-1];if(!i||!r||!o)continue;let s=i.position,x=r.position,y=o.position,b=h.trailTransform?r.transformData??l:l,{distance:m}=(0,e.getDistances)(s,x),{distance:M}=(0,e.getDistances)(x,y);if(m>g*e.double||M>g*e.double||Math.abs(s.x-x.x)>u.width*e.half||Math.abs(s.y-x.y)>u.height*e.half||Math.abs(x.x-y.x)>u.width*e.half||Math.abs(x.y-y.y)>u.height*e.half)continue;a.setTransform(b.a,b.b,b.c,b.d,x.x,x.y);let W=(s.x+x.x)*e.half-x.x,_=(s.y+x.y)*e.half-x.y,v=(x.x+y.x)*e.half-x.x,w=(x.y+y.y)*e.half-x.y;a.beginPath(),a.moveTo(W,_),a.quadraticCurveTo(e.originPoint.x,e.originPoint.y,v,w);let k=Math.max(t/p*d,c,(h.trailMinWidth??-1)*n),R=a.globalAlpha;a.globalAlpha=h.trailFade?t/p:e.defaultAlpha,a.lineWidth=h.trailMaxWidth?Math.min(k,h.trailMaxWidth*n):k,a.strokeStyle=r.color,a.stroke(),a.globalAlpha=R}a.restore()}particleInit(t,a){a.trail=[];let i=a.effectData;a.trailFade=i?.fade??!0,a.trailLength=(0,e.getRangeValue)(i?.length??10)*t.retina.pixelRatio,a.trailMaxWidth=i?.maxWidth?(0,e.getRangeValue)(i.maxWidth)*t.retina.pixelRatio:void 0,a.trailMinWidth=i?.minWidth?(0,e.getRangeValue)(i.minWidth)*t.retina.pixelRatio:void 0,a.trailTransform=i?.transform??!1}}}}]);
@@ -1,5 +1,5 @@
1
- import { defaultAlpha, double, getRangeValue, half, none, originPoint, } from "@tsparticles/engine";
2
- const minTrailLength = 2, trailLengthOffset = 1, minWidth = -1, defaultLength = 10;
1
+ import { defaultAlpha, double, getDistances, getRangeValue, half, originPoint, } from "@tsparticles/engine";
2
+ const minTrailLength = 3, trailLengthOffset = 1, minWidth = -1, firstIndex = 0, defaultLength = 10, loopTrailLengthOffset = 2, loopTrailLengthMinIndex = 0;
3
3
  const defaultTransform = {
4
4
  a: 1,
5
5
  b: 0,
@@ -7,12 +7,16 @@ const defaultTransform = {
7
7
  d: 1,
8
8
  };
9
9
  export class TrailDrawer {
10
+ _container;
11
+ constructor(container) {
12
+ this._container = container;
13
+ }
10
14
  drawAfter(data) {
11
- const { context, radius, particle, transformData } = data, diameter = radius * double, pxRatio = particle.container.retina.pixelRatio, currentPos = particle.getPosition(), trail = particle.trail;
15
+ const { context, drawPosition, drawRadius, drawScale, particle, transformData } = data, container = this._container, diameter = drawRadius * double, pxRatio = container.retina.pixelRatio, trail = particle.trail;
12
16
  if (!trail || !particle.trailLength) {
13
17
  return;
14
18
  }
15
- const pathLength = particle.trailLength + radius;
19
+ const currentPos = drawPosition, pathLength = particle.trailLength * drawScale + drawRadius;
16
20
  trail.push({
17
21
  color: context.fillStyle || context.strokeStyle,
18
22
  position: {
@@ -24,46 +28,45 @@ export class TrailDrawer {
24
28
  if (trail.length < minTrailLength) {
25
29
  return;
26
30
  }
27
- while (trail.length > pathLength) {
28
- trail.shift();
31
+ const pathLengthFloor = Math.floor(pathLength);
32
+ if (trail.length > pathLengthFloor) {
33
+ trail.splice(firstIndex, trail.length - pathLengthFloor);
29
34
  }
30
35
  const trailLength = Math.min(trail.length, pathLength), canvasSize = {
31
- width: particle.container.canvas.size.width + diameter,
32
- height: particle.container.canvas.size.height + diameter,
36
+ width: container.canvas.size.width * drawScale + diameter,
37
+ height: container.canvas.size.height * drawScale + diameter,
33
38
  };
34
- const trailPos = trail[trailLength - trailLengthOffset];
35
- if (!trailPos) {
36
- return;
37
- }
38
- let lastPos = trailPos.position;
39
- for (let i = trailLength; i > none; i--) {
40
- const step = trail[i - trailLengthOffset];
41
- if (!step) {
39
+ context.save();
40
+ context.lineCap = "butt";
41
+ context.lineJoin = "round";
42
+ for (let i = trailLength - loopTrailLengthOffset; i > loopTrailLengthMinIndex; i--) {
43
+ const previousStep = trail[i + trailLengthOffset], step = trail[i], nextStep = trail[i - trailLengthOffset];
44
+ if (!previousStep || !step || !nextStep) {
42
45
  continue;
43
46
  }
44
- const position = step.position, stepTransformData = particle.trailTransform ? (step.transformData ?? defaultTransform) : defaultTransform;
45
- context.setTransform(stepTransformData.a, stepTransformData.b, stepTransformData.c, stepTransformData.d, position.x, position.y);
46
- context.beginPath();
47
- context.moveTo(lastPos.x - position.x, lastPos.y - position.y);
48
- const warp = {
49
- x: (lastPos.x + canvasSize.width) % canvasSize.width,
50
- y: (lastPos.y + canvasSize.height) % canvasSize.height,
51
- };
52
- if (Math.abs(lastPos.x - position.x) > canvasSize.width * half ||
53
- Math.abs(lastPos.y - position.y) > canvasSize.height * half) {
54
- lastPos = position;
47
+ const previousPosition = previousStep.position, position = step.position, nextPosition = nextStep.position, stepTransformData = particle.trailTransform ? (step.transformData ?? defaultTransform) : defaultTransform, { distance: previousDistance } = getDistances(previousPosition, position), { distance: nextDistance } = getDistances(position, nextPosition);
48
+ if (previousDistance > pathLength * double || nextDistance > pathLength * double) {
55
49
  continue;
56
50
  }
57
- context.lineTo(Math.abs(lastPos.x - position.x) > canvasSize.width * half ? warp.x : originPoint.x, Math.abs(lastPos.y - position.y) > canvasSize.height * half ? warp.y : originPoint.y);
58
- const width = Math.max((i / trailLength) * diameter, pxRatio, particle.trailMinWidth ?? minWidth), oldAlpha = context.globalAlpha;
51
+ if (Math.abs(previousPosition.x - position.x) > canvasSize.width * half ||
52
+ Math.abs(previousPosition.y - position.y) > canvasSize.height * half ||
53
+ Math.abs(position.x - nextPosition.x) > canvasSize.width * half ||
54
+ Math.abs(position.y - nextPosition.y) > canvasSize.height * half) {
55
+ continue;
56
+ }
57
+ context.setTransform(stepTransformData.a, stepTransformData.b, stepTransformData.c, stepTransformData.d, position.x, position.y);
58
+ const startX = (previousPosition.x + position.x) * half - position.x, startY = (previousPosition.y + position.y) * half - position.y, endX = (position.x + nextPosition.x) * half - position.x, endY = (position.y + nextPosition.y) * half - position.y;
59
+ context.beginPath();
60
+ context.moveTo(startX, startY);
61
+ context.quadraticCurveTo(originPoint.x, originPoint.y, endX, endY);
62
+ const width = Math.max((i / trailLength) * diameter, pxRatio, (particle.trailMinWidth ?? minWidth) * drawScale), oldAlpha = context.globalAlpha;
59
63
  context.globalAlpha = particle.trailFade ? i / trailLength : defaultAlpha;
60
- context.lineWidth = particle.trailMaxWidth ? Math.min(width, particle.trailMaxWidth) : width;
64
+ context.lineWidth = particle.trailMaxWidth ? Math.min(width, particle.trailMaxWidth * drawScale) : width;
61
65
  context.strokeStyle = step.color;
62
66
  context.stroke();
63
67
  context.globalAlpha = oldAlpha;
64
- lastPos = position;
65
68
  }
66
- context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, currentPos.x, currentPos.y);
69
+ context.restore();
67
70
  }
68
71
  particleInit(container, particle) {
69
72
  particle.trail = [];
package/browser/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  export async function loadTrailEffect(engine) {
2
- engine.checkVersion("4.0.0-alpha.8");
3
- await engine.register(async (e) => {
4
- const { TrailDrawer } = await import("./TrailDrawer.js");
5
- e.addEffect("trail", new TrailDrawer());
2
+ engine.checkVersion("4.0.0-beta.1");
3
+ await engine.pluginManager.register(e => {
4
+ e.pluginManager.addEffect("trail", async (container) => {
5
+ const { TrailDrawer } = await import("./TrailDrawer.js");
6
+ return new TrailDrawer(container);
7
+ });
6
8
  });
7
9
  }
@@ -1,5 +1,5 @@
1
- import { defaultAlpha, double, getRangeValue, half, none, originPoint, } from "@tsparticles/engine";
2
- const minTrailLength = 2, trailLengthOffset = 1, minWidth = -1, defaultLength = 10;
1
+ import { defaultAlpha, double, getDistances, getRangeValue, half, originPoint, } from "@tsparticles/engine";
2
+ const minTrailLength = 3, trailLengthOffset = 1, minWidth = -1, firstIndex = 0, defaultLength = 10, loopTrailLengthOffset = 2, loopTrailLengthMinIndex = 0;
3
3
  const defaultTransform = {
4
4
  a: 1,
5
5
  b: 0,
@@ -7,12 +7,16 @@ const defaultTransform = {
7
7
  d: 1,
8
8
  };
9
9
  export class TrailDrawer {
10
+ _container;
11
+ constructor(container) {
12
+ this._container = container;
13
+ }
10
14
  drawAfter(data) {
11
- const { context, radius, particle, transformData } = data, diameter = radius * double, pxRatio = particle.container.retina.pixelRatio, currentPos = particle.getPosition(), trail = particle.trail;
15
+ const { context, drawPosition, drawRadius, drawScale, particle, transformData } = data, container = this._container, diameter = drawRadius * double, pxRatio = container.retina.pixelRatio, trail = particle.trail;
12
16
  if (!trail || !particle.trailLength) {
13
17
  return;
14
18
  }
15
- const pathLength = particle.trailLength + radius;
19
+ const currentPos = drawPosition, pathLength = particle.trailLength * drawScale + drawRadius;
16
20
  trail.push({
17
21
  color: context.fillStyle || context.strokeStyle,
18
22
  position: {
@@ -24,46 +28,45 @@ export class TrailDrawer {
24
28
  if (trail.length < minTrailLength) {
25
29
  return;
26
30
  }
27
- while (trail.length > pathLength) {
28
- trail.shift();
31
+ const pathLengthFloor = Math.floor(pathLength);
32
+ if (trail.length > pathLengthFloor) {
33
+ trail.splice(firstIndex, trail.length - pathLengthFloor);
29
34
  }
30
35
  const trailLength = Math.min(trail.length, pathLength), canvasSize = {
31
- width: particle.container.canvas.size.width + diameter,
32
- height: particle.container.canvas.size.height + diameter,
36
+ width: container.canvas.size.width * drawScale + diameter,
37
+ height: container.canvas.size.height * drawScale + diameter,
33
38
  };
34
- const trailPos = trail[trailLength - trailLengthOffset];
35
- if (!trailPos) {
36
- return;
37
- }
38
- let lastPos = trailPos.position;
39
- for (let i = trailLength; i > none; i--) {
40
- const step = trail[i - trailLengthOffset];
41
- if (!step) {
39
+ context.save();
40
+ context.lineCap = "butt";
41
+ context.lineJoin = "round";
42
+ for (let i = trailLength - loopTrailLengthOffset; i > loopTrailLengthMinIndex; i--) {
43
+ const previousStep = trail[i + trailLengthOffset], step = trail[i], nextStep = trail[i - trailLengthOffset];
44
+ if (!previousStep || !step || !nextStep) {
42
45
  continue;
43
46
  }
44
- const position = step.position, stepTransformData = particle.trailTransform ? (step.transformData ?? defaultTransform) : defaultTransform;
45
- context.setTransform(stepTransformData.a, stepTransformData.b, stepTransformData.c, stepTransformData.d, position.x, position.y);
46
- context.beginPath();
47
- context.moveTo(lastPos.x - position.x, lastPos.y - position.y);
48
- const warp = {
49
- x: (lastPos.x + canvasSize.width) % canvasSize.width,
50
- y: (lastPos.y + canvasSize.height) % canvasSize.height,
51
- };
52
- if (Math.abs(lastPos.x - position.x) > canvasSize.width * half ||
53
- Math.abs(lastPos.y - position.y) > canvasSize.height * half) {
54
- lastPos = position;
47
+ const previousPosition = previousStep.position, position = step.position, nextPosition = nextStep.position, stepTransformData = particle.trailTransform ? (step.transformData ?? defaultTransform) : defaultTransform, { distance: previousDistance } = getDistances(previousPosition, position), { distance: nextDistance } = getDistances(position, nextPosition);
48
+ if (previousDistance > pathLength * double || nextDistance > pathLength * double) {
55
49
  continue;
56
50
  }
57
- context.lineTo(Math.abs(lastPos.x - position.x) > canvasSize.width * half ? warp.x : originPoint.x, Math.abs(lastPos.y - position.y) > canvasSize.height * half ? warp.y : originPoint.y);
58
- const width = Math.max((i / trailLength) * diameter, pxRatio, particle.trailMinWidth ?? minWidth), oldAlpha = context.globalAlpha;
51
+ if (Math.abs(previousPosition.x - position.x) > canvasSize.width * half ||
52
+ Math.abs(previousPosition.y - position.y) > canvasSize.height * half ||
53
+ Math.abs(position.x - nextPosition.x) > canvasSize.width * half ||
54
+ Math.abs(position.y - nextPosition.y) > canvasSize.height * half) {
55
+ continue;
56
+ }
57
+ context.setTransform(stepTransformData.a, stepTransformData.b, stepTransformData.c, stepTransformData.d, position.x, position.y);
58
+ const startX = (previousPosition.x + position.x) * half - position.x, startY = (previousPosition.y + position.y) * half - position.y, endX = (position.x + nextPosition.x) * half - position.x, endY = (position.y + nextPosition.y) * half - position.y;
59
+ context.beginPath();
60
+ context.moveTo(startX, startY);
61
+ context.quadraticCurveTo(originPoint.x, originPoint.y, endX, endY);
62
+ const width = Math.max((i / trailLength) * diameter, pxRatio, (particle.trailMinWidth ?? minWidth) * drawScale), oldAlpha = context.globalAlpha;
59
63
  context.globalAlpha = particle.trailFade ? i / trailLength : defaultAlpha;
60
- context.lineWidth = particle.trailMaxWidth ? Math.min(width, particle.trailMaxWidth) : width;
64
+ context.lineWidth = particle.trailMaxWidth ? Math.min(width, particle.trailMaxWidth * drawScale) : width;
61
65
  context.strokeStyle = step.color;
62
66
  context.stroke();
63
67
  context.globalAlpha = oldAlpha;
64
- lastPos = position;
65
68
  }
66
- context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, currentPos.x, currentPos.y);
69
+ context.restore();
67
70
  }
68
71
  particleInit(container, particle) {
69
72
  particle.trail = [];
package/cjs/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  export async function loadTrailEffect(engine) {
2
- engine.checkVersion("4.0.0-alpha.8");
3
- await engine.register(async (e) => {
4
- const { TrailDrawer } = await import("./TrailDrawer.js");
5
- e.addEffect("trail", new TrailDrawer());
2
+ engine.checkVersion("4.0.0-beta.1");
3
+ await engine.pluginManager.register(e => {
4
+ e.pluginManager.addEffect("trail", async (container) => {
5
+ const { TrailDrawer } = await import("./TrailDrawer.js");
6
+ return new TrailDrawer(container);
7
+ });
6
8
  });
7
9
  }
@@ -4,7 +4,7 @@
4
4
  * Demo / Generator : https://particles.js.org/
5
5
  * GitHub : https://www.github.com/matteobruni/tsparticles
6
6
  * How to use? : Check the GitHub README
7
- * v4.0.0-alpha.8
7
+ * v4.0.0-beta.1
8
8
  */
9
9
  "use strict";
10
10
  /*
@@ -23,7 +23,7 @@
23
23
  \*************************************/
24
24
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
25
25
 
26
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ TrailDrawer: () => (/* binding */ TrailDrawer)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nconst minTrailLength = 2,\n trailLengthOffset = 1,\n minWidth = -1,\n defaultLength = 10;\nconst defaultTransform = {\n a: 1,\n b: 0,\n c: 0,\n d: 1\n};\nclass TrailDrawer {\n drawAfter(data) {\n const {\n context,\n radius,\n particle,\n transformData\n } = data,\n diameter = radius * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.double,\n pxRatio = particle.container.retina.pixelRatio,\n currentPos = particle.getPosition(),\n trail = particle.trail;\n if (!trail || !particle.trailLength) {\n return;\n }\n const pathLength = particle.trailLength + radius;\n trail.push({\n color: context.fillStyle || context.strokeStyle,\n position: {\n x: currentPos.x,\n y: currentPos.y\n },\n transformData\n });\n if (trail.length < minTrailLength) {\n return;\n }\n while (trail.length > pathLength) {\n trail.shift();\n }\n const trailLength = Math.min(trail.length, pathLength),\n canvasSize = {\n width: particle.container.canvas.size.width + diameter,\n height: particle.container.canvas.size.height + diameter\n };\n const trailPos = trail[trailLength - trailLengthOffset];\n if (!trailPos) {\n return;\n }\n let lastPos = trailPos.position;\n for (let i = trailLength; i > _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.none; i--) {\n const step = trail[i - trailLengthOffset];\n if (!step) {\n continue;\n }\n const position = step.position,\n stepTransformData = particle.trailTransform ? step.transformData ?? defaultTransform : defaultTransform;\n context.setTransform(stepTransformData.a, stepTransformData.b, stepTransformData.c, stepTransformData.d, position.x, position.y);\n context.beginPath();\n context.moveTo(lastPos.x - position.x, lastPos.y - position.y);\n const warp = {\n x: (lastPos.x + canvasSize.width) % canvasSize.width,\n y: (lastPos.y + canvasSize.height) % canvasSize.height\n };\n if (Math.abs(lastPos.x - position.x) > canvasSize.width * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half || Math.abs(lastPos.y - position.y) > canvasSize.height * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half) {\n lastPos = position;\n continue;\n }\n context.lineTo(Math.abs(lastPos.x - position.x) > canvasSize.width * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half ? warp.x : _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.x, Math.abs(lastPos.y - position.y) > canvasSize.height * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half ? warp.y : _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.y);\n const width = Math.max(i / trailLength * diameter, pxRatio, particle.trailMinWidth ?? minWidth),\n oldAlpha = context.globalAlpha;\n context.globalAlpha = particle.trailFade ? i / trailLength : _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.defaultAlpha;\n context.lineWidth = particle.trailMaxWidth ? Math.min(width, particle.trailMaxWidth) : width;\n context.strokeStyle = step.color;\n context.stroke();\n context.globalAlpha = oldAlpha;\n lastPos = position;\n }\n context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, currentPos.x, currentPos.y);\n }\n particleInit(container, particle) {\n particle.trail = [];\n const effectData = particle.effectData;\n particle.trailFade = effectData?.fade ?? true;\n particle.trailLength = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeValue)(effectData?.length ?? defaultLength) * container.retina.pixelRatio;\n particle.trailMaxWidth = effectData?.maxWidth ? (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeValue)(effectData.maxWidth) * container.retina.pixelRatio : undefined;\n particle.trailMinWidth = effectData?.minWidth ? (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeValue)(effectData.minWidth) * container.retina.pixelRatio : undefined;\n particle.trailTransform = effectData?.transform ?? false;\n }\n}\n\n//# sourceURL=webpack://@tsparticles/effect-trail/./dist/browser/TrailDrawer.js?\n}");
26
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ TrailDrawer: () => (/* binding */ TrailDrawer)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nconst minTrailLength = 3, trailLengthOffset = 1, minWidth = -1, firstIndex = 0, defaultLength = 10, loopTrailLengthOffset = 2, loopTrailLengthMinIndex = 0;\nconst defaultTransform = {\n a: 1,\n b: 0,\n c: 0,\n d: 1\n};\nclass TrailDrawer {\n _container;\n constructor(container){\n this._container = container;\n }\n drawAfter(data) {\n const { context, drawPosition, drawRadius, drawScale, particle, transformData } = data, container = this._container, diameter = drawRadius * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.double, pxRatio = container.retina.pixelRatio, trail = particle.trail;\n if (!trail || !particle.trailLength) {\n return;\n }\n const currentPos = drawPosition, pathLength = particle.trailLength * drawScale + drawRadius;\n trail.push({\n color: context.fillStyle || context.strokeStyle,\n position: {\n x: currentPos.x,\n y: currentPos.y\n },\n transformData\n });\n if (trail.length < minTrailLength) {\n return;\n }\n const pathLengthFloor = Math.floor(pathLength);\n if (trail.length > pathLengthFloor) {\n trail.splice(firstIndex, trail.length - pathLengthFloor);\n }\n const trailLength = Math.min(trail.length, pathLength), canvasSize = {\n width: container.canvas.size.width * drawScale + diameter,\n height: container.canvas.size.height * drawScale + diameter\n };\n context.save();\n context.lineCap = \"butt\";\n context.lineJoin = \"round\";\n for(let i = trailLength - loopTrailLengthOffset; i > loopTrailLengthMinIndex; i--){\n const previousStep = trail[i + trailLengthOffset], step = trail[i], nextStep = trail[i - trailLengthOffset];\n if (!previousStep || !step || !nextStep) {\n continue;\n }\n const previousPosition = previousStep.position, position = step.position, nextPosition = nextStep.position, stepTransformData = particle.trailTransform ? step.transformData ?? defaultTransform : defaultTransform, { distance: previousDistance } = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistances)(previousPosition, position), { distance: nextDistance } = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistances)(position, nextPosition);\n if (previousDistance > pathLength * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.double || nextDistance > pathLength * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.double) {\n continue;\n }\n if (Math.abs(previousPosition.x - position.x) > canvasSize.width * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half || Math.abs(previousPosition.y - position.y) > canvasSize.height * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half || Math.abs(position.x - nextPosition.x) > canvasSize.width * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half || Math.abs(position.y - nextPosition.y) > canvasSize.height * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half) {\n continue;\n }\n context.setTransform(stepTransformData.a, stepTransformData.b, stepTransformData.c, stepTransformData.d, position.x, position.y);\n const startX = (previousPosition.x + position.x) * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half - position.x, startY = (previousPosition.y + position.y) * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half - position.y, endX = (position.x + nextPosition.x) * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half - position.x, endY = (position.y + nextPosition.y) * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half - position.y;\n context.beginPath();\n context.moveTo(startX, startY);\n context.quadraticCurveTo(_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.x, _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.y, endX, endY);\n const width = Math.max(i / trailLength * diameter, pxRatio, (particle.trailMinWidth ?? minWidth) * drawScale), oldAlpha = context.globalAlpha;\n context.globalAlpha = particle.trailFade ? i / trailLength : _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.defaultAlpha;\n context.lineWidth = particle.trailMaxWidth ? Math.min(width, particle.trailMaxWidth * drawScale) : width;\n context.strokeStyle = step.color;\n context.stroke();\n context.globalAlpha = oldAlpha;\n }\n context.restore();\n }\n particleInit(container, particle) {\n particle.trail = [];\n const effectData = particle.effectData;\n particle.trailFade = effectData?.fade ?? true;\n particle.trailLength = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeValue)(effectData?.length ?? defaultLength) * container.retina.pixelRatio;\n particle.trailMaxWidth = effectData?.maxWidth ? (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeValue)(effectData.maxWidth) * container.retina.pixelRatio : undefined;\n particle.trailMinWidth = effectData?.minWidth ? (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeValue)(effectData.minWidth) * container.retina.pixelRatio : undefined;\n particle.trailTransform = effectData?.transform ?? false;\n }\n}\n\n\n//# sourceURL=webpack://@tsparticles/effect-trail/./dist/browser/TrailDrawer.js?\n}");
27
27
 
28
28
  /***/ }
29
29
 
@@ -1,5 +1,5 @@
1
- import { defaultAlpha, double, getRangeValue, half, none, originPoint, } from "@tsparticles/engine";
2
- const minTrailLength = 2, trailLengthOffset = 1, minWidth = -1, defaultLength = 10;
1
+ import { defaultAlpha, double, getDistances, getRangeValue, half, originPoint, } from "@tsparticles/engine";
2
+ const minTrailLength = 3, trailLengthOffset = 1, minWidth = -1, firstIndex = 0, defaultLength = 10, loopTrailLengthOffset = 2, loopTrailLengthMinIndex = 0;
3
3
  const defaultTransform = {
4
4
  a: 1,
5
5
  b: 0,
@@ -7,12 +7,16 @@ const defaultTransform = {
7
7
  d: 1,
8
8
  };
9
9
  export class TrailDrawer {
10
+ _container;
11
+ constructor(container) {
12
+ this._container = container;
13
+ }
10
14
  drawAfter(data) {
11
- const { context, radius, particle, transformData } = data, diameter = radius * double, pxRatio = particle.container.retina.pixelRatio, currentPos = particle.getPosition(), trail = particle.trail;
15
+ const { context, drawPosition, drawRadius, drawScale, particle, transformData } = data, container = this._container, diameter = drawRadius * double, pxRatio = container.retina.pixelRatio, trail = particle.trail;
12
16
  if (!trail || !particle.trailLength) {
13
17
  return;
14
18
  }
15
- const pathLength = particle.trailLength + radius;
19
+ const currentPos = drawPosition, pathLength = particle.trailLength * drawScale + drawRadius;
16
20
  trail.push({
17
21
  color: context.fillStyle || context.strokeStyle,
18
22
  position: {
@@ -24,46 +28,45 @@ export class TrailDrawer {
24
28
  if (trail.length < minTrailLength) {
25
29
  return;
26
30
  }
27
- while (trail.length > pathLength) {
28
- trail.shift();
31
+ const pathLengthFloor = Math.floor(pathLength);
32
+ if (trail.length > pathLengthFloor) {
33
+ trail.splice(firstIndex, trail.length - pathLengthFloor);
29
34
  }
30
35
  const trailLength = Math.min(trail.length, pathLength), canvasSize = {
31
- width: particle.container.canvas.size.width + diameter,
32
- height: particle.container.canvas.size.height + diameter,
36
+ width: container.canvas.size.width * drawScale + diameter,
37
+ height: container.canvas.size.height * drawScale + diameter,
33
38
  };
34
- const trailPos = trail[trailLength - trailLengthOffset];
35
- if (!trailPos) {
36
- return;
37
- }
38
- let lastPos = trailPos.position;
39
- for (let i = trailLength; i > none; i--) {
40
- const step = trail[i - trailLengthOffset];
41
- if (!step) {
39
+ context.save();
40
+ context.lineCap = "butt";
41
+ context.lineJoin = "round";
42
+ for (let i = trailLength - loopTrailLengthOffset; i > loopTrailLengthMinIndex; i--) {
43
+ const previousStep = trail[i + trailLengthOffset], step = trail[i], nextStep = trail[i - trailLengthOffset];
44
+ if (!previousStep || !step || !nextStep) {
42
45
  continue;
43
46
  }
44
- const position = step.position, stepTransformData = particle.trailTransform ? (step.transformData ?? defaultTransform) : defaultTransform;
45
- context.setTransform(stepTransformData.a, stepTransformData.b, stepTransformData.c, stepTransformData.d, position.x, position.y);
46
- context.beginPath();
47
- context.moveTo(lastPos.x - position.x, lastPos.y - position.y);
48
- const warp = {
49
- x: (lastPos.x + canvasSize.width) % canvasSize.width,
50
- y: (lastPos.y + canvasSize.height) % canvasSize.height,
51
- };
52
- if (Math.abs(lastPos.x - position.x) > canvasSize.width * half ||
53
- Math.abs(lastPos.y - position.y) > canvasSize.height * half) {
54
- lastPos = position;
47
+ const previousPosition = previousStep.position, position = step.position, nextPosition = nextStep.position, stepTransformData = particle.trailTransform ? (step.transformData ?? defaultTransform) : defaultTransform, { distance: previousDistance } = getDistances(previousPosition, position), { distance: nextDistance } = getDistances(position, nextPosition);
48
+ if (previousDistance > pathLength * double || nextDistance > pathLength * double) {
55
49
  continue;
56
50
  }
57
- context.lineTo(Math.abs(lastPos.x - position.x) > canvasSize.width * half ? warp.x : originPoint.x, Math.abs(lastPos.y - position.y) > canvasSize.height * half ? warp.y : originPoint.y);
58
- const width = Math.max((i / trailLength) * diameter, pxRatio, particle.trailMinWidth ?? minWidth), oldAlpha = context.globalAlpha;
51
+ if (Math.abs(previousPosition.x - position.x) > canvasSize.width * half ||
52
+ Math.abs(previousPosition.y - position.y) > canvasSize.height * half ||
53
+ Math.abs(position.x - nextPosition.x) > canvasSize.width * half ||
54
+ Math.abs(position.y - nextPosition.y) > canvasSize.height * half) {
55
+ continue;
56
+ }
57
+ context.setTransform(stepTransformData.a, stepTransformData.b, stepTransformData.c, stepTransformData.d, position.x, position.y);
58
+ const startX = (previousPosition.x + position.x) * half - position.x, startY = (previousPosition.y + position.y) * half - position.y, endX = (position.x + nextPosition.x) * half - position.x, endY = (position.y + nextPosition.y) * half - position.y;
59
+ context.beginPath();
60
+ context.moveTo(startX, startY);
61
+ context.quadraticCurveTo(originPoint.x, originPoint.y, endX, endY);
62
+ const width = Math.max((i / trailLength) * diameter, pxRatio, (particle.trailMinWidth ?? minWidth) * drawScale), oldAlpha = context.globalAlpha;
59
63
  context.globalAlpha = particle.trailFade ? i / trailLength : defaultAlpha;
60
- context.lineWidth = particle.trailMaxWidth ? Math.min(width, particle.trailMaxWidth) : width;
64
+ context.lineWidth = particle.trailMaxWidth ? Math.min(width, particle.trailMaxWidth * drawScale) : width;
61
65
  context.strokeStyle = step.color;
62
66
  context.stroke();
63
67
  context.globalAlpha = oldAlpha;
64
- lastPos = position;
65
68
  }
66
- context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, currentPos.x, currentPos.y);
69
+ context.restore();
67
70
  }
68
71
  particleInit(container, particle) {
69
72
  particle.trail = [];
package/esm/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  export async function loadTrailEffect(engine) {
2
- engine.checkVersion("4.0.0-alpha.8");
3
- await engine.register(async (e) => {
4
- const { TrailDrawer } = await import("./TrailDrawer.js");
5
- e.addEffect("trail", new TrailDrawer());
2
+ engine.checkVersion("4.0.0-beta.1");
3
+ await engine.pluginManager.register(e => {
4
+ e.pluginManager.addEffect("trail", async (container) => {
5
+ const { TrailDrawer } = await import("./TrailDrawer.js");
6
+ return new TrailDrawer(container);
7
+ });
6
8
  });
7
9
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsparticles/effect-trail",
3
- "version": "4.0.0-alpha.8",
3
+ "version": "4.0.0-beta.1",
4
4
  "description": "tsParticles trail effect",
5
5
  "homepage": "https://particles.js.org",
6
6
  "repository": {
@@ -100,7 +100,7 @@
100
100
  "./package.json": "./package.json"
101
101
  },
102
102
  "dependencies": {
103
- "@tsparticles/engine": "4.0.0-alpha.8"
103
+ "@tsparticles/engine": "4.0.0-beta.1"
104
104
  },
105
105
  "publishConfig": {
106
106
  "access": "public"