@tsparticles/effect-trail 4.0.0-alpha.5 → 4.0.0-beta.0

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/543.min.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";(this.webpackChunk_tsparticles_effect_trail=this.webpackChunk_tsparticles_effect_trail||[]).push([[543],{543(t,a,i){i.d(a,{TrailDrawer:()=>n});var e=i(303);let l={a:1,b:0,c:0,d:1};class n{drawAfter(t){let{context:a,drawPosition:i,drawRadius:n,drawScale:r,particle:h,transformData:o}=t,s=n*e.double,d=h.container.retina.pixelRatio,f=h.trail;if(!f||!h.trailLength)return;let c=h.trailLength*r+n;if(f.push({color:a.fillStyle||a.strokeStyle,position:{x:i.x,y:i.y},transformData:o}),f.length<3)return;let g=Math.floor(c);f.length>g&&f.splice(0,f.length-g);let x=Math.min(f.length,c),p={width:h.container.canvas.size.width*r+s,height:h.container.canvas.size.height*r+s};a.save(),a.lineCap="butt",a.lineJoin="round";for(let t=x-2;t>0;t--){let i=f[t+1],n=f[t],o=f[t-1];if(!i||!n||!o)continue;let g=i.position,u=n.position,y=o.position,b=h.trailTransform?n.transformData??l:l,{distance:m}=(0,e.getDistances)(g,u),{distance:M}=(0,e.getDistances)(u,y);if(m>c*e.double||M>c*e.double||Math.abs(g.x-u.x)>p.width*e.half||Math.abs(g.y-u.y)>p.height*e.half||Math.abs(u.x-y.x)>p.width*e.half||Math.abs(u.y-y.y)>p.height*e.half)continue;a.setTransform(b.a,b.b,b.c,b.d,u.x,u.y);let W=(g.x+u.x)*e.half-u.x,v=(g.y+u.y)*e.half-u.y,w=(u.x+y.x)*e.half-u.x,k=(u.y+y.y)*e.half-u.y;a.beginPath(),a.moveTo(W,v),a.quadraticCurveTo(e.originPoint.x,e.originPoint.y,w,k);let R=Math.max(t/x*s,d,(h.trailMinWidth??-1)*r),T=a.globalAlpha;a.globalAlpha=h.trailFade?t/x:e.defaultAlpha,a.lineWidth=h.trailMaxWidth?Math.min(R,h.trailMaxWidth*r):R,a.strokeStyle=n.color,a.stroke(),a.globalAlpha=T}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,
@@ -8,11 +8,11 @@ const defaultTransform = {
8
8
  };
