Skip to content

Commit 8ce4d11

Browse files
committed
got all the source up to date on main with the source on gh-pages
1 parent 2ca72ee commit 8ce4d11

29 files changed

+667
-84
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
**Parametrix** is a streamlined 3D animation software that works natively in your browser of choice. It offers support for moving, rotating, scaling, and changing the colors of objects animated in a scene according to a variety of mathematically constructed functions that the user can configure.
44

5+
The standalone website can be found here: https://matthewsavitt.github.io/Parametrix-CMSI-4072/
6+
57
## How to Use
68

79
1. Clone the repository:
@@ -19,4 +21,4 @@
1921

2022

2123
## Credits
22-
Code by Matthew Savitt :D, open source or whatever.
24+
Code by Matthew Savitt :D, open source or whatever.

assets/gizmo.PNG

2.61 KB
Loading

assets/menuOpen.mp3

1.63 KB
Binary file not shown.

assets/paper-crumple.mp3

18.5 KB
Binary file not shown.

assets/paths.png

2.61 KB
Loading

assets/pitch.png

203 Bytes
Loading

assets/roll.png

122 Bytes
Loading

assets/yaw.png

259 Bytes
Loading

src/animationHud.js

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ export function createPlaybackHUD(animationManager, scene) {
161161

162162
// Create path icon image
163163
const pathIcon = document.createElement('img');
164-
pathIcon.src = '/../assets/paths.png';
164+
pathIcon.src = './paths.png';
165165
pathIcon.width = 20;
166166
pathIcon.height = 20;
167167
pathIcon.style.marginRight = '5px';
@@ -180,6 +180,21 @@ export function createPlaybackHUD(animationManager, scene) {
180180
pathToggleCheckbox.checked = true; // Default to showing paths
181181
pathToggleCheckbox.id = 'path-toggle';
182182

183+
// Listen for project loading to update UI state
184+
window.addEventListener('project-loaded', (event) => {
185+
if (event.detail && event.detail.showAnimationPaths !== undefined) {
186+
window.showAnimationPaths = event.detail.showAnimationPaths;
187+
togglePathsButton.textContent = window.showAnimationPaths ? '👁️ Paths: ON' : '👁️ Paths: OFF';
188+
189+
// Update visibility of all paths
190+
scene.traverse(obj => {
191+
if (obj.isAnimationPath) {
192+
obj.visible = window.showAnimationPaths;
193+
}
194+
});
195+
}
196+
});
197+
183198
// Add components to container in correct order
184199
pathToggleContainer.appendChild(pathLabelContent);
185200
pathToggleContainer.appendChild(pathToggleCheckbox);
@@ -194,11 +209,27 @@ export function createPlaybackHUD(animationManager, scene) {
194209
gizmoToggleCheckbox.id = 'gizmo-toggle';
195210
gizmoToggleCheckbox.checked = true; // Default to visible
196211

212+
//create gizmo icon image
213+
const gizmoIcon = document.createElement('img');
214+
gizmoIcon.src = './gizmo.PNG';
215+
gizmoIcon.width = 20;
216+
gizmoIcon.height = 20;
217+
gizmoIcon.style.marginLeft = '5px';
218+
197219
const gizmoToggleLabel = document.createElement('label');
198220
gizmoToggleLabel.htmlFor = 'gizmo-toggle';
199221
gizmoToggleLabel.textContent = 'Show Gizmo:';
200222
gizmoToggleLabel.style.marginRight = '10px';
201223

224+
// Create label container with icon and text
225+
const gizmoLabelContent = document.createElement('div');
226+
gizmoLabelContent.style.display = 'flex';
227+
gizmoLabelContent.style.alignItems = 'right';
228+
gizmoLabelContent.style.marginRight = '10px';
229+
gizmoLabelContent.appendChild(gizmoIcon);
230+
gizmoLabelContent.appendChild(gizmoToggleLabel);
231+
gizmoToggleContainer.appendChild(gizmoLabelContent);
232+
// Append the checkbox to the label container
202233
gizmoToggleContainer.appendChild(gizmoToggleLabel);
203234
gizmoToggleContainer.appendChild(gizmoToggleCheckbox);
204235

src/animationManager.js

Lines changed: 53 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,62 +10,75 @@ export class AnimationManager {
1010
}
1111

1212
addAnimation(object, animationConfig) {
13+
console.log("Adding animation:", animationConfig);
14+
1315
// Update start/end times of the timeline if needed
1416
this.startTime = Math.min(this.startTime, animationConfig.startT);
1517
this.endTime = Math.max(this.endTime, animationConfig.endT);
1618

17-
// Check if the object already has animations
19+
// Initialize animations array if it doesn't exist
1820
if (!object.animations) {
1921
object.animations = [];
20-
21-
// Add an update method to the object
22-
object.update = (time) => {
23-
// Apply all animations for this object, using the provided time
24-
object.animations.forEach(anim => {
25-
const { property, axis, startT, endT, functions, loop } = anim;
26-
27-
// Skip if outside time range and not looping
28-
if (time < startT) return;
29-
if (time > endT && !loop && !this.loop) return;
30-
31-
// Calculate local time based on global time
32-
let localTime;
33-
if (loop || this.loop) {
34-
// Loop the animation (cycle between startT and endT)
35-
const duration = endT - startT;
36-
const elapsed = time - startT;
37-
localTime = startT + (elapsed % duration);
38-
} else {
39-
// Play once and clamp to endT
40-
localTime = Math.min(time, endT);
41-
}
42-
43-
// Apply the function to the specified property and axis
44-
if (functions[axis]) {
45-
const { apply, params } = functions[axis];
46-
const value = apply(localTime, params);
47-
48-
// Apply to the object
49-
if (property === 'position') {
50-
object.position[axis] = value;
51-
} else if (property === 'rotation') {
52-
object.rotation[axis] = value;
53-
} else if (property === 'scale') {
54-
object.scale[axis] = Math.max(0.01, value); // Prevent negative/zero scale
55-
}
56-
}
57-
});
58-
};
5922
}
23+
// Remove any existing animation for the same property and axis
24+
object.animations = object.animations.filter(anim =>
25+
!(anim.property === animationConfig.property && anim.axis === animationConfig.axis)
26+
);
27+
28+
// Remove from global animations list too
29+
this.animations = this.animations.filter(anim =>
30+
!(anim.object === object && anim.property === animationConfig.property && anim.axis === animationConfig.axis)
31+
);
6032

6133
// Add this animation to the object's animations
6234
object.animations.push(animationConfig);
6335

6436
// Add to global animations list
6537
this.animations.push({ object, ...animationConfig });
6638

39+
// Ensure the update method is created
40+
object.update = (time) => {
41+
if (!object.animations || object.animations.length === 0) return;
42+
43+
object.animations.forEach(anim => {
44+
const { property, axis, startT, endT, functions } = anim;
45+
46+
if (time < startT) return;
47+
48+
let localTime;
49+
if (this.loop) {
50+
const duration = endT - startT;
51+
const elapsed = time - startT;
52+
localTime = startT + (elapsed % duration);
53+
} else {
54+
localTime = Math.min(time, endT);
55+
}
56+
57+
if (functions[axis]) {
58+
const { apply, params } = functions[axis];
59+
const value = apply(localTime, params);
60+
61+
if (property === 'position') {
62+
object.position[axis] = value;
63+
} else if (property === 'rotation') {
64+
object.rotation[axis] = value;
65+
} else if (property === 'scale') {
66+
object.scale[axis] = Math.max(0.01, value);
67+
} else if (property === 'color' && object.material && object.material.color) {
68+
// Color animation
69+
if (axis === 'r') object.material.color.r = value / 255;
70+
if (axis === 'g') object.material.color.g = value / 255;
71+
if (axis === 'b') object.material.color.b = value / 255;
72+
}
73+
}
74+
});
75+
};
76+
6777
// Apply animation immediately with current time
6878
object.update(this.globalTime);
79+
80+
// Debug log to verify the animation is added
81+
console.log(`Animation added to ${object.uuid}, total animations: ${this.animations.length}`);
6982
} addAnimation(object, animationConfig) {
7083
console.log("Adding animation:", animationConfig);
7184

0 commit comments

Comments
 (0)