Try it out!
Click or scan the QR code above to launch a new CodePen instance of this session. Compare the two sessions - you’ll see that the animated simulations are identical. The balls all move and bounce exactly the same way.Interactive Elements
Click any ball to stop/start it - changes sync to all users
Non-interactive Elements
The rounded rectangle bounces but ignores user actions
What You’ll Learn
1. Simulation Model
How to create a model that runs physics simulations
2. Interactive View
Building views that respond to user interactions
3. Safe Communication
Properly communicating between Model and View
Architecture Overview
This application uses two Multisynq Model subclasses:MyModel and BallModel. Both classes must be registered with Multisynq for proper synchronization.
Using Multisynq Constants
The app usesMultisynq.Constants to ensure all users share the same configuration values:
Models must not use global variables, but global constants are fine.
Multisynq.Constants is recursively frozen once a session starts to prevent accidental modification.Simple Animation Model
MyModel - Root Model
MyModel is the root model passed to Multisynq.Session.join(). It creates and stores the BallModel objects in the MyModel.children array.
BallModel - Individual Ball Logic
EachBallModel represents a shaped, colored, bouncing ball. The model stores only the data needed for synchronization:
- Shape: String (
'circle'or'roundRect') - Color: Random color value
- Position: Current x,y coordinates
- Speed: Velocity vector
Event Subscription
BallModel subscribes to the 'touch-me' event using its own ID as scope. This ensures that only the specific ball responds to touch events intended for it.
Simulation Loop
BallModel schedules its first step() method invocation. This creates a continuous simulation loop:
25 balls ticking at 30Hz generates 750 messages per second, but future messages are very efficient with minimal overhead.
Movement and Bouncing
moveBounce() method updates ball position and handles wall collisions. When a ball hits a wall, it gets a new random speed vector.
Deterministic Random Speed
Simple Animation View
The View comprises two classes:MyView and BallView.
MyView - Container View
MyView is called when a session instance starts, receiving the MyModel object as an argument. It builds the visual representation and container for all balls.
Creating Child Views
MyView accesses the model’s children collection and creates a BallView for each BallModel.
It’s fine for views to read from models directly, but views MUST NOT modify models in any way.
Responsive Scaling
MyView listens for browser “resize” events and adjusts the view scale accordingly. This ensures all users see the same scene regardless of their window size.
Cleanup on Detach
BallView - Individual Ball Display
EachBallView tracks its associated BallModel and handles visual representation and user interaction.
Position Updates
BallView subscribes to 'pos-changed' events from its specific model. The "oncePerFrame" handling ensures efficient rendering even with multiple position updates per frame.
Touch/Click Handling
BallView sets up touch/click handlers that publish 'touch-me' events. The corresponding BallModel subscribes to these events and toggles ball motion on and off.
Key Concepts Demonstrated
Model-View Separation
Model-View Separation
- Models handle all logic and state
- Views handle display and user input
- Communication happens only through events
Deterministic Simulation
Deterministic Simulation
- All instances run identical physics calculations
- Synchronized random number generation
- Consistent timing across all users
Efficient Event Handling
Efficient Event Handling
- Scoped events using object IDs
- Frame-rate limited updates
- Minimal overhead for future scheduling
Interactive Synchronization
Interactive Synchronization
- User actions sync across all sessions
- Individual object state management
- Immediate feedback with global updates
Next Steps
Now that you understand basic animation and interaction patterns, you can explore:Multi-user Chat
Learn to handle user input and message synchronization
View Smoothing
Create smoother animations with interpolation techniques
Best Practices
Use Constants
Store shared configuration in
Multisynq.ConstantsScope Events
Use object IDs to scope events to specific instances
Efficient Updates
Use
"oncePerFrame" handling for frequent updatesClean Resources
Implement proper cleanup in
detach() methods