What is Tweaks?
Real-time Parameter Control
Tweaks provides a dynamic panel that allows you to adjust variables, colors, numbers, and boolean values in real-time without modifying code or refreshing your application.
Rapid Prototyping
Perfect for game development, animations, visualizations, and any interactive content where fine-tuning parameters is crucial for achieving the desired effect.
Developer Experience
Enhances the development workflow by providing instant feedback and eliminating the need for constant code changes during the experimentation phase.
How to Use Tweaks
Enable Tweaks as an Advanced Ability
When starting a new project, select "Tweaks" from the Advanced Abilities options. This will automatically set up the Tweaks infrastructure in your project.
✅ Tweaks - Real-time parameter adjustment
Import and Initialize Tweaks
In your JavaScript file, import the Tweaks library and create a Tweaks instance:
import { Tweaks } from 'https://esm.sh/tweaks';
const tweaks = new Tweaks();
tweaks.show(); // Display the Tweaks panel
Add Parameters to Tweak
Use the various methods to add different types of parameters:
// Numbers with range
const speed = tweaks.addNumber('Speed', 5, { min: 0, max: 10, step: 0.1 });
// Colors
const color = tweaks.addColor('Background Color', '#ff0000');
// Booleans
const isEnabled = tweaks.addBoolean('Enable Effect', true);
// Strings
const message = tweaks.addString('Message', 'Hello World');
// Select options
const mode = tweaks.addSelect('Mode', 'normal', ['normal', 'fast', 'slow']);
Use the Values in Your Code
Access the current values of your parameters in your render loop or event handlers:
function animate() {
// Get current values from Tweaks
const currentSpeed = speed.value;
const currentColor = color.value;
const enabled = isEnabled.value;
if (enabled) {
// Use the tweaked values
object.rotation.y += currentSpeed * 0.01;
renderer.setClearColor(currentColor);
}
requestAnimationFrame(animate);
}
Adding Tweaks to Existing Projects
Don't worry! You can still add Tweaks to your existing project even if you didn't select it initially as an Advanced Ability.
Method 1: Manual Installation
Add the Tweaks import to your JavaScript file:
import { Tweaks } from 'https://esm.sh/tweaks';
Initialize Tweaks in your code:
const tweaks = new Tweaks();
tweaks.show();
Add your parameters and start tweaking!
Method 2: Request Project Update
Ask your AI assistant to add Tweaks to your project:
"Please add Tweaks functionality to this project"
The AI will automatically set up the necessary imports and initialization code.
Specify which parameters you'd like to be tweakable.
When requesting Tweaks to be added to an existing project, be specific about which variables or properties you want to control. This helps the AI set up the most useful Tweaks panel for your needs.
Complete API Reference
Parameter Types
addNumber(name, value, options)
// Basic number
const speed = tweaks.addNumber('Speed', 5);
// With range and step
const precision = tweaks.addNumber('Precision', 0.5, {
min: 0,
max: 1,
step: 0.01
});
// With custom range
const temperature = tweaks.addNumber('Temperature', 20, {
min: -10,
max: 50,
step: 0.5
});
addColor(name, value)
// Hex color
const bgColor = tweaks.addColor('Background', '#ff0000');
// RGB color
const textColor = tweaks.addColor('Text Color', 'rgb(255, 0, 0)');
// Named color
const accent = tweaks.addColor('Accent', 'crimson');
addBoolean(name, value)
// Simple boolean
const isEnabled = tweaks.addBoolean('Enable Effect', true);
// Multiple booleans
const showDebug = tweaks.addBoolean('Show Debug', false);
const autoRotate = tweaks.addBoolean('Auto Rotate', true);
addString(name, value)
// Text input
const message = tweaks.addString('Message', 'Hello World');
// URL input
const imageUrl = tweaks.addString('Image URL', '/default.jpg');
addSelect(name, value, options)
// Simple select
const mode = tweaks.addSelect('Mode', 'normal', [
'normal', 'fast', 'slow'
]);
// Object options
const quality = tweaks.addSelect('Quality', 'medium', {
'Low': 'low',
'Medium': 'medium',
'High': 'high'
});
addVector2(name, x, y, options)
// 2D position
const position = tweaks.addVector2('Position', 0, 0, {
min: -100,
max: 100,
step: 1
});
// Access values
console.log(position.x, position.y);
addVector3(name, x, y, z, options)
// 3D rotation
const rotation = tweaks.addVector3('Rotation', 0, 0, 0, {
min: -Math.PI,
max: Math.PI,
step: 0.01
});
// Access values
object.rotation.set(rotation.x, rotation.y, rotation.z);
addButton(name, callback)
// Action button
tweaks.addButton('Reset Scene', () => {
resetAllObjects();
});
// Multiple actions
tweaks.addButton('Save Screenshot', saveScreenshot);
tweaks.addButton('Toggle Fullscreen', toggleFullscreen);
Advanced Features
Folders and Organization
Group related parameters into collapsible folders for better organization.
// Create folders
const lightingFolder = tweaks.addFolder('Lighting');
const materialFolder = tweaks.addFolder('Material');
// Add parameters to folders
lightingFolder.addNumber('Intensity', 1, { min: 0, max: 5 });
lightingFolder.addColor('Color', '#ffffff');
materialFolder.addNumber('Roughness', 0.5, { min: 0, max: 1 });
materialFolder.addNumber('Metalness', 0, { min: 0, max: 1 });
// Nested folders
const advancedFolder = lightingFolder.addFolder('Advanced');
advancedFolder.addVector3('Position', 0, 10, 0);
Presets and State Management
Save and load different configurations to quickly switch between setups.
// Save current state as preset
tweaks.savePreset('Day Scene');
tweaks.savePreset('Night Scene');
// Load a preset
tweaks.loadPreset('Night Scene');
// Get all preset names
const presets = tweaks.getPresets();
// Export/Import presets
const stateData = tweaks.exportState();
localStorage.setItem('tweaks-state', JSON.stringify(stateData));
// Later, restore state
const savedState = JSON.parse(localStorage.getItem('tweaks-state'));
tweaks.importState(savedState);
Event Handling and Callbacks
React to parameter changes with custom callbacks and event listeners.
// Listen to specific parameter changes
const speed = tweaks.addNumber('Speed', 5);
speed.onChange((value) => {
console.log('Speed changed to:', value);
updateAnimationSpeed(value);
});
// Listen to all parameter changes
tweaks.onChange((changedParameter, newValue) => {
console.log(`${changedParameter.name} changed to:`, newValue);
});
// One-time event listeners
speed.once('change', () => {
console.log('Speed was changed for the first time');
});
// Remove event listeners
const callback = (value) => console.log(value);
speed.onChange(callback);
speed.removeListener('change', callback);
Panel Configuration
Customize the appearance and behavior of the Tweaks panel.
// Initialize with options
const tweaks = new Tweaks({
title: 'My Controls',
position: 'top-left', // top-left, top-right, bottom-left, bottom-right
width: 300,
collapsed: false,
theme: 'dark', // light, dark, auto
autoPlace: true,
hideable: true,
closeable: false
});
// Runtime panel control
tweaks.show();
tweaks.hide();
tweaks.toggle();
tweaks.open(); // expand if collapsed
tweaks.close(); // collapse if expanded
// Position and sizing
tweaks.setPosition('bottom-right');
tweaks.setWidth(400);
tweaks.setTitle('Updated Controls');
Real-World Examples
Game Development
// Player settings
const playerFolder = tweaks.addFolder('Player');
const jumpHeight = playerFolder.addNumber('Jump Height', 10, { min: 5, max: 20 });
const moveSpeed = playerFolder.addNumber('Move Speed', 300, { min: 100, max: 500 });
const playerColor = playerFolder.addColor('Player Color', '#00ff00');
// Enemy settings
const enemyFolder = tweaks.addFolder('Enemies');
const spawnRate = enemyFolder.addNumber('Spawn Rate', 2, { min: 0.5, max: 5, step: 0.1 });
const enemyHealth = enemyFolder.addNumber('Health', 100, { min: 50, max: 200 });
// Game loop
function updateGame() {
player.jumpPower = jumpHeight.value;
player.speed = moveSpeed.value;
player.tint = playerColor.value;
enemyManager.spawnRate = spawnRate.value;
enemyManager.defaultHealth = enemyHealth.value;
}
3D Visualization
// Camera controls
const cameraFolder = tweaks.addFolder('Camera');
const fov = cameraFolder.addNumber('FOV', 75, { min: 10, max: 160 });
const cameraPosition = cameraFolder.addVector3('Position', 0, 5, 10);
// Lighting
const lightFolder = tweaks.addFolder('Lighting');
const ambientIntensity = lightFolder.addNumber('Ambient', 0.4, { min: 0, max: 1 });
const directionalIntensity = lightFolder.addNumber('Directional', 1, { min: 0, max: 3 });
const lightColor = lightFolder.addColor('Light Color', '#ffffff');
// Material properties
const materialFolder = tweaks.addFolder('Material');
const roughness = materialFolder.addNumber('Roughness', 0.5, { min: 0, max: 1 });
const metalness = materialFolder.addNumber('Metalness', 0, { min: 0, max: 1 });
// Animation
function animate() {
camera.fov = fov.value;
camera.position.set(cameraPosition.x, cameraPosition.y, cameraPosition.z);
camera.updateProjectionMatrix();
ambientLight.intensity = ambientIntensity.value;
directionalLight.intensity = directionalIntensity.value;
directionalLight.color.set(lightColor.value);
material.roughness = roughness.value;
material.metalness = metalness.value;
}
Creative Coding
// Canvas settings
const canvasFolder = tweaks.addFolder('Canvas');
const backgroundColor = canvasFolder.addColor('Background', '#000000');
const clearCanvas = canvasFolder.addBoolean('Clear Each Frame', true);
// Pattern generation
const patternFolder = tweaks.addFolder('Pattern');
const particleCount = patternFolder.addNumber('Particles', 100, { min: 10, max: 1000 });
const noiseScale = patternFolder.addNumber('Noise Scale', 0.01, { min: 0.001, max: 0.1, step: 0.001 });
const colorPalette = patternFolder.addSelect('Palette', 'rainbow', [
'rainbow', 'sunset', 'ocean', 'forest'
]);
// Animation controls
const animFolder = tweaks.addFolder('Animation');
const animSpeed = animFolder.addNumber('Speed', 1, { min: 0, max: 5, step: 0.1 });
const rotationSpeed = animFolder.addNumber('Rotation', 0.01, { min: -0.1, max: 0.1, step: 0.001 });
// Reset button
tweaks.addButton('Reset Pattern', () => {
initializeParticles();
resetAnimation();
});
Data Visualization
// Data controls
const dataFolder = tweaks.addFolder('Data');
const dataPoints = dataFolder.addNumber('Data Points', 50, { min: 10, max: 200 });
const refreshRate = dataFolder.addNumber('Refresh Rate (ms)', 1000, { min: 100, max: 5000 });
const dataRange = dataFolder.addVector2('Value Range', 0, 100);
// Visualization
const vizFolder = tweaks.addFolder('Visualization');
const chartType = vizFolder.addSelect('Chart Type', 'line', ['line', 'bar', 'scatter', 'area']);
const showGrid = vizFolder.addBoolean('Show Grid', true);
const smoothing = vizFolder.addBoolean('Smooth Lines', true);
// Styling
const styleFolder = tweaks.addFolder('Styling');
const primaryColor = styleFolder.addColor('Primary Color', '#2196F3');
const secondaryColor = styleFolder.addColor('Secondary Color', '#FF9800');
const lineWidth = styleFolder.addNumber('Line Width', 2, { min: 1, max: 10 });
// Update chart
function updateChart() {
chart.config.data.datasets[0].pointBackgroundColor = primaryColor.value;
chart.config.data.datasets[0].borderColor = primaryColor.value;
chart.config.data.datasets[0].borderWidth = lineWidth.value;
chart.config.options.scales.x.grid.display = showGrid.value;
chart.update();
}
Performance Considerations
Optimize Update Frequency
Avoid reading Tweaks values on every frame if the calculations are expensive.
// BAD: Reading on every frame
function animate() {
heavyCalculation(expensiveParam.value);
requestAnimationFrame(animate);
}
// GOOD: Cache values and update only when changed
let cachedValue = expensiveParam.value;
expensiveParam.onChange(value => cachedValue = value);
function animate() {
heavyCalculation(cachedValue);
requestAnimationFrame(animate);
}
Memory Management
Clean up event listeners when components are destroyed.
class MyComponent {
constructor() {
this.tweaks = new Tweaks();
this.speed = this.tweaks.addNumber('Speed', 5);
// Store callback reference for cleanup
this.speedCallback = (value) => this.updateSpeed(value);
this.speed.onChange(this.speedCallback);
}
destroy() {
// Clean up listeners
this.speed.removeListener('change', this.speedCallback);
this.tweaks.destroy();
}
}
Mobile Optimization
Consider mobile-specific configurations for better touch interaction.
const isMobile = window.innerWidth < 768;
const tweaks = new Tweaks({
width: isMobile ? 280 : 320,
position: isMobile ? 'bottom-left' : 'top-right',
collapsed: isMobile, // Start collapsed on mobile
hideable: true
});
// Larger step sizes for touch
const sensitivity = isMobile ? 0.1 : 0.01;
const rotation = tweaks.addNumber('Rotation', 0, {
min: -Math.PI,
max: Math.PI,
step: sensitivity
});
Keyboard Shortcuts & Tips
Pro Tips
Best Practices
Meaningful Names
Use descriptive names for your parameters that clearly indicate what they control.
Appropriate Ranges
Set realistic min/max values and step sizes for numeric parameters to provide fine-grained control.
Group Related Parameters
Organize related parameters together and use folders for complex interfaces.
Save Presets
Use Tweaks' preset functionality to save and load different configurations quickly.