9
9
  export class TrailDrawer {
10
10
  drawAfter(data) {
11
- const { context, radius, particle, transformData } = data, diameter = radius * double, pxRatio = particle.container.retina.pixelRatio, currentPos = particle.getPosition(), trail = particle.trail;
11
+ const { context, drawPosition, drawRadius, drawScale, particle, transformData } = data, diameter = drawRadius * double, pxRatio = particle.container.retina.pixelRatio, trail = particle.trail;
12
12
  if (!trail || !particle.trailLength) {
13
13
  return;
14
14
  }
15
- const pathLength = particle.trailLength + radius;
15
+ const currentPos = drawPosition, pathLength = particle.trailLength * drawScale + drawRadius;
16
16
  trail.push({
17
17
  color: context.fillStyle || context.strokeStyle,
18
18
  position: {
@@ -24,48 +24,45 @@ export class TrailDrawer {
24
24
  if (trail.length < minTrailLength) {
25
25
  return;
26
26
  }
27
- while (trail.length > pathLength) {
28
- trail.shift();
27
+ const pathLengthFloor = Math.floor(pathLength);
28
+ if (trail.length > pathLengthFloor) {
29
+ trail.splice(firstIndex, trail.length - pathLengthFloor);
29
30
  }
30
31
  const trailLength = Math.min(trail.length, pathLength), canvasSize = {
31
- width: particle.container.canvas.size.width + diameter,
32
- height: particle.container.canvas.size.height + diameter,
32
+ width: particle.container.canvas.size.width * drawScale + diameter,
33
+ height: particle.container.canvas.size.height * drawScale + diameter,
33
34
  };
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) {
35
+ context.save();
36
+ context.lineCap = "butt";
37
+ context.lineJoin = "round";
38
+ for (let i = trailLength - loopTrailLengthOffset; i > loopTrailLengthMinIndex; i--) {
39
+ const previousStep = trail[i + trailLengthOffset], step = trail[i], nextStep = trail[i - trailLengthOffset];
40
+ if (!previousStep || !step || !nextStep) {
42
41
  continue;
43
42
  }
44
- const position = step.position, stepTransformData = particle.trailTransform
45
- ? (step.transformData ?? defaultTransform)
46
- : defaultTransform;
47
- context.setTransform(stepTransformData.a, stepTransformData.b, stepTransformData.c, stepTransformData.d, position.x, position.y);
48
- context.beginPath();
49
- context.moveTo(lastPos.x - position.x, lastPos.y - position.y);
50
- const warp = {
51
- x: (lastPos.x + canvasSize.width) % canvasSize.width,
52
- y: (lastPos.y + canvasSize.height) % canvasSize.height,
53
- };
54
- if (Math.abs(lastPos.x - position.x) > canvasSize.width * half ||
55
- Math.abs(lastPos.y - position.y) > canvasSize.height * half) {
56
- lastPos = position;
43
+ 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);
44
+ if (previousDistance > pathLength * double || nextDistance > pathLength * double) {
57
45
  continue;
58
46
  }
59
- 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);
60
- const width = Math.max((i / trailLength) * diameter, pxRatio, particle.trailMinWidth ?? minWidth), oldAlpha = context.globalAlpha;
47
+ if (Math.abs(previousPosition.x - position.x) > canvasSize.width * half ||
48
+ Math.abs(previousPosition.y - position.y) > canvasSize.height * half ||
49
+ Math.abs(position.x - nextPosition.x) > canvasSize.width * half ||
50
+ Math.abs(position.y - nextPosition.y) > canvasSize.height * half) {
51
+ continue;
52
+ }
53
+ context.setTransform(stepTransformData.a, stepTransformData.b, stepTransformData.c, stepTransformData.d, position.x, position.y);
54
+ 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;
55
+ context.beginPath();
56
+ context.moveTo(startX, startY);
57
+ context.quadraticCurveTo(originPoint.x, originPoint.y, endX, endY);
58
+ const width = Math.max((i / trailLength) * diameter, pxRatio, (particle.trailMinWidth ?? minWidth) * drawScale), oldAlpha = context.globalAlpha;
61
59
  context.globalAlpha = particle.trailFade ? i / trailLength : defaultAlpha;
62
- context.lineWidth = particle.trailMaxWidth ? Math.min(width, particle.trailMaxWidth) : width;
60
+ context.lineWidth = particle.trailMaxWidth ? Math.min(width, particle.trailMaxWidth * drawScale) : width;
63
61
  context.strokeStyle = step.color;
64
62
  context.stroke();
65
63
  context.globalAlpha = oldAlpha;
66
- lastPos = position;
67
64
  }
68
- context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, currentPos.x, currentPos.y);
65
+ context.restore();
69
66
  }
70
67
  particleInit(container, particle) {
71
68
  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.5");
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.0");
3
+ await engine.register(e => {
4
+ e.addEffect("trail", async () => {
5
+ const { TrailDrawer } = await import("./TrailDrawer.js");
6
+ return new TrailDrawer();
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,
@@ -8,11 +8,11 @@ const defaultTransform = {
8
8
  };
9
9
  export class TrailDrawer {
10
10
  drawAfter(data) {
11
- const { context, radius, particle, transformData } = data, diameter = radius * double, pxRatio = particle.container.retina.pixelRatio, currentPos = particle.getPosition(), trail = particle.trail;
11
+ const { context, drawPosition, drawRadius, drawScale, particle, transformData } = data, diameter = drawRadius * double, pxRatio = particle.container.retina.pixelRatio, trail = particle.trail;
12
12
  if (!trail || !particle.trailLength) {
13
13
  return;
14
14
  }
15
- const pathLength = particle.trailLength + radius;
15
+ const currentPos = drawPosition, pathLength = particle.trailLength * drawScale + drawRadius;
16
16
  trail.push({
17
17
  color: context.fillStyle || context.strokeStyle,
18
18
  position: {
@@ -24,48 +24,45 @@ export class TrailDrawer {
24
24
  if (trail.length < minTrailLength) {
25
25
  return;
26
26
  }
27
- while (trail.length > pathLength) {
28
- trail.shift();
27
+ const pathLengthFloor = Math.floor(pathLength);
28
+ if (trail.length > pathLengthFloor) {
29
+ trail.splice(firstIndex, trail.length - pathLengthFloor);
29
30
  }
30
31
  const trailLength = Math.min(trail.length, pathLength), canvasSize = {
31
- width: particle.container.canvas.size.width + diameter,
32
- height: particle.container.canvas.size.height + diameter,
32
+ width: particle.container.canvas.size.width * drawScale + diameter,
33
+ height: particle.container.canvas.size.height * drawScale + diameter,
33
34
  };
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) {
35
+ context.save();
36
+ context.lineCap = "butt";
37
+ context.lineJoin = "round";
38
+ for (let i = trailLength - loopTrailLengthOffset; i > loopTrailLengthMinIndex; i--) {
39
+ const previousStep = trail[i + trailLengthOffset], step = trail[i], nextStep = trail[i - trailLengthOffset];
40
+ if (!previousStep || !step || !nextStep) {
42
41
  continue;
43
42
  }
44
- const position = step.position, stepTransformData = particle.trailTransform
45
- ? (step.transformData ?? defaultTransform)
46
- : defaultTransform;
47
- context.setTransform(stepTransformData.a, stepTransformData.b, stepTransformData.c, stepTransformData.d, position.x, position.y);
48
- context.beginPath();
49
- context.moveTo(lastPos.x - position.x, lastPos.y - position.y);
50
- const warp = {
51
- x: (lastPos.x + canvasSize.width) % canvasSize.width,
52
- y: (lastPos.y + canvasSize.height) % canvasSize.height,
53
- };
54
- if (Math.abs(lastPos.x - position.x) > canvasSize.width * half ||
55
- Math.abs(lastPos.y - position.y) > canvasSize.height * half) {
56
- lastPos = position;
43
+ 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);
44
+ if (previousDistance > pathLength * double || nextDistance > pathLength * double) {
57
45
  continue;
58
46
  }
59
- 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);
60
- const width = Math.max((i / trailLength) * diameter, pxRatio, particle.trailMinWidth ?? minWidth), oldAlpha = context.globalAlpha;
47
+ if (Math.abs(previousPosition.x - position.x) > canvasSize.width * half ||
48
+ Math.abs(previousPosition.y - position.y) > canvasSize.height * half ||
49
+ Math.abs(position.x - nextPosition.x) > canvasSize.width * half ||
50
+ Math.abs(position.y - nextPosition.y) > canvasSize.height * half) {
51
+ continue;
52
+ }
53
+ context.setTransform(stepTransformData.a, stepTransformData.b, stepTransformData.c, stepTransformData.d, position.x, position.y);
54
+ 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;
55
+ context.beginPath();
56
+ context.moveTo(startX, startY);
57
+ context.quadraticCurveTo(originPoint.x, originPoint.y, endX, endY);
58
+ const width = Math.max((i / trailLength) * diameter, pxRatio, (particle.trailMinWidth ?? minWidth) * drawScale), oldAlpha = context.globalAlpha;
61
59
  context.globalAlpha = particle.trailFade ? i / trailLength : defaultAlpha;
62
- context.lineWidth = particle.trailMaxWidth ? Math.min(width, particle.trailMaxWidth) : width;
60
+ context.lineWidth = particle.trailMaxWidth ? Math.min(width, particle.trailMaxWidth * drawScale) : width;
63
61
  context.strokeStyle = step.color;
64
62
  context.stroke();
65
63
  context.globalAlpha = oldAlpha;
66
- lastPos = position;
67
64
  }
68
- context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, currentPos.x, currentPos.y);
65
+ context.restore();
69
66
  }
70
67
  particleInit(container, particle) {
71
68
  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.5");
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.0");
3
+ await engine.register(e => {
4
+ e.addEffect("trail", async () => {
5
+ const { TrailDrawer } = await import("./TrailDrawer.js");
6
+ return new TrailDrawer();
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.5
7
+ * v4.0.0-beta.0
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 drawAfter(data) {\n const { context, drawPosition, drawRadius, drawScale, particle, transformData } = data, diameter = drawRadius * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.double, pxRatio = particle.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: particle.container.canvas.size.width * drawScale + diameter,\n height: particle.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,
@@ -8,11 +8,11 @@ const defaultTransform = {
8
8
  };
9
9
  export class TrailDrawer {
10
10
  drawAfter(data) {
11
- const { context, radius, particle, transformData } = data, diameter = radius * double, pxRatio = particle.container.retina.pixelRatio, currentPos = particle.getPosition(), trail = particle.trail;
11
+ const { context, drawPosition, drawRadius, drawScale, particle, transformData } = data, diameter = drawRadius * double, pxRatio = particle.container.retina.pixelRatio, trail = particle.trail;
12
12
  if (!trail || !particle.trailLength) {
13
13
  return;
14
14
  }
15
- const pathLength = particle.trailLength + radius;
15
+ const currentPos = drawPosition, pathLength = particle.trailLength * drawScale + drawRadius;
16
16
  trail.push({
17
17
  color: context.fillStyle || context.strokeStyle,
18
18
  position: {
@@ -24,48 +24,45 @@ export class TrailDrawer {
24
24
  if (trail.length < minTrailLength) {
25
25
  return;
26
26
  }
27
- while (trail.length > pathLength) {
28
- trail.shift();
27
+ const pathLengthFloor = Math.floor(pathLength);
28
+ if (trail.length > pathLengthFloor) {
29
+ trail.splice(firstIndex, trail.length - pathLengthFloor);
29
30
  }
30
31
  const trailLength = Math.min(trail.length, pathLength), canvasSize = {
31
- width: particle.container.canvas.size.width + diameter,
32
- height: particle.container.canvas.size.height + diameter,
32
+ width: particle.container.canvas.size.width * drawScale + diameter,
33
+ height: particle.container.canvas.size.height * drawScale + diameter,
33
34
  };
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) {
35
+ context.save();
36
+ context.lineCap = "butt";
37
+ context.lineJoin = "round";
38
+ for (let i = trailLength - loopTrailLengthOffset; i > loopTrailLengthMinIndex; i--) {
39
+ const previousStep = trail[i + trailLengthOffset], step = trail[i], nextStep = trail[i - trailLengthOffset];
40
+ if (!previousStep || !step || !nextStep) {
42
41
  continue;
43
42
  }
44
- const position = step.position, stepTransformData = particle.trailTransform
45
- ? (step.transformData ?? defaultTransform)
46
- : defaultTransform;
47
- context.setTransform(stepTransformData.a, stepTransformData.b, stepTransformData.c, stepTransformData.d, position.x, position.y);
48
- context.beginPath();
49
- context.moveTo(lastPos.x - position.x, lastPos.y - position.y);
50
- const warp = {
51
- x: (lastPos.x + canvasSize.width) % canvasSize.width,
52
- y: (lastPos.y + canvasSize.height) % canvasSize.height,
53
- };
54
- if (Math.abs(lastPos.x - position.x) > canvasSize.width * half ||
55
- Math.abs(lastPos.y - position.y) > canvasSize.height * half) {
56
- lastPos = position;
43
+ 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);
44
+ if (previousDistance > pathLength * double || nextDistance > pathLength * double) {
57
45
  continue;
58
46
  }
59
- 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);
60
- const width = Math.max((i / trailLength) * diameter, pxRatio, particle.trailMinWidth ?? minWidth), oldAlpha = context.globalAlpha;
47
+ if (Math.abs(previousPosition.x - position.x) > canvasSize.width * half ||
48
+ Math.abs(previousPosition.y - position.y) > canvasSize.height * half ||
49
+ Math.abs(position.x - nextPosition.x) > canvasSize.width * half ||
50
+ Math.abs(position.y - nextPosition.y) > canvasSize.height * half) {
51
+ continue;
52
+ }
53
+ context.setTransform(stepTransformData.a, stepTransformData.b, stepTransformData.c, stepTransformData.d, position.x, position.y);
54
+ 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;
55
+ context.beginPath();
56
+ context.moveTo(startX, startY);
57
+ context.quadraticCurveTo(originPoint.x, originPoint.y, endX, endY);
58
+ const width = Math.max((i / trailLength) * diameter, pxRatio, (particle.trailMinWidth ?? minWidth) * drawScale), oldAlpha = context.globalAlpha;
61
59
  context.globalAlpha = particle.trailFade ? i / trailLength : defaultAlpha;
62
- context.lineWidth = particle.trailMaxWidth ? Math.min(width, particle.trailMaxWidth) : width;
60
+ context.lineWidth = particle.trailMaxWidth ? Math.min(width, particle.trailMaxWidth * drawScale) : width;
63
61
  context.strokeStyle = step.color;
64
62
  context.stroke();
65
63
  context.globalAlpha = oldAlpha;
66
- lastPos = position;
67
64
  }
68
- context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, currentPos.x, currentPos.y);
65
+ context.restore();
69
66
  }
70
67
  particleInit(container, particle) {
71
68
  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.5");
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.0");
3
+ await engine.register(e => {
4
+ e.addEffect("trail", async () => {
5
+ const { TrailDrawer } = await import("./TrailDrawer.js");
6
+ return new TrailDrawer();
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.5",
3
+ "version": "4.0.0-beta.0",
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.5"
103
+ "@tsparticles/engine": "4.0.0-beta.0"
104
104
  },
105
105
  "publishConfig": {
106
106
  "access": "public"