Version v1.77.0 Changelog July 2, 2026
Breaking Changes
Node.js Support
- Engine/Node: Raised the minimum supported Node.js version to 22. Node.js 20 no longer receives security updates as of May 2026, we strongly recommend updating to a supported version.
Asset Sources & Registration
- Engine (Swift + Android): Several built-in asset source IDs were renamed or merged — update any hardcoded IDs:
ly.img.vectorpath→ly.img.vector.shape,ly.img.colors.defaultPalette→ly.img.color.palette, andly.img.filter.lut+ly.img.filter.duotone→ly.img.filter(one source for both LUT and duotone). BecauseaddDefaultAssetSources/addDemoAssetSourcesstill iterate the old IDs, the four renamed/merged IDs are skipped silently against the default asset base URL — shapes, the default palette, and filters go missing until you re-register with the new IDs viaaddLocalAssetSourceFromJSON(Swift) /addLocalSourceFromJSON(Android). The default starter kits now also registerly.img.text,ly.img.text.styles,ly.img.text.curves, andly.img.text.components. - Editor/iOS: Filter selection now uses a single
ly.img.filtersource covering both LUT and duotone effects, detected at runtime via asset metadata. Shape and sticker group identifiers are simplified (e.g."filled"instead of"//ly.img.cesdk.vectorpaths/category/filled"); update any hardcoded group identifiers. - Editor/Android: Filter selection now uses a single
ly.img.filtersource covering both LUT and duotone effects, detected at runtime via asset metadata. - Editor/iOS + Android: Starter kits now register
ly.img.text(basic text presets) andly.img.caption.presets(caption styles) alongside the existing default sources. - Editor/Flutter + React Native: The default
baseUrinow resolves to the updated asset content. If you self-host, copy theassets/directory fromhttps://cdn.img.ly/packages/imgly/cesdk-<flutter|react-native>/<version>/imgly-assets.zipand pointbaseUriat your hosted location. - Migration guide: Migrating to v1.76 covers the full old → new asset source ID mapping, the merged filter source, the new text and caption sources, and how to register sources with
addLocalAssetSourceFromJSONinstead of the deprecated helpers — including how to fix empty or “Cannot connect to service” asset-library panels after upgrading.
Camera & Capture Modes
- Camera/Android: Added photo and mixed (photo + video) capture modes.
CameraConfigurationgainscaptureType(Photo/Video/Mixed),captureCount(Single/Multi),photoClipDuration, andshowsPhotoPreview; results now arrive asCameraResult.Captures(List<Capture>)(withCapture.Photo(uri, clipDuration)/Capture.Video(recording)) via a newCaptureMediaActivityResultContract.CaptureVideo/CaptureVideo.Inputare renamed toCaptureMedia/CaptureMedia.Input(old names@Deprecated(level = ERROR)) andCameraResult.Record([Recording])is@Deprecated(level = ERROR)— extract recordings with the newList<Capture>.videosextension, and swap theis CameraResult.Record ->arm foris CameraResult.Captures ->in exhaustivewhens. - Camera/iOS: Added photo and mixed capture modes via
captureType(.photo/.video/.mixed) andcaptureCount(.single/.multi); captures arrive as a newCaptureenum (.photo(Photo)/.video(Recording)) throughCameraResult.capture([Capture]), and dual-camera mode now captures both cameras (Photo.imagescarries one or two images).CameraResult.recording([Recording])is now@available(*, unavailable, renamed: "capture")— extract recordings with the new[Capture].videosextension and swap the.recordingarm for.capturein exhaustive switches. (The deprecatedResult<[Recording], CameraError>callback initializer is unaffected.) - Camera/ReactNative: The bridge no longer emits
CameraRecordingResult— pure-video sessions return aCameraCaptureResultwithcaptures: Capture[], andPhotochanged from{ uri, duration }to{ images: PhotoImage[], duration }. Replaceresult.recordings.forEach(...)withresult.captures.forEach(...)switching on eachCapture’sphoto/videofield; replacephoto.uriwithphoto.images[0].uri. - Camera/Flutter: The bridge no longer emits
CameraRecording— pure-video sessions return aCameraResultwith a populatedcapture: CameraCapture, andPhotochanged from{ uri, duration }to{ images: List<PhotoImage>, duration }(with a typedRect). Readresult.capture?.capturesand pattern-match eachCapture’sphoto/videofield. - Editor/Android: The IMG.LY camera dock now launches in
Mixed/Multifrom a video editor (captured photos become timeline image-fill blocks using each photo’sclipDuration) and inPhoto/Singlefrom a non-timeline editor (design, photo, apparel, postcard). The design starter-kit dock button now opens the IMG.LY camera (Dock.Button.rememberImglyCamera()) instead of the system camera. - Editor/iOS: When opened from a video editor the camera launches in
.mixed/.multi(captured photos become timeline image-fill blocks whose duration matchesCameraConfiguration.photoClipDuration, 5 seconds by default; dual-camera photos lay out as a PIP); in non-timeline editors it launches in.photo/.single. The design starter-kit dock now usesDock.Buttons.imglyCamera()instead of the systemUIImagePickerControllerflow.
Background Removal
- Editor/iOS:
BackgroundRemovalPluginnow takes aBackgroundRemovalConfigurationand defaults to the IMG.LY IS-Net backend (VisionBackgroundRemovalConfigurationrestores the previous Apple Vision behavior). TheOptionsstruct is removed, and the package ships as four library products so unneeded targets can be excluded. - Editor/Android:
ly.img:plugin-background-removalis now the base package; add a concrete implementation (ly.img:plugin-background-removal-imglyorly.img:plugin-background-removal-google).Dock.Button.rememberBackgroundRemovalnow requires aconfigparameter, anddockModifierreceivesBackgroundRemovalConfig.
Error Handling
- Engine: Error message wording was standardized across the SDK. If you branch on error message substrings (e.g.
error.message.includes(…)), switch to the stableerror.code— existing substring matches may no longer match. See the Error Catalog for the full list of structured error codes. - Engine: Calling
addAsset,removeAsset, orapplyAssetPropertyon a custom asset source that does not implement the operation now throws an error carrying the matchingBINDING.ASSET_SOURCE_ADD_UNSUPPORTED,BINDING.ASSET_SOURCE_REMOVE_UNSUPPORTED, orBINDING.ASSET_SOURCE_APPLY_PROPERTIES_UNSUPPORTEDcode — previouslyaddAsset/removeAssetsilently did nothing andapplyAssetPropertynever completed. Implement the operation or catch the error if you are probing for support.
Keyboard Shortcuts
- Editor/Web: Keyboard shortcuts are now a public, customizable registry via
cesdk.shortcuts, and the listener binds to the editor container instead of thedocument— shortcuts only fire when focus is inside the editor. Restore page-wide behavior withcesdk.shortcuts.setRoot(...), or disable the layer withcesdk.shortcuts.setEnabled(false). The registry exposesset,get,list,remove,has,clear,setEnabled,addScope, andsetRoot; each shortcut is an object withkeys(a chord like'Mod+z'or a sequence array),run(an action id or a function),scope, and optionalwhen,description,category, andsequenceTimeout. See the Migrating to v1.77 guide for details. - Engine/Web: The same keyboard-shortcut registry is available on the engine layer at
engine.shortcuts, so any@cesdk/engineintegration gets shortcuts without the editor UI (same methods).
Editor Configuration
- Editor/Android: Editor configuration composition was fixed so component lambdas that explicitly return
nulloverride parent components instead of falling back to them.
Deprecations
All items below remain functional this release; migrate before they are removed.
- Engine (Swift + Android): The asset-source helper layer —
DefaultAssetSource,DemoAssetSource,populateAssetSource(...),addDefaultAssetSources(...),addDemoAssetSources(...)— is deprecated. Register sources directly viaaddLocalAssetSourceFromJSON(Swift) /addLocalSourceFromJSON(Android) pointing at each source’scontent.json. - Engine (Swift + Android): Asset-source URL constants (
Engine.assetBaseURL/Engine.Companion.assetBaseUri) are deprecated and will be removed in a future version. Build your ownbaseURLfrom bundled assets — for exampleBundle.main.url(forResource: "IMGLYAssets", withExtension: "bundle")on iOS. The IMG.LY CDN is for development and evaluation only; self-host for production. - Editor/Android:
AppearanceAssetSourceType.LutFilterandDuoToneFilterstill resolve but are deprecated — migrate toAppearanceAssetSourceType.Filter. - Editor/iOS:
TextAssetSourceis deprecated. The default text library now uses the split text sources (ly.img.text,ly.img.text.styles,ly.img.text.curves,ly.img.text.components); register and use those instead. - Editor/Android:
TextAssetSourceandAssetSourceType.Textare deprecated. Use the split text sources (AssetSourceType.TextPlain,TextStyles,TextCurves,TextComponents) instead. - Engine: The control-gizmo flags
showMoveHandles,dynamicMoveHandleVisibility,showResizeHandles,showScaleHandles, andshowRotateHandlesare deprecated (still functional) — use the newcontrolGizmo/*HandleVisibilitysettings instead. - Plugins/Web:
convertToPDFX3is now a deprecated alias ofconvertToPDFX.
New Features
AI Image Generation
- Editor/Android: Added the
AIImageGenerationPluginplugin that provides image generation features using AI. - Editor/iOS: Added AI Image Generation plugin (
IMGLYPluginAIImageGeneration)
Text on a Path (Curved Text)
- Engine: Added text-on-curve support. Six new public API methods (
setTextOnPath,getTextOnPath,setTextOnPathOffset,getTextOnPathOffset,setTextOnPathFlipped,getTextOnPathFlipped) let text blocks follow a validated SVG baseline path. Three new properties (text/pathOffset,text/pathFlipped,text/pathExternalRef) control proportional path offset, flipped placement, and the active curve asset reference. The existing vertical alignment (text/verticalAlignment) controls the text’s vertical orientation relative to the curve:Topplaces the bottom of the glyphs on the curve (text above it),Centercenters the glyphs on the curve, andBottomplaces the top of the glyphs on the curve (text below it). - Engine/Web/Android/iOS: The new text-on-path API methods are available on all platforms, e.g.
engine.block.setTextOnPath,engine.block.getTextOnPath. - Engine: Style presets can now place text on a curve. The baseline path lives in the preset’s flat
propertiesmap like any other key:text/path(a virtual property routed throughsetTextOnPath, inheriting its SVG validation and path-bounds sizing; an explicitnullclears the path) alongside the reflectedtext/pathOffsetandtext/pathFlippedproperties. - Engine: Added the Circle, Arch, Wave, and Elevate curve presets to the
ly.img.text.curvesasset source, applied like any other style preset. - Editor/Web: Text-on-curve presets appear as the Curved Text section of the Text library, backed by the
ly.img.text.curvesasset source. - Editor/Android: Added a UI for placing text on a path. The new inspector bar button
InspectorBar.Button.rememberTextOnPath(...)— included in the default inspector bar for text blocks — opens the new sheetSheetType.TextOnPath(style)with a grid of preset curves backed by thely.img.text.curvesasset source, plus path position, direction, and offset controls. - Editor/iOS: Added a UI for placing text on a path. The new inspector bar button
InspectorBar.Buttons.textOnPath(...)— included in the default inspector bar for text blocks — opens the new sheetSheetType.textOnPath(style:)with a grid of preset curves backed by thely.img.text.curvesasset source, plus path position, direction, and offset controls.
Text Presets & Library
- Editor/Web: Reworked the built-in text presets into reusable style presets that apply a complete look (font, color, outline, background, shadow, and animations) in a single step. The default Text library (
ly.img.text) groups them into sections — Plain Text (Default / Elegant / Modern Tech themes), Text Styles (outline, glow, neon, …), Text Combinations (pre-designed text layouts), and Curved Text (text-on-path) — backed by thely.img.text,ly.img.text.styles,ly.img.text.components, andly.img.text.curvesasset sources. TheTextAssetSourceandTextComponentAssetSourceplugins wire all of these into the singlely.img.textentry. The text “Styles” inspector button restyles a block from the same library minus Text Combinations (text designs create new blocks and aren’t valid restyle targets). - Editor/Web:
cesdk.ui.setReplaceAssetLibraryEntriesnow accepts{ entry, excludeSourceIds }objects alongside plain entry IDs, letting you hide specific asset sources from a replacement panel without affecting how that entry behaves on insert. - Editor/Web: Added new caption style presets. The
CaptionPresetsAssetSourceplugin provides them through thely.img.caption.presetsasset source and applies them via the engine’s declarative style-preset mechanism, so captions and text now share the same one-step styling. - Editor/Android: Added
InspectorBar.Button.rememberTextPresets()— a “Presets” inspector-bar button for text blocks that opens a restyle picker offering Plain Text, Text Styles, and Curved Text presets; tapping one restyles the selected block in place via the engine’s style-preset apply path. The button appears once any of thely.img.text,ly.img.text.styles, orly.img.text.curvessources is registered. - Editor/Android: The default asset library “Text” tab now offers four sections — Plain Text, Text Styles, Text Combinations, and Curved Text — each backed by its own asset source (
ly.img.text,ly.img.text.styles,ly.img.text.components,ly.img.text.curves). Plain Text drills into its Default, Elegant, and Modern Tech themes. Tapping a preset creates a pre-styled text block. In the Elements tab these appear as a single “Text” group whose preview mixes all of the text sources. Custom asset libraries can compose these sections viaLibraryContent.Section. - Editor/Android: Added
LibraryContent.Section.groupTitleKeyPrefix— sections expanded from asset groups can derive each group section’s title from a localization key (<prefix><group>), falling back to a humanized group name. - Editor/iOS: Added
InspectorBar.Buttons.textPresets()— a “Presets” inspector-bar button for text blocks that opens a restyle picker offering Plain Text, Text Styles, and Curved Text presets; tapping one restyles the selected block in place via the engine’s style-preset apply path. The button appears once thely.img.text.stylessource is registered. - Editor/iOS: The default asset library “Text” tab now offers four sections — Plain Text, Text Styles, Text Combinations, and Curved Text — each backed by its own asset source (
ly.img.text,ly.img.text.styles,ly.img.text.components,ly.img.text.curves). Plain Text drills into its Default, Elegant, and Modern Tech themes. Tapping a preset creates a pre-styled text block. In the Elements tab these appear as a single “Text” group whose preview mixes all of the text sources. Custom asset libraries can compose these sections viaAssetLibrarySection.
Typeface Library & Language Groups
- Editor/Web: Introduced a new typeface library panel (browse every source, search, filter by language/source) replacing the fonts dropdown.
- Editor/Android + iOS: Every typeface in the
ly.img.typefacesource now declares the language groups it covers (for examplelatin,cyrillic,greek,hebrew) via the assetgroupsfield — query them withengine.asset.getGroups(sourceId)(Android) /getGroups(sourceID:)(iOS) or narrow font queries with group-filteredfindAssets. The umbrella version in every source’scontent.jsonmoves to7.0.0; no sources are added, renamed, or removed and no source IDs change, so no registration changes are required. If you self-host, copy theassets/directory from the platform’simgly-assets.zip. - Editor/Flutter + React Native: Typefaces in the default asset content now declare the language groups they cover via the asset
groupsfield. No source IDs change. - Engine/Web: The default asset source now tags every built-in typeface with language groups so the typeface library can filter the fonts by language.
Text Formatting UI
- Editor/Android + iOS: Added a text formatting UI that stays anchored to the keyboard while the IME is open.
Text Runs API
- Engine (Web / Android / Swift): Added
getTextRunsreturning an ordered list of per-runTextRunInfo(color, font weight, font style, font size, text case, typeface, resolved font file URI, text decoration, and kerning):engine.block.getTextRuns(id, from, to)(Web),getTextRuns(block, from, to)→List<TextRunInfo>(Android), andgetTextRuns(_ id:, in subrange:)→[TextRunInfo](Swift).
Crop — Original Aspect Ratio
- Editor/iOS + Android: Added an “Original” crop preset to the crop sheet that reverts a block to the intrinsic aspect ratio of its image or video content.
- Engine (Swift + Android): Added
canRevertToOriginalRatio(BlockAPI.canRevertToOriginalRatio(_:)/BlockApi.canRevertToOriginalRatio(block)) to query whether a block can revert to the intrinsic aspect ratio of its image or video content.
Control Gizmo Handle Visibility
- Engine: New
controlGizmo/moveHandleVisibility,controlGizmo/resizeHandlesVisibility,controlGizmo/scaleHandlesVisibilityandcontrolGizmo/rotateHandlesVisibilitysettings ('auto' | 'always' | 'never', default'auto'). Use'always'to keep a handle visible while editing text, so a block can be moved, resized or rotated while typing. (These supersede the oldershow*Handlesflags — see Deprecations.)
Actions Registry
- Engine: Added
engine.actions, a registry of named editor commands — undo, redo, delete, duplicate, group, align, crop, text formatting, zoom, pan, and many more. Run one by id (engine.actions.run('undo')), change what a built-in does, or add your own. Clicks, double-clicks, wheel zoom, and right-click/long-press run through the same registry, so an override applies consistently across the editor. Available with@cesdk/engineand@cesdk/node; the register, override, and keyboard-rebinding APIs are not yet exposed on the iOS and Android bindings.
Structured Errors
- Engine/Web: Errors thrown by
CreativeEngineare nowEngineErrorinstances (extendingError) with a stablecode(e.g."SCENE.NOT_VALID") pluscategory,hint,args,docsUrl, andsilent. Existingtry/catchcode that readserror.messagekeeps working — new code can branch onerror.codeinstead of matching message strings. A typedEngineErrorCodeunion of all codes is exported from@cesdk/engine(and re-exported from@cesdk/cesdk-jstogether withEngineError/isEngineError) for compile-time-checked branching.error.codestays astring, so unknown or future codes never break consumers. See the Migrate to Structured Errors guide for how to move off message-string matching. - Engine/Swift: Thrown
NSErrors now carry the structured fields inuserInfo(EngineErrorCodeKey,EngineErrorCategoryKey, …);domainandcodeare unchanged. Thehintand docs URL surface through Foundation’s standard slots (localizedRecoverySuggestion/helpAnchor). Wrap an error withEngineError(error)to readcode,category,hint,args,docsURL, andsilent, then branch oncodeinstead oflocalizedDescription. Use theEngineErrorCodeenum toswitchon codes without bare strings. See the Migrate to Structured Errors guide for how to move off message-string matching. - Engine/Android:
EngineExceptionnow exposescode,category,hint,args,docsUrl, andsilent. Existing code that readse.messagekeeps working — new code can branch one.codeand surface the relevant docs page viae.docsUrl. Use theEngineErrorCodeconstants inly.img.engineto branch without bare strings. See the Migrate to Structured Errors guide for how to move off message-string matching. - Editor: Engine error dialogs across Web, iOS, Android, Flutter, and React Native now show customer-facing, localizable copy keyed off the structured engine error
code, falling back to the engine’s English message when no copy is authored — so a dialog never shows a blank or a raw code. You can override this copy per error code and resolve it yourself in custom error handlers. See the Custom Error Messages guide for authoring copy and the Error Catalog for the full list of structured error codes.
Node-Native Engine & ESM Build
- Engine/Node: New
@cesdk/node-nativepackage shipping a native N-API addon for macOS (arm64, x64) and Linux x64 (glibc ≥ 2.39). Drop-in replacement for@cesdk/node(WASM) with GPU rendering, real video/audio export, and no WebAssembly memory ceiling. Switch the import —import CreativeEngine from '@cesdk/node-native'— and the existing code keeps working. Windows, Alpine/musl, Linux arm64, and AWS Lambda are unsupported in this release; those workloads stay on@cesdk/node. Licensing requirements are unchanged from@cesdk/node— see the package README and https://img.ly/pricing for details. Nightly builds publish under the@devdist-tag for early validation. - Engine/Node: Ship a real ESM build alongside the existing CJS build.
importresolves to./build/index.mjsand exposesCreativeEngineas the default export plus all named exports (LogLevel, color helpers,MimeType, etc.);requirecontinues to return theCreativeEngineclass with named exports attached as properties. No source code changes are required for existing CJS consumers.
Print & PDF Output
- Plugins/Web: Added
convertToPDFXto@imgly/plugin-print-ready-pdfs-web. Supports both PDF/X-3 and PDF/X-4 viaoutputStandard, defaulting to PDF/X-4 so live transparency is preserved and vector text on transparent pages is no longer rasterized. (SupersedesconvertToPDFX3— see Deprecations.) - Engine/Renderer: Added support for underlayer settings, text overhang, and PDF device CMYK export options
Improvements & Behavior Changes
Typefaces & Font Library
- Editor/Web: Removed the font style/weight dropdown from the default text controls; weight and style are now set via the typeface library panel and the bold/italic toggles.
- Editor/Web: The typeface select tooltip now shows the selected typeface name.
- Engine:
ly.img.document-typefacesasset source stays in sync with the scene. Entries are removed once no text or caption block references the typeface anymore, andonAssetSourceUpdatedfires after every mutation.
Text Presets & Library
- Editor/Web: The default
ly.img.textlibrary keeps the source ID it has used since earlier versions, but its content changed from the basic Title / Headline / Paragraph entries to the new Plain Text style presets (per-asset IDs are now group-scoped, e.g.ly.img.text.default.title); thely.img.text.styles,ly.img.text.curves, andly.img.text.componentssources join the same entry. See the Migrating to v1.77 guide for details. - Editor/Web: Caption style presets now set the caption’s font size and frame, scaled to the page, so applying one sizes the caption consistently and the size scales with the page resolution.
Keyboard Shortcuts
- Engine: Keyboard shortcuts are no longer handled inside the engine. If you embed
@cesdk/enginewithout the CE.SDK editor UI and relied on the engine reacting to key presses (undo/redo, delete, arrow-key nudge, and so on), handle the key events yourself and dispatch the matching command throughengine.actions. Integrations that use the prebuilt CE.SDK editor are unaffected — on the web it maps keys to actions for you.
Performance
- Engine: Added viewport-aware page culling for multi-page scenes. Only visible pages are processed each frame, dramatically improving performance for photobook-style scenes with 100+ pages. Controlled via
features/viewportCullingEnabledsetting (enabled by default). - Editor/Android: Improved pages mode performance for large scenes. Page thumbnails are now rendered sequentially with an in-memory cache, so re-entering pages mode displays thumbnails instantly.
Bug Fixes
Engine
- Fixed a data race in the audio time-stretcher that could crash playback when scrubbing or splitting a video clip at a playback speed other than 1.
- Fixed line shapes losing their gradient or image fill and turning solid black. Lines now render gradient, image, and video fills correctly.
- Fixed movement constraint clamping for rotated blocks. The constraint now follows the block’s axis-aligned bounding box in page space, so rotating a block no longer lets its visible bounds drift past the page edge along its long axis.
- Fixed PDF exports with
exportPdfWithDeviceCMYKlosing spot color names. Spot colors now keep their name in the exported PDF, so print shops can match them to the correct ink. - Fixed system font fallback for characters not covered by the assigned typeface on Node and Node-Native. The hosted fallback fonts are now resolved from the IMG.LY CDN when a local
baseURL/basePathis configured (as on Node), instead of from a local path where they are not available — so unsupported characters render the same as in the browser. A remotebaseURL(e.g. a self-hosted CDN mirror) is still used as-is. - Fixed lines disappearing when combined with another element through a boolean operation. A line now contributes its visible (stroked) footprint to the combined shape, and a result that takes its color from a line now uses the line’s color.
- Fixed a video fill whose source failed to load (for example because of a CORS or network error) being re-fetched on every render frame with no limit. A failed video load now keeps its error state like image fills do; use
forceLoadResources/forceLoadAVResourceto explicitly retry it.
Engine/Web
- Fixed jittery video playback on Firefox. H.264 videos containing B-frames are now decoded in presentation order instead of decode order, eliminating the jumping and twitching artifacts that appeared while a video was playing.
Engine/Node
- Fixed
targetWidth/targetHeightbeing silently ignored byexportVideoin@cesdk/node-native. Passing both dimensions now resizes the exported video as documented, matching the WASM binding — no explicituseTargetSizeflag required.
Engine/Android
- Fixed a potential crash when overlapping engine directory cleanup operations delete stale temporary files.
Editor/Web
- Fixed uneven inspector bar spacing — corrected the doubled flex gap around zero-width spacers and removed the redundant horizontal margin that made the trim bar inset wider than other bars.
- Fixed the caption panel input losing focus immediately after clicking “Create Manually”, which interrupted typing the first caption.
- Fixed an issue causing the shadow inspector to be visible for page blocks.
Editor/iOS
- Fixed a regression where pressing Backspace on an empty list item deleted the whole paragraph in a single keystroke. The first Backspace now clears the bullet/number while keeping the paragraph, and a second Backspace merges it with the previous paragraph (matching Web and Android). Affects both the hardware and on-screen keyboard.
- Fixed the Crop sheet’s Reset button. It is now correctly disabled when the crop has no modifications, and tapping it clears all crop edits while keeping the block in crop mode.
- Fixed undo/redo after a page resize leaving the canvas zoom misaligned. The view now re-fits the page on every history step while the resize sheet is open.
- Dashed and dotted strokes no longer flicker while adjusting the stroke width.
Editor/Android
- Dashed and dotted strokes no longer flicker while adjusting the stroke width.
Editor/Flutter
- Fixed an issue where effects applied to paused videos were not immediately visible when using TextureView.