SchemaX
SchemaX is a Flutter + GraphX rendering engine that turns structured schema data into highly interactive canvases. Provide a JSON schema describing the background and elements of your scene and SchemaX delivers a widget with panning, zooming, animation hooks, and a plugin system.
Build touch-friendly, schema-driven canvases for Flutter. SchemaX handles viewport math so you can focus on the story your scene tells.
Highlights
- Schema-first workflow — Encode backgrounds, element bounds, and custom metadata with
Schema/SchemaElement. SchemaX restores the layout on any screen and enforces clamped bounds. - Smooth gestures — Dragging, pinch-to-zoom, focus points, and
tweenTo/tweenBackanimations are built in, making it easy to guide the user to a specific element. - Extensible plugins — Implement
InteractivePluginto react to gestures and render overlays such as coordinate axes or visibility trackers (ViewportVisibilityPlugin). - Event hooks — Use
renderer.onClick/renderer.onZoomto coordinate Flutter UI with GraphX nodes. - Utility toolbox — Helpers for image caching, zoom compensation, looping animations, and more reduce glue code.
Installation
dependencies:
schemax: ^1.1.0 # use the published version when available
# or when developing locally:
# schemax:
# path: ../schemax
flutter pub get
Quick Start
-
Register a custom element
class BuildingElement extends SchemaElement { BuildingElement(super.config); static void register() { SchemaElement.registerType('building', BuildingElement.new); } @override Future<GDisplayObject> build(RendererCore renderer) async { final rect = renderer.rectTransformWithConfig(this); final sprite = GSprite()..setPosition(rect.x, rect.y); // Draw anything you need inside the sprite. sprite.onTap.add((_) => renderer.triggerTap(this)); return sprite; } } -
Load the schema
final schemaJson = jsonDecode(await rootBundle.loadString('assets/schema.json')); final schema = Schema.fromMap(schemaJson); -
Render with
RendererWidgetclass SocialMap extends HookWidget { const SocialMap({super.key}); @override Widget build(BuildContext context) { socialMapInit(); // registers SchemaElement types final schema = Schema.fromMap(kMySchema); return RendererWidget( schema: schema, interactivePlugins: [ CoordinateAxisPlugin(valueMode: AxisValueMode.transformed), ViewportVisibilityPlugin( onVisible: (element) => debugPrint('visible ${element?.id}'), ), ], onControllerReady: (controller) { controller.renderer.onClick((payload) { if (payload is BuildingSprite) payload.showInfo(); }); }, ); } }
Schema Structure
| Field | Type | Description |
|---|---|---|
background |
String |
URL or asset path for the background image. Images are loaded via loadImage and cached automatically. |
align |
center / left-top |
Default alignment of the background on the stage. left-top works with focusPointX/Y to define the initial viewport. |
scaleable / draggable |
bool |
Enable or disable pinch-zoom/drag gestures. |
options.minScale / maxScale |
double |
Zoom limits applied by RendererCore.clampedScale. |
options.focusPointX/Y |
double |
Initial focus point in schema coordinates. |
elements |
List<Map> |
Raw element configuration. Each entry must include id, type, x, y, width, and height. Custom keys are parsed by your SchemaElement subclass. |
Register new element types via SchemaElement.registerType, then override build to return any GDisplayObject. See example/lib/social_map for an end-to-end implementation.
Plugin System
InteractivePlugin exposes onAttach, onMove, and onScale. The RendererPluginManager dispatches every gesture to each plugin in order, letting you render overlays or react to viewport changes without touching gesture logic.
Built-in plugins include:
CoordinateAxisPlugin— draws top/left axes with ticks and labels using either schema coordinates or transformed stage values.ViewportVisibilityPlugin— reports which element meets a visibility threshold within the current viewport.
Plugins have full access to RendererCore helpers (stageToViewportX/Y, stageToSchemaX/Y, rectTransform*, etc.) so you can position overlays precisely.
Controller & Core APIs
RendererWidget— wrapsSceneBuilderWidgetwith aGestureDetector, instantiating aRendererControllerunless you provide one.RendererController— holds theRendererCore, translates Flutter gestures to renderer interactions, and forwards events to plugins.RendererCoreessentials:onClick/onZoomto listen for tap propagation and zoom changes (ZoomEventData).tweenTo(Base, ViewportAnimationConfig)/tweenBack()for focus animations.resetTransform()/resetContentInitialPosition()to return to the starting view.rectTransform*,stageToSchema*,stageToViewport*for converting between coordinate spaces.
Utilities & Animation Helpers
helper/zoom.keepElementSizekeeps an overlay visually stable while the canvas zooms;calcKeepSizeZoomreturns the compensation factor.utils/animate.breathingAnimationplusutils/utils.LoopManagerproduce looping tween sequences (used by the sample “breathing” indicator).utils/image.loadImagewraps network/local image loading with caching;utils/file.loadImageFromPathleveragesDefaultCacheManager.
Example App
The example/ directory ships with a “social map” demo. It showcases schema parsing, a custom building element, animated info cards, and plugin overlays.
cd example
flutter run
Development & Testing
flutter analyze— static analysis.flutter test— run unit/widget tests (add your own as needed).
License
SchemaX is distributed under the MIT License (see LICENSE).