Skip to content

Commit

Permalink
Feature: Add speed slider logic to the extension (#901)
Browse files Browse the repository at this point in the history
* Fix progress line.

* Calculate speed of the branches.

* Use speed multiplier for progressLine

* Use speed multiplier for branches.

* Add speed multiplier for the barrageAnimation.

* Send speed multiplier as a prop to p5

* Add speed multiplier for the auctions.

* Reduce delay between 2 components.

* Add speed timer to the ripple effect.

* create a drawInstantly funtion in branches.

* Create branches using progress line.

* Make bubble speed calculation dynamic.

* Fix animation speed.

* Change condition.

* Fix bubble calculation.

* Update ripple effect.

* Modify speed of barrage and ripple effect.

* Code refactoring:
- Add comments
- Remove unused code
  • Loading branch information
amovar18 authored Dec 25, 2024
1 parent 5afed08 commit c5c5b87
Show file tree
Hide file tree
Showing 10 changed files with 193 additions and 150 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const app = {
expandedCircleDiameter: 640,
minifiedCircleDiameter: 50,
},
speedMultiplier: 1,
p: null,
igp: null,
up: null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,20 @@ import ProgressLine from './progressLine';
import app from '../app';
import config from '../config';
import Box from './box';
import { wipeAndRecreateInterestCanvas } from '../utils';
import { delay, wipeAndRecreateInterestCanvas } from '../utils';

const LEFT_MARGIN = 70; // Margin from the left side of the canvas
const ANIMATION_SPEED = 15; // Controls the speed of the horizontal line drawing
const EXPAND_ICON_SIZE = 20;

let spacing, progress, renderedBranchIds, endpoints;
let spacing, renderedBranchIds, endpoints;

const Branches = async ({ x1, y1, branches, currentIndex }) => {
const Branches = async ({
x1,
y1,
branches,
currentIndex,
noAnimation = app.speedMultiplier === 4,
}) => {
x1 = typeof x1 === 'function' ? x1() : x1;
y1 = typeof y1 === 'function' ? y1() : y1;

Expand All @@ -37,7 +42,6 @@ const Branches = async ({ x1, y1, branches, currentIndex }) => {
id: index, // To prevent duplicate rendering
}));

progress = 0;
renderedBranchIds = [];
endpoints = [];
const p = app.p;
Expand All @@ -50,140 +54,95 @@ const Branches = async ({ x1, y1, branches, currentIndex }) => {
y1: y1,
direction: 'down',
noArrow: true,
noAnimation: true,
noAnimation: app.speedMultiplier === 4,
});

