Pi.js v2.2.0 expands the WebGL2 rendering foundation introduced in v2.0 with host-controlled canvas layout, automatic WebGL context recovery, and consistent transparent composition across drawing, layers, and contexts. This release removes the deprecated palette options from loadImage() and aligns custom sampler orientation with u_texture, so applications using those features will need small code changes before upgrading.
INTRODUCTION
Pi.js v2.2.0 is a feature release for applications upgrading from any Pi.js v2.x version. Most v2.0 and v2.1 applications can upgrade without code changes, but two intentional compatibility breaks require review: the removal of usePalette and paletteKeys from image loading, and the Y-axis alignment of custom sampler2D uniforms.
Applications upgrading directly from Pi.js v1.2.x should read the v2.0 and v2.1 upgrade guides first because the architectural and API changes introduced in those releases still apply.
UPGRADE AT A GLANCE
-
EXISTING V2.X APPLICATIONS
- Existing drawing, text, input, sound, shader, view, and plugin code remains compatible
- No documented v2.1 commands were removed or renamed
- Host-controlled layout, context recovery, and the polygons plugin are opt-in or automatic
- Applications that do not use palette-based image loading or custom sampler uniforms should behave as they did in v2.1
-
NEW CAPABILITIES
- Let the host page control canvas layout CSS with the
noCssscreen option - Recover automatically from WebGL context loss across all screens sharing a context
- Use the polygons plugin, now bundled with the full version
- Rely on consistent transparent composition across drawing, layers, and contexts
- Let the host page control canvas layout CSS with the
-
BEHAVIOR TO REVIEW
loadImage()andloadSpritesheet()no longer acceptusePaletteorpaletteKeys- Images retain their source colors when screen palettes change
- Custom
sampler2Dinputs now align withu_textureorientation ready()callbacks now run asynchronously- Input cancellation now resolves with
null - Applications must redraw their content after a restored WebGL context
NEW FEATURES
-
HOST-CONTROLLED CANVAS LAYOUT
- The
screen()options object accepts a new optionalnoCssproperty - With
noCss: true, Pi.js still appends the canvas to its container and sets its backing-store size - Pi.js does not apply layout CSS, leaving positioning, sizing, and responsive behavior to the host page
- This is useful for custom layouts, CSS frameworks, and embedded canvases managed by application stylesheets
Host-controlled layout example:
$.screen( { "aspect": "320x200", "noCss": true } ); - The
-
WEBGL CONTEXT RECOVERY
- When a WebGL context is lost, all screens sharing that context suspend together
- On restoration, Pi.js rebuilds GPU resources automatically, including textures, framebuffers, and cached shader programs
- Restored framebuffers start transparent; applications must redraw their content after restoration
- Parented offscreen screens recover alongside their parent because they share the parent’s context
- No application code is required to detect the loss itself, but redraw logic should be reachable after recovery
-
POLYGONS PLUGIN IN THE FULL VERSION
- The polygons plugin is now included with the full Pi.js build
- Applications using the full bundle no longer need to load the plugin separately
- Applications using the lite build can continue loading the plugin as an external bundle
-
CONSISTENT TRANSPARENT COMPOSITION
- Alpha handling is now consistent across direct drawing, offscreen layers, and shared contexts
- Compositing an offscreen screen onto a parent produces the same result whether or not the contexts are shared
- Transparent regions behave predictably when layering multiple offscreen screens
BEHAVIORAL CHANGES
-
IMAGE LOADING PALETTE OPTIONS REMOVED
loadImage()andloadSpritesheet()no longer acceptusePaletteorpaletteKeys- Passing these options no longer has any effect; no compatibility shim is provided
- Images always retain their source colors, even when the screen palette changes after loading
- Applications that relied on palette-mapped image colors should bake the desired colors into their image assets or apply a shader effect instead
-
CUSTOM SAMPLER ORIENTATION ALIGNED
- Custom
sampler2Duniform inputs now use the same orientation as the built-inu_texture - Remove any
1.0 - uv.yworkaround that was applied only to custom image maps - Shaders that sample both
u_textureand a custom sampler can now use the same texture coordinates for both
Before v2.2:
vec2 uv = vec2( v_texCoord.x, 1.0 - v_texCoord.y ); vec4 overlay = texture( u_overlay, uv );With v2.2:
vec4 overlay = texture( u_overlay, v_texCoord ); - Custom
-
ASYNCHRONOUS READY CALLBACKS
ready()callbacks now always run asynchronously, even when resources are already available- Code that assumed synchronous execution immediately after
ready()should be reviewed
-
INPUT CANCELLATION RESOLVES WITH NULL
- Cancelled input operations now resolve with
null - Code waiting on input should handle a
nullresult as a cancellation signal
- Cancelled input operations now resolve with
FIXES AND RESOURCE MANAGEMENT
-
SCREEN REMOVAL AND SELECTION
- Removing a screen now keeps global commands bound to the active surviving screen
- Selecting a screen after removal no longer references the deleted screen
- Failed screen creation rolls back cleanly without leaving partial state
-
INPUT COORDINATE ACCURACY
- Mouse and touch coordinates now account for CSS scaling, borders, padding, and page scrolling
- Pointer positions remain correct when the canvas is styled by the host page, including with
noCsslayouts
-
DRAWING CORRECTNESS
- Large draw operations use bounded batches, avoiding resource spikes on heavy frames
- Full-turn arcs now render identically to complete circles
-
LIFECYCLE EDGE CASES
- Image, font, audio, and plugin lifecycle issues around removal, late events, and failed initialization are resolved
- Late events from removed resources no longer fire into disposed screens
- Failed plugin initialization no longer leaves partially registered state
PERFORMANCE IMPROVEMENTS
- Cached static images and sprites avoid unnecessary WebGL state queries during drawing
- Triangle and line geometry use bounded reserves and copies, reducing allocation churn
- Large draw operations batch within fixed limits for more predictable frame times
API COMPATIBILITY
Pi.js v2.2.0 does not remove or rename any documented v2.1 command. Two option-level changes are intentional breaks: the removal of usePalette and paletteKeys from image loading, and the orientation alignment of custom sampler2D uniforms.
EXTENDED COMMANDS
screen()accepts a new optionalnoCssoptions propertyloadImage()no longer acceptsusePaletteorpaletteKeysloadSpritesheet()no longer acceptsusePaletteorpaletteKeysready()callbacks now always run asynchronously
BUNDLED PLUGINS
- The polygons plugin is now included with the full version
MIGRATION GUIDE
-
UPDATE THE LIBRARY
- Replace all Pi.js v2.x bundle files with matching v2.2 bundle files
- Keep full, lite, ESM, and IIFE variants consistent with the variant already in use
- Update separately loaded plugin bundles at the same time when applicable
- Do not mix v2.1 core files and v2.2-generated type definitions
- If you use the full build and load the polygons plugin separately, remove the duplicate plugin script
-
REMOVE PALETTE LOADING OPTIONS
- Search for
usePaletteandpaletteKeysin all image and spritesheet loading calls - Remove these options; they no longer have any effect
- If palette-mapped colors were intentional, bake the colors into the source assets or use a custom shader
- Verify images that were loaded before palette changes still appear with the expected colors
Before v2.2:
await $.loadImage( "hero", "hero.png", { "usePalette": true } );With v2.2:
await $.loadImage( "hero", "hero.png" ); - Search for
-
FIX CUSTOM SAMPLER ORIENTATION
- Search shader source for
1.0 -applied to texture coordinates used with custom samplers - Remove Y-flip workarounds that were applied only to custom image maps
- Keep any flip that corrects for a genuinely different source, such as raw video elements, if visually required
- Test shaders that sample both
u_textureand a custom sampler with shared coordinates
- Search shader source for
-
VERIFY EXISTING CODE
- Run the application without adopting any new features
- Check transparent layering between offscreen screens and their parents
- Check code that runs immediately after
ready()for ordering assumptions - Check input handling code for the new
nullcancellation result - Test mouse and touch accuracy on pages with CSS scaling, borders, padding, or scrolling
-
ADOPT HOST-CONTROLLED LAYOUT
- Add
noCss: truewhen the host page should own canvas layout - Provide explicit CSS for canvas position and display size in the host stylesheet
- Verify pointer coordinates remain accurate under the host layout
- Add
-
PREPARE FOR CONTEXT RECOVERY
- Structure drawing code so the full scene can be redrawn on demand
- Do not assume framebuffer contents survive a context loss
- Test recovery using browser developer tools that simulate WebGL context loss
- Verify all screens sharing a context, including parented offscreen screens, redraw correctly
-
TEST CLEANUP AND REMOVAL
- Test removing the active screen and confirm global commands target the surviving screen
- Test failed screen creation paths and confirm no partial screens remain
- Test removing images, fonts, and audio while events are still pending
TECHNICAL DETAILS
CONTEXT RECOVERY MODEL
- Context loss suspends every screen bound to the lost WebGL context
- Restoration rebuilds textures, framebuffers, and cached shader programs per screen
- Restored framebuffers are transparent; previous pixel contents are not preserved
- Parented offscreen screens share the parent’s context and recover with it
CANVAS LAYOUT MODEL
- By default, Pi.js continues to manage canvas layout CSS as in v2.1
- With
noCss: true, Pi.js manages only canvas creation, attachment, and backing-store size - Input coordinate mapping accounts for host-applied CSS transforms, borders, padding, and scrolling
IMAGE COLOR MODEL
- Images are stored and rendered with their source colors
- Screen palette changes no longer remap previously loaded image colors
- Palette-based color effects can be reproduced with custom fragment shaders
RESOURCE LIFECYCLE
- Screen removal rebinds global commands to the active surviving screen
- Failed screen creation rolls back allocated resources
- Removed images, fonts, and audio resources ignore late-arriving events
UPGRADE CHECKLIST
- ☐ Replace v2.x bundles and type definitions with v2.2 versions
- ☐ Remove
usePaletteandpaletteKeysfrom image and spritesheet loading - ☐ Remove Y-flip workarounds applied only to custom sampler uniforms
- ☐ Remove duplicate polygons plugin scripts when using the full build
- ☐ Review code that assumed synchronous
ready()callbacks - ☐ Handle
nullresults from cancelled input operations - ☐ Verify transparent composition across offscreen layers and contexts
- ☐ Structure scenes so they can be redrawn after context restoration
- ☐ Test pointer accuracy under CSS scaling, borders, padding, and scrolling
- ☐ Test screen removal and confirm global commands follow the surviving screen
- ☐ Test host-controlled layouts when adopting
noCss
SUMMARY
- ✅ Host-controlled canvas layout with the
noCssscreen option - ✅ Automatic WebGL context loss recovery across shared contexts
- ✅ Polygons plugin bundled with the full version
- ✅ Consistent transparent composition across drawing, layers, and contexts
- ✅ Accurate pointer coordinates under CSS scaling, borders, padding, and scrolling
- ✅ Custom sampler orientation aligned with
u_texture - ✅ Cleaner screen removal, creation rollback, and resource lifecycle handling
- ✅ Reduced WebGL state queries and bounded geometry batching for better performance
Most v2.1 applications require only a bundle update. Review image loading options, custom sampler orientation, ready() timing assumptions, and input cancellation handling before upgrading.
For detailed API documentation, visit: https://pijs.org/api