Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow new particles to be visible when paused #49

Merged
merged 1 commit into from
Dec 14, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 58 additions & 52 deletions src/components/ParticleRenderer/ParticleRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,10 @@
}

scope.view.onFrame = () => {
if (isPausedRef.current) return;

const currentParticles = particlesRef.current;
if (!currentParticles || !layerRef.current) return;

// Clean up removed particles regardless of pause state
const currentParticleIds = new Set(currentParticles.map((p) => p.id));
trailsRef.current.forEach((trail, id) => {
if (!currentParticleIds.has(id)) {
Expand All @@ -88,14 +87,14 @@
size = 10,
mass = 0.1,
} = particle;
const isNegativeMass = mass < 0;

// Always create new particles, even when paused
if (!trailsRef.current.has(id)) {
const path: ParticleTrail["path"] = new scope.Path({
strokeColor: color,
strokeWidth: 0,
strokeCap: "round",
dashArray: isNegativeMass ? [4, 4] : null,
dashArray: mass < 0 ? [4, 4] : null,
});

const segmentPaths: paper.Path[] = [];
Expand All @@ -106,7 +105,7 @@
strokeWidth: 0,
opacity: 0,
strokeCap: "round",
dashArray: isNegativeMass ? [4, 4] : null,
dashArray: mass < 0 ? [4, 4] : null,
visible: false,
});
layerRef.current?.addChild(segmentPath);
Expand All @@ -119,7 +118,7 @@
strokeColor: color,
strokeWidth: 2,
fillColor: null,
dashArray: isNegativeMass ? [4, 4] : null,
dashArray: mass < 0 ? [4, 4] : null,
});
layerRef.current?.addChild(path.lastCircle);
layerRef.current?.addChild(path);
Expand All @@ -129,63 +128,70 @@

const trail = trailsRef.current.get(id)!;

trail.path.add(new Point(position.x, position.y));
if (trail.path.segments.length > maxTrailPointsRef.current) {
trail.path.removeSegments(
0,
trail.path.segments.length - maxTrailPointsRef.current
);
} else if (trail.path.segments.length < maxTrailPointsRef.current) {
const lastPosition = trail.path.lastSegment.point;
while (trail.path.segments.length < maxTrailPointsRef.current) {
trail.path.insert(0, lastPosition);
// Only update existing particles if not paused
if (!isPausedRef.current) {
trail.path.add(new Point(position.x, position.y));
if (trail.path.segments.length > maxTrailPointsRef.current) {
trail.path.removeSegments(
0,
trail.path.segments.length - maxTrailPointsRef.current
);
} else if (trail.path.segments.length < maxTrailPointsRef.current) {
const lastPosition = trail.path.lastSegment.point;
while (trail.path.segments.length < maxTrailPointsRef.current) {
trail.path.insert(0, lastPosition);
}
}
}

const segments = trail.path.segments;
const totalSegments = segments.length - 1;

trail.segmentPaths.forEach((segmentPath, i) => {
if (i < totalSegments) {
segmentPath.visible = true;
segmentPath.segments[0].point = segments[i].point;
segmentPath.segments[1].point = segments[i + 1].point;

const progress = i / totalSegments;
segmentPath.strokeWidth = size * 1.2 * progress;
segmentPath.opacity = 0.3 * progress;
} else {
segmentPath.visible = false;
}
});
const segments = trail.path.segments;
const totalSegments = segments.length - 1;

trail.segmentPaths.forEach((segmentPath, i) => {
if (i < totalSegments) {
segmentPath.visible = true;
segmentPath.segments[0].point = segments[i].point;
segmentPath.segments[1].point = segments[i + 1].point;

const progress = i / totalSegments;
segmentPath.strokeWidth = size * 1.2 * progress;
segmentPath.opacity = 0.3 * progress;
} else {
segmentPath.visible = false;
}
});
}

// Always update particle circle position
if (trail.path.lastCircle) {
trail.path.lastCircle.position = new Paper.Point(
position.x,
position.y
);
}

trail.path.vectors?.forEach((vector) => vector.remove());
trail.path.vectors = [];
if (showVelocityArrowsRef.current) {
const velocityArrow = createArrow(
new Paper.Point(position.x, position.y),
particle.velocity,
"#4CAF50",
1
);
trail.path.vectors.push(velocityArrow);
}
// Update vectors if not paused
if (!isPausedRef.current) {
trail.path.vectors?.forEach((vector) => vector.remove());
trail.path.vectors = [];
if (showVelocityArrowsRef.current) {
const velocityArrow = createArrow(
new Paper.Point(position.x, position.y),
particle.velocity,
"#4CAF50",
1
);
trail.path.vectors.push(velocityArrow);
}

if (showForceArrowsRef.current) {
const forceArrow = createArrow(
new Paper.Point(position.x, position.y),
isNegativeMass ? particle.force.multiply(-1) : particle.force,
"#FF4081",
40
);
trail.path.vectors.push(forceArrow);
if (showForceArrowsRef.current) {
const forceArrow = createArrow(
new Paper.Point(position.x, position.y),
mass < 0 ? particle.force.multiply(-1) : particle.force,
"#FF4081",
40
);
trail.path.vectors.push(forceArrow);
}
}
});

Expand All @@ -199,7 +205,7 @@
layerRef.current = null;
}
};
}, [scope, particlesRef]);

Check warning on line 208 in src/components/ParticleRenderer/ParticleRenderer.tsx

View workflow job for this annotation

GitHub Actions / build

React Hook useEffect has a missing dependency: 'isPausedRef'. Either include it or remove the dependency array

return null;
};
Expand Down
Loading