PinePaper Studio — AI Agent Skills Reference
What is PinePaper? A professional web app for creating animated text, graphics, diagrams, and data visualizations on an infinite canvas. Powered by Paper.js vector math — everything is resolution-independent and exportable. How AI agents use it: Via MCP tools (@pinepaper.studio/mcp-server) or the Agent Mode JS API (window.PinePaperAgent).
Table of Contents
- Item Creation
- Animation
- Relations (Inter-Item Behaviors)
- Keyframe Animation
- Text & Typography
- Diagrams & Flowcharts
- Maps & Geospatial
- Masking & Reveal Effects
- Visual Effects
- Image Filters
- Rigging & Skeletal Animation
- Blending & Compositing
- 3D Projection
- Background Generators
- Camera Control
- Export Formats
- Canvas & View Management
- Selection & Queries
- History
- Agent Mode Quick Start
- MCP Tool Reference
Item Creation
Create items with app.create(type, params). All items are vector-based and infinitely scalable.
Item Types
| Type | Key Parameters |
|---|---|
text | content, fontSize, fontFamily, fontWeight, color, x, y |
circle | radius, fillColor, strokeColor, x, y |
rectangle | width, height, fillColor, cornerRadius, x, y |
ellipse | radiusX, radiusY, fillColor, x, y |
triangle | radius, fillColor, x, y |
star | radius, points, innerRadius, fillColor, x, y |
polygon | radius, sides, fillColor, x, y |
line | from, to, strokeColor, strokeWidth |
path | segments, strokeColor, closed |
arc | from, through, to, strokeColor |
Common Parameters (All Items)
x, y — Position
fillColor — Fill (hex, rgba, or gradient object)
strokeColor — Stroke color
strokeWidth — Stroke width
opacity — 0-1
rotation — Degrees
scale / scaleX/Y — Uniform or axis scale
shadowColor — Shadow color
shadowBlur — Shadow blur radius
shadowOffset — [dx, dy]
blendMode — CSS blend mode string
label — String or { content, position, fontSize, color }Gradient Colors
fillColor: {
type: 'linear', // or 'radial'
stops: [
{ color: '#ff0000', offset: 0 },
{ color: '#0000ff', offset: 1 }
],
origin: [100, 100],
destination: [500, 500]
}Batch Operations
app.batchCreate([
{ type: 'text', params: { content: 'Hello', x: 200, y: 200 } },
{ type: 'circle', params: { radius: 50, x: 400, y: 300 } }
]);Animation
Simple Animations
Apply via app.animate(item, { animationType, animationSpeed }) or inline during creation.
| Type | Effect | Key Params |
|---|---|---|
pulse | Scale breathing | speed, intensity |
rotate | Continuous spin | speed |
bounce | Vertical bounce | speed, intensity |
fade | Opacity pulse | speed, intensity |
wobble | Side-to-side rock | speed, intensity |
shake | Rapid jitter | speed, intensity |
swing | Pendulum swing | speed, intensity |
jelly | Elastic squash/stretch | speed, intensity |
typewriter | Character-by-character reveal | speed |
Inline Animation
app.create('text', {
content: 'Hello World',
x: 400, y: 300,
animationType: 'bounce',
animationSpeed: 1.2,
animationIntensity: 0.15
});Relations
Relations define persistent inter-item behaviors. Add with app.addRelation(sourceId, targetId, type, params).
Motion Relations
| Relation | Description | Key Params |
|---|---|---|
orbits | Circular motion around target | radius, speed, direction, phase |
follows | Move toward target | offset, smoothing, delay |
attached_to | Move with target | offset, inherit_rotation |
maintains_distance | Stay fixed distance | distance, strength |
points_at | Rotate to face target | offset_angle, smoothing |
mirrors | Mirror position | axis, center |
parallax | Depth-based movement | depth, origin |
bounds_to | Stay within bounds | padding, bounce |
spring_follow | Physics spring motion | stiffness, damping, mass, maxDisplacement |
Animation Relations
| Relation | Description | Key Params |
|---|---|---|
grows_from | Scale in from zero | origin, duration, delay, easing |
staggered_with | Staggered effect | index, stagger, effect |
indicates | Highlight pulse | scale, color, duration, repeat |
circumscribes | Draw shape around target | shape, color, strokeWidth, fadeOut |
wave_through | Wave distortion | amplitude, frequency, direction |
morphs_to | Shape morph | duration, easing, morphColor, morphSize |
Camera Relations
| Relation | Description | Key Params |
|---|---|---|
camera_follows | View tracks item | smoothing, offset, zoom, deadzone |
camera_animates | Keyframe camera | keyframes, duration, loop |
Procedural Relations
| Relation | Description | Key Params |
|---|---|---|
wiggle | Noise-driven motion | property, frequency, amplitude, seed |
driven_by | Property linking | sourceProperty, targetProperty, multiplier |
time_expression | Math-based motion | property, expression, baseValue |
Character Relations
| Relation | Description | Key Params |
|---|---|---|
part_of | Semantic child | role (e.g., eye_left, mouth) |
expresses | Facial expression | expression, interval, duration |
Convenience Methods
app.addRelation(sourceId, targetId, type, params);
app.removeRelation(sourceId, targetId, type);
app.replaceRelation(sourceId, targetId, type, params);
app.getRelations(itemId);
app.hasRelation(sourceId, targetId, type);
app.addParts(parentId, { eye_left: id1, eye_right: id2 });Time-Scoped Relations
Any relation supports startTime, endTime, and autoRemove to limit when it's active during timeline playback.
Keyframe Animation
Full timeline-based animation with per-property easing, spatial paths, and morphing.
app.create('circle', {
radius: 40, x: 100, y: 300,
animationType: 'keyframe',
keyframes: [
{ time: 0, properties: { x: 100, opacity: 0 }, easing: 'easeOut' },
{ time: 1, properties: { x: 500, opacity: 1 } },
{ time: 2, properties: { x: 500, y: 100, scale: 2 }, easing: 'bounce' }
]
});Animatable Properties
x, y, position, scale, scaleX, scaleY, rotation, opacity, fillColor, strokeColor, fontSize, strokeWidth, shadowBlur, shadowOffsetX, shadowOffsetY, segments (path morphing), trimStart, trimEnd, trimOffset
Easing Functions
linear, easeIn, easeOut, easeInOut, easeInCubic, easeOutCubic, easeInOutCubic, bounce, elastic, or custom cubic bezier [x1, y1, x2, y2]
Per-Property Easing
{ time: 1, properties: { x: 500, y: 100 }, propertyEasings: { x: 'bounce', y: 'easeOut' } }Spatial Motion Paths
{ time: 0, properties: { x: 100, y: 300 }, spatialHandles: { out: [50, -100] } },
{ time: 1, properties: { x: 500, y: 300 }, spatialHandles: { in: [-50, -100] } }Trim Paths (Line Draw Effect)
app.create('path', {
segments: [[100, 300], [700, 300]],
strokeColor: '#3b82f6',
animationType: 'keyframe',
keyframes: [
{ time: 0, properties: { trimEnd: 0 } },
{ time: 2, properties: { trimEnd: 1 }, easing: 'easeOut' }
]
});Timeline Playback
app.playKeyframeTimeline(duration, loop);
app.pauseKeyframeTimeline();
app.stopKeyframeTimeline();
app.seekKeyframeTimeline(time);Animation Presets Library
Import from js/templates/_shared/animations.js:
Reveal: fadeInUp, fadeInDown, fadeInLeft, fadeInRight, fadeIn Scale: popIn, explosivePop, scalePulse, breathe Physics: gravityDrop, rubberBand, swing, elasticSnap Paths: spiralIn, sineFloat, figureEight, circularOrbit Glitch: glitchFlicker, motionBlurSnap, cyberScan Exit: zoomOut, fadeOutDown, hingeDrop, shrinkAway
Text & Typography
Letter Collage
Break text into individually styled/animated letters:
const collage = app.letterCollage.create('HELLO', {
style: 'tile', // tile, magazine, paperCut, fold, gradient
palette: 'neon', // wordle, scrabble, candy, neon, rainbow, pastel, etc.
fontSize: 48,
x: 200, y: 150
});Tile Palettes: wordle, scrabble, candy, neon, rainbow, pastel, cotton, earth, ocean, forest, sunset, corporate, minimal, monochrome, christmas, halloween, valentines, magazine, ransom, newspaper
Gradient Palettes: rainbow, sunset, fire, gold, rose, ocean, ice, forest, midnight, cyberpunk, neonGlow, chrome
Staggered Letter Animation
app.letterCollage.applyStaggeredAnimation(collageId, {
effect: 'fadeSlideUp', // fadeSlideDown, popIn, typewriter, wave
staggerDelay: 0.1,
duration: 0.5,
sequence: 'linear' // reverse, random, center, fibonacci, wave
});Cursive Handwriting
app.createCursiveText('Hello World', {
x: 200, y: 300, scale: 2,
strokeColor: '#f59e0b', strokeWidth: 3,
animate: true, duration: 3
});Font Studio
Create custom fonts from drawn glyphs:
app.fontStudio.createGlyph(char, paperPath);
app.fontStudio.downloadFont('otf');
app.fontStudio.loadIntoDocument();Diagrams & Flowcharts
Create Diagram Shapes
app.diagramSystem.createShape('process', { position: new Point(x, y), label: 'Step 1' });
app.diagramSystem.createShape('decision', { position: new Point(x, y), label: 'Yes/No?' });Shape Types: process, decision, terminal, data, document, database, cloud, server, uml-class, uml-usecase
Comment Shapes: speech-bubble, speech-bubble-square, thought-bubble, comment-box, speech-bubble-pointed, double-bubble, quote-bubble, callout-box
Connect & Layout
app.diagramSystem.connect(shape1, shape2);
await app.diagramSystem.applyLayout(null, 'hierarchical', { direction: 'TB' });Layout Algorithms: hierarchical, force-directed, tree, radial, grid
Mermaid Import/Export
// Import Mermaid syntax
const result = app.importMermaid(`
graph TD
A[Start] --> B{Decision}
B -->|Yes| C[Action]
B -->|No| D[End]
`);
// Export current diagram as Mermaid
const mermaid = app.exportMermaid({ direction: 'LR' });Arrow System
app.arrowSystem.createArrow([point1, point2], {
lineColor: '#333', lineWidth: 2,
headStyle: 'stealth' // classic, stealth, sharp, open, none
});Maps & Geospatial
Load a Map
const map = await app.mapSystem.loadMap('world', {
projection: 'naturalEarth',
quality: 'standard',
interactive: true,
showOcean: true
});Available Maps: world, worldHighRes, usa, usaCounties, canada, india, europe
Projections: naturalEarth, mercator, robinson, orthographic, equirectangular, albers, albersUsa, conicEqualArea, winkelTripel
Choropleth & Data Visualization
app.mapSystem.applyDataColors(
{ 'USA': 90, 'CAN': 75, 'MEX': 60 },
{ colorScale: ['#f7fbff', '#08519c'], legend: true, legendTitle: 'Score' }
);Region Control
app.mapSystem.highlightRegions(['USA', 'CAN'], { fill: '#ef4444' });
app.mapSystem.animateReveal('all', { duration: 1, stagger: 0.05, effect: 'fadeIn' });Markers & Labels
app.mapSystem.addMarker(-122.4, 37.8, { shape: 'pin', label: 'San Francisco' });
app.mapSystem.addRegionLabel('USA', { content: 'United States', fontSize: 14 });Region Animation
app.animateMapWave({
duration: 10, loop: true,
colors: ['#ef4444', '#fbbf24', '#22c55e', '#3b82f6'],
waveDirection: 'horizontal'
});Import/Export
app.mapSystem.exportSVG();
app.exportMapGeoJSON({ includeStyles: true });
app.exportMapRegionDataCSV();
await app.importCustomMap(geoJson);Masking & Reveal Effects
Static Masks
app.applyMask(item, 'circle', { radius: 100 });
app.applyMask(item, 'star', { points: 5, radius: 80 });Mask Types: rectangle, circle, ellipse, star, triangle, hexagon, heart, rounded, custom
Mask Modes: clip (show inside), subtract (show outside), intersect (overlap only)
Animated Mask Reveals
app.applyAnimatedMask(item, 'wipeLeft', { duration: 0.8 });Preset Animations: wipeLeft, wipeRight, wipeUp, wipeDown, iris, irisOut, star, heart, curtainHorizontal, curtainVertical, cinematic, diagonalWipe, revealUp, revealDown
Mask Stacking
app.maskingSystem.addMask(item, 'circle', { mode: 'clip' });
app.maskingSystem.addMask(item, 'rectangle', { mode: 'subtract' });Visual Effects
Apply particle/FX effects to items:
app.applyEffect(item, 'sparkle', { color: '#ffd700', speed: 2 });
app.applyEffect(item, 'confetti', { colors: ['#ff0', '#f0f', '#0ff'], count: 50 });Effect Types:
| Effect | Key Params |
|---|---|
sparkle | color, speed, size |
blast | color, radius, count, interval |
fire | color, size, turbulence |
smoke | color, size, drift |
rain | color, count, speed, angle |
snow | color, count, speed, spread |
confetti | colors[], count, gravity |
ripple | color, maxRadius, ringCount |
glow | color, speed, intensity |
electric | color, boltCount, length |
Image Filters
GPU-accelerated filters for raster images:
await app.applyImageFilter(raster, 'blur', { radius: 5 });
// Chain multiple filters
await app.applyImageFilterChain(raster, [
{ name: 'brightness', params: { value: 20 } },
{ name: 'contrast', params: { value: 15 } },
{ name: 'vignette', params: { intensity: 0.5 } }
]);Filters: grayscale, sepia, brightness, contrast, saturation, invert, posterize, hsl, colorTint, vignette, edgeDetect, blur
Cutout Style Presets
await app.applyCutoutStyle(item, 'sticker');Presets: papercut, postcard, sticker, poster, monochromeCut, edgeSketch, warmGlow, coolTone
Rigging & Skeletal Animation
Create a Skeleton
const skeletonId = app.riggingSystem.createSkeleton('character', { x: 400, y: 500 });
const spine = app.riggingSystem.addBone(skeletonId, { name: 'spine', length: 100, angle: -90 });
const head = app.riggingSystem.addBone(skeletonId, { name: 'head', length: 40, angle: -90, parentBoneId: spine });Rig Presets
Apply a full preset skeleton in one call:
const preset = getRigPreset('humanoid');
const { boneMap, chainIds } = applyRigPreset(app.riggingSystem, skeletonId, preset);Presets: humanoid (20 bones), quadruped (13), spider (19), bird (15), fish (14), hand (17), centaur (29), simple_arm (3), snake (10), chain (5)
IK Solvers
app.riggingSystem.createIKChain(skeletonId, {
name: 'left_arm', boneIds: [upperArm, lowerArm],
solverType: 'two_bone' // 'fabrik', 'two_bone', 'ccd'
});Poses & Shape Keys
// Save/load poses
const poseId = app.riggingSystem.savePose(skeletonId, 'wave');
app.riggingSystem.loadPose(skeletonId, poseId);
app.riggingSystem.interpolatePoses(poseA, poseB, 0.5);
// Shape keys (blend shapes)
const blinkKey = app.riggingSystem.saveShapeKey(skeletonId, 'blink');
app.riggingSystem.loadShapeKey(skeletonId, blinkKey, 0.8); // weight 0-1Expressions
Built-in facial expressions: blink, smile, frown, surprise, wink, talk
app.addRelation(faceId, null, 'expresses', { expression: 'blink', interval: 3 });Path Skinning (2D LBS)
app.riggingSystem.skinPath(skeletonId, itemId, { maxInfluences: 2 });Blending & Compositing
app.blendingSystem.applyPreset(itemId, 'neon');
app.blendingSystem.transitionBlendMode(itemId, 'screen', { duration: 0.5 });
app.blendingSystem.setGroupBlendMode(groupId, 'multiply', { cascadeOpacity: true });Presets: ghost, neon, shadow, glow, xray, dreamy, vintage
Blend Modes: normal, multiply, screen, overlay, darken, lighten, color-dodge, color-burn, hard-light, soft-light, difference, exclusion, hue, saturation, color, luminosity
Interactive Blending
app.blendingSystem.addInteractiveBlend(itemId, {
event: 'hover',
modes: ['normal', 'screen'],
opacities: [1.0, 0.8]
});3D Projection
Render 3D primitives onto the 2D canvas:
app.createObject3D('cube', { size: 1.5, color: '#3b82f6', rotationY: 45 });
app.createObject3D('sphere', { radius: 1, color: '#ef4444' });
app.createGlossySphere({ x: 400, y: 300, radius: 60, color: '#F97316' });
app.setProjection3D('perspective', { fov: 60 });
app.setCamera3D({ position: { x: 3, y: 2, z: 5 }, target: { x: 0, y: 0, z: 0 } });Primitives: cube, sphere, cylinder, torus, cone
Projections: perspective, orthographic, isometric, cabinet, cavalier
Background Generators
Procedural animated backgrounds:
app.executeGenerator('drawBokeh', { circleCount: 30, animated: true });
app.executeGenerator('drawConstellation', { animated: true });
app.executeGenerator('drawWaves', { waveCount: 8, fill: true, animated: true });Generators:
| Name | Description |
|---|---|
drawBokeh | Depth-of-field circles |
drawGradientMesh | Multi-color gradient blobs |
drawOrganicFlow | Aurora/silk flowing layers |
drawWaves | Flowing wave lines |
drawStarfield | Animated starfield |
drawNeonGrid | Glowing neon grid |
drawCircuit | Circuit board with pulses |
drawConstellation | Connected star points |
drawGrid | Customizable animated grid |
drawSunburst | Radiating rays |
drawFlowField | Directional flow particles |
drawNoiseTexture | Perlin noise texture |
drawKaleidoscope | Kaleidoscope pattern |
drawTessellation | Geometric tiling |
drawSunsetScene | Animated sunset |
drawCosmosSpace | Space scene |
drawFireflies | Floating fireflies |
drawFallingPetals | Falling petals |
drawGeometricAbstract | Overlapping shapes |
drawMetaballs | Organic blobs |
drawGoldenSpiral | Golden ratio spiral |
drawPerspectiveGrid | 3D perspective grid |
Camera Control
app.camera.zoomIn(2, 0.5); // Zoom 2x over 0.5s
app.camera.panTo(200, 200, 0.5); // Pan to point
app.camera.moveTo(200, 200, 2, 0.5); // Pan + zoom
app.camera.reset(0.5); // Reset view
// Keyframe camera animation
app.addRelation('camera', null, 'camera_animates', {
duration: 6, loop: true,
keyframes: [
{ time: 0, zoom: 1, center: [400, 300] },
{ time: 3, zoom: 2, center: [600, 300], easing: 'easeInOut' },
{ time: 6, zoom: 1, center: [400, 300] }
]
});Export Formats
| Format | Method | Notes |
|---|---|---|
| WebM | Export UI | VP9, best for animations |
| MP4 | Export UI | H.264 via WebCodecs (Chrome 94+) |
| GIF | Export UI | Via gif.js Web Workers |
| Animated SVG | app.exportAnimatedSVG() | SMIL or CSS animations |
| PNG | Export UI | Up to 600 DPI |
app.exportPDF({ dpi }) | 300/600 DPI, bleed, trim marks | |
| Lottie | app.exportLottie({ fps, duration }) | JSON for any Lottie player |
| GeoJSON | app.exportMapGeoJSON() | Map data export |
| Mermaid | app.exportMermaid() | Diagram text export |
Canvas & View Management
Canvas Presets
app.setCanvasSize('instagram-post'); // 1080x1080
app.setCanvasSize('youtube-thumbnail'); // 1280x720
app.setCanvasSize('tiktok'); // 1080x1920
app.setCanvasSize({ width: 1920, height: 1080 }); // CustomPresets: youtube-thumbnail, instagram-post, instagram-story, tiktok, a4-portrait, letter-portrait, and more.
View Control
app.getCanvasSize(); // { width, height, preset }
app.expandCanvasToIncludeContent(20); // Fit to content + paddingSelection & Queries
app.select(item);
app.deselect();
app.selectAll();
app.deselectAll();
app.getSelection();
// Registry
app.itemRegistry.getAll();
app.itemRegistry.getByType('text');
app.itemRegistry.getItem(itemId);
// Relation queries
app.hasRelation(sourceId, targetId, type);
app.queryNotRelation(type); // Items without relation
app.queryIsolatedItems(); // Items with no relations
app.queryCompound([...conditions]);
app.queryRelationChain([...types]);History
app.undo();
app.redo();
app.getHistoryState(); // { canUndo, canRedo, undoCount, redoCount }
app.clearCanvas();Agent Mode Quick Start
Activate via URL ?agent=1 or ?mode=agent:
const agent = window.PinePaperAgent;
await agent.configure({ mode: 'agent' });
await agent.waitForReady();
// Create content
const text = app.create('text', { content: 'Hello', x: 400, y: 300, fontSize: 48 });
app.animate(text, { animationType: 'pulse' });
// Export
const result = await agent.quickExport();
// Reset for new canvas
agent.reset({ canvas: 'tiktok' });Smart Export
const rec = agent.getExportRecommendation();
// { format: 'webm', reason: 'Has animations, WebM gives best quality' }MCP Tool Reference
The MCP server (@pinepaper.studio/mcp-server) exposes these tools:
Item Tools
pinepaper_create_item— Create any item typepinepaper_modify_item— Modify item propertiespinepaper_batch_create— Create multiple items
Animation Tools
pinepaper_animate— Apply simple animationpinepaper_keyframe_animate— Apply keyframe animation
Relation Tools
pinepaper_add_relation— Add relation between itemspinepaper_remove_relation— Remove relation
Diagram Tools
pinepaper_create_diagram_shape— Create flowchart shapepinepaper_connect— Connect shapespinepaper_auto_layout— Apply layout algorithm
Map Tools
pinepaper_load_map— Load geographic mappinepaper_highlight_regions— Highlight regionspinepaper_apply_data_colors— Choropleth coloringpinepaper_add_marker— Add map marker
Rigging Tools
pinepaper_create_skeleton— Create skeletonpinepaper_add_bone— Add bonepinepaper_attach_item_to_bone— Attach itempinepaper_apply_rig_preset— Apply presetpinepaper_save_pose/pinepaper_load_pose— Pose managementpinepaper_interpolate_poses— Blend poses
Blending Tools
pinepaper_apply_blend_preset— Apply blend presetpinepaper_transition_blend_mode— Animated blend transitionpinepaper_add_interactive_blend— Interactive blendingpinepaper_set_group_blend_mode— Group blending
Filter Tools
pinepaper_apply_image_filter— Single GPU filterpinepaper_apply_filter_chain— Multi-filter chain
Masking Tools
pinepaper_apply_cutout_style— Apply cutout presetpinepaper_get_cutout_styles— List presets
Lasso Tools
pinepaper_lasso_activate— Activate lasso on imagepinepaper_lasso_apply— Extract region
View Tools
pinepaper_zoom— Set zoom levelpinepaper_pan— Pan viewpinepaper_fit_view— Fit content in viewpinepaper_get_view_state— Get current view
Selection Tools
pinepaper_select— Select itempinepaper_select_all— Select allpinepaper_deselect_all— Deselect allpinepaper_get_selection— Get selectionpinepaper_delete_selected— Delete selected
Transform Tools
pinepaper_nudge— Move itemspinepaper_flip— Flip itemspinepaper_reorder— Change z-order
Background Tools
pinepaper_set_background— Set backgroundpinepaper_clear_background— Clear backgroundpinepaper_get_background— Get background
History Tools
pinepaper_undo/pinepaper_redo— Undo/redopinepaper_get_history_state— Get history statepinepaper_clear_canvas— Clear canvas
Query Tools
pinepaper_query_items— Query items by criteriapinepaper_get_item_by_id— Get specific itempinepaper_hit_test— Hit test at pointpinepaper_is_empty— Check if canvas empty
Precomp Tools
pinepaper_create_precomp— Create compositionpinepaper_add_to_precomp— Add to compositionpinepaper_remove_from_precomp— Remove from composition
Playback Tools
pinepaper_play_timeline— Play keyframe timelinepinepaper_stop_timeline— Stop playbackpinepaper_pause_timeline— Pause playbackpinepaper_seek_timeline— Seek to time
Export Tools
pinepaper_export_svg— Export as SVGpinepaper_export_training_data— Export training data
Generator Tools
pinepaper_execute_generator— Run background generatorpinepaper_list_generators— List available generators
Font Tools
pinepaper_font_create_glyph— Create font glyphpinepaper_font_export— Export font filepinepaper_font_status— Get font creation status