return new Promise((resolve) => {
const animate = () => {
if (app.isRevisitingNodeInInteractiveMode) {
const branchXEndpoint =
currentIndex * LEFT_MARGIN + 15 + (branches.length - 1) * spacing;

branches.forEach(({ id, type }, index) => {
const x = currentIndex * LEFT_MARGIN + 15 + index * spacing;
const y = y2 - 9;
let endpoint;
p.push();
p.stroke(0);
p.line(x, y, branchXEndpoint, y);
p.pop();
p.push();
p.stroke(0);
p.line(x, y, x, y + 20);
p.pop();
if (type === 'datetime') {
endpoint = drawDateTimeBranch(x, y, branches[index]);
}

if (type === 'box') {
endpoint = drawBoxesBranch(x, y, branches[index]);
}

endpoints.push(endpoint);

renderedBranchIds.push(id);
});
resolve(endpoints);
return;
}
if (app.cancelPromise) {
resolve(endpoints);
return;
}
const drawInstantly = () => {
const branchXEndpoint =
currentIndex * LEFT_MARGIN + 15 + (branches.length - 1) * spacing;

if (app.timeline.isPaused) {
requestAnimationFrame(animate); // Continue loop but remain paused
return;
branches.forEach(({ id, type }, index) => {
const x = currentIndex * LEFT_MARGIN + 15 + index * spacing;
const y = y2 - 9;
let endpoint;
p.push();
p.stroke(0);
p.line(x, y, branchXEndpoint, y);
p.pop();
p.push();
p.stroke(0);
p.line(x, y, x, y + 20);
p.pop();
if (type === 'datetime') {
endpoint = drawDateTimeBranch(x, y, branches[index]);
}

// Clear canvas or update logic (if necessary)
wipeAndRecreateInterestCanvas();

// Draw the animated timeline
drawAnimatedTimeline(currentIndex * LEFT_MARGIN, y2 - 9, branches).then(
() => {
resolve(endpoints);
}
);

// Continue animation until progress completes
if (progress < (branches.length - 1) * spacing) {
progress += ANIMATION_SPEED;
requestAnimationFrame(animate);
if (type === 'box') {
endpoint = drawBoxesBranch(x, y, branches[index]);
}
};

// Start the animation loop
requestAnimationFrame(animate);
});
};
endpoints.push(endpoint);

const drawAnimatedTimeline = (x, y, branches) => {
const p = app.p;
const leftMargin = 15;
x = x + leftMargin;
p.push();
p.stroke(0);
p.strokeWeight(1);
p.pop();
renderedBranchIds.push(id);
});
};

if (app.isRevisitingNodeInInteractiveMode || noAnimation) {
drawInstantly();
await delay(noAnimation ? 1000 : 0);
return endpoints;
}

if (app.cancelPromise) {
return new Promise((resolve) => resolve());
return endpoints;
}

return new Promise((resolve) => {
// Draw the horizontal line
p.line(x, y, x + progress, y);
// Clear canvas or update logic (if necessary)
wipeAndRecreateInterestCanvas();

const branchXEndpoint =
currentIndex * LEFT_MARGIN + 15 + (branches.length - 1) * spacing;
const branchXStartpoint = currentIndex * LEFT_MARGIN + 15;

if (app.cancelPromise) {
resolve();
return;
}
await ProgressLine({
x1: branchXStartpoint,
y1: y2 - 9,
customWidth: branchXEndpoint - branchXStartpoint,
direction: 'right',
noArrow: true,
noAnimation: app.speedMultiplier === 4,
isBranch: true,
});

// Draw vertical lines and labels as the horizontal line progresses
for (let i = 0; i < branches.length; i++) {
const branchX = x + i * spacing;
const branch = branches[i];
await Promise.all(
branches.map(async ({ id, type }, index) => {
const x = currentIndex * LEFT_MARGIN + 15 + index * spacing;
const y = y2 - 9;
let endpoint;
if (app.cancelPromise) {
resolve();
return;

await ProgressLine({
x1: x,
y1: y,
customHeight: 20,
direction: 'down',
noArrow: true,
noAnimation: app.speedMultiplier === 4,
});

if (type === 'datetime') {
endpoint = drawDateTimeBranch(x, y, branches[index]);
}

if (progress >= i * spacing && !renderedBranchIds.includes(branch.id)) {
// Draw vertical line once the horizontal line reaches its position
p.push();
p.stroke(0);
p.line(branchX, y, branchX, y + 20);
p.pop();

switch (branch.type) {
case 'datetime':
endpoint = drawDateTimeBranch(branchX, y, branch);
break;
case 'box':
endpoint = drawBoxesBranch(branchX, y, branch);
break;
default:
break;
}

// Store the endpoint coordinates for each branch
endpoints.push(endpoint);

renderedBranchIds.push(branch.id);
if (type === 'box') {
endpoint = drawBoxesBranch(x, y, branches[index]);
}
}
if (app.cancelPromise) {
resolve();
return;
}
// Resolve if the progress exceeds the required length
if (progress >= (branches.length - 1) * spacing) {
resolve();
return;
}
});

endpoints.push(endpoint);
renderedBranchIds.push(id);
})
);

return endpoints;
};

const drawDateTimeBranch = (x, y, branch) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,17 @@ const ARROW_SIZE = 10;
const ProgressLine = ({
x1,
y1,
customWidth,
customHeight,
direction = 'right',
text = '',
noArrow = false,
noAnimation = true,
noAnimation = app.speedMultiplier === 4,
isBranch = false,
}) => {
const width = config.flow.lineWidth - ARROW_SIZE;
const height = config.flow.lineHeight - ARROW_SIZE;
const incrementBy = 5; // Adjust to control speed
const width = customWidth ?? config.flow.lineWidth - ARROW_SIZE;
const height = customHeight ?? config.flow.lineHeight - ARROW_SIZE;
const incrementBy = isBranch ? 15 : app.speedMultiplier; // Adjust to control speed
const p = app.p;

x1 = typeof x1 === 'function' ? x1() : x1;
Expand All @@ -48,19 +51,40 @@ const ProgressLine = ({

const draw = {
right: () => {
//Doing this since it was noticed that drawing switching to fastest mode in mid animation still shows the arrow
p.push();
p.noStroke();
p.fill(config.flow.colors.box.background);
p.rect(x1, y1, width, ARROW_SIZE);
p.pop();

p.line(x1, y1, x1 + width, y2);
drawArrow(x1 + width, y1, direction);

return { x: x1 + width, y: y1 };
},
left: () => {
//Doing this since it was noticed that drawing switching to fastest mode in mid animation still shows the arrow
p.push();
p.noStroke();
p.fill(config.flow.colors.box.background);
p.rect(x2, y2 + 10, -width, ARROW_SIZE);
p.pop();

p.line(x2, y2 + 10, x2 - width, y1 + 10);
drawArrow(x2 - width, y1 + 4, direction);
utils.drawText(text, x2 - width / 2, y1 + height / 2);

return { x: x2 - width, y: y1 + 10 };
},
down: () => {
//Doing this since it was noticed that drawing switching to fastest mode in mid animation still shows the arrow
p.push();
p.noStroke();
p.fill(config.flow.colors.box.background);
p.rect(x1 - 5, y1, ARROW_SIZE, height);
p.pop();

p.line(x1, y1, x2, y1 + height);
drawArrow(x1, y1 + height, direction);
utils.drawText(
Expand All @@ -72,6 +96,13 @@ const ProgressLine = ({
return { x: x1, y: y1 + height };
},
up: () => {
//Doing this since it was noticed that drawing switching to fastest mode in mid animation still shows the arrow
p.push();
p.noStroke();
p.fill(config.flow.colors.box.background);
p.rect(x1 - 5, y1, ARROW_SIZE, -height);
p.pop();

p.line(x1, y1, x2, y1 - height);
drawArrow(x1, y1 - height, direction);
utils.drawText(
Expand All @@ -90,7 +121,6 @@ const ProgressLine = ({
p.push();
p.stroke(0);
p.strokeWeight(1);

returnCoordinates = draw[direction]();

p.pop();
Expand All @@ -112,7 +142,12 @@ const ProgressLine = ({
return;
}

if (noAnimation || app.isRevisitingNodeInInteractiveMode) {
//Redundant condition to handle case when animation has started and someone has switched to fastest speed.
if (
noAnimation ||
app.isRevisitingNodeInInteractiveMode ||
app.speedMultiplier === 4
) {
drawInstantly();
resolve(returnCoordinates);
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,14 @@ rippleEffect.start = (x = 0, y = 0) => {
return;
}

let baseSpeed = 1;

if (app.speedMultiplier > 2) {
baseSpeed = app.speedMultiplier / 2;
}

let startTime = null; // Tracks the start time of the animation
const duration = config.rippleEffect.time; // Total animation time
const duration = config.rippleEffect.time / baseSpeed; // Total animation time
config.rippleEffect.rippled = true;

const animate = (timestamp) => {
Expand All @@ -63,15 +69,16 @@ rippleEffect.start = (x = 0, y = 0) => {

if (!startTime) {
startTime = timestamp;
} // Set the initial timestamp
}

const elapsed = timestamp - startTime;

if (elapsed > duration) {
resolve();
return;
}

rippleEffect.create(x, y);
rippleEffect.create(x, y, baseSpeed);

// Continue the animation loop
requestAnimationFrame(animate);
Expand All @@ -82,9 +89,9 @@ rippleEffect.start = (x = 0, y = 0) => {
});
};

rippleEffect.create = (rippleX, rippleY) => {
rippleEffect.create = (rippleX, rippleY, speed) => {
// Calculate the area to clear
const { ripples, numRipples, speed, maxRadius } = config.rippleEffect;
const { ripples, numRipples, maxRadius } = config.rippleEffect;
const clearWidth = maxRadius * 2 + (numRipples - 1) * 40;
const clearHeight = maxRadius * 1.5;
const p = app.p;
Expand Down
Loading

0 comments on commit c5c5b87

Please sign in to comment.