diff --git a/documentation/draw.md b/documentation/draw.md new file mode 100644 index 0000000..be7b5f9 --- /dev/null +++ b/documentation/draw.md @@ -0,0 +1,169 @@ +# Drawing with GraphX™ + +In **GraphX™** we have a couple of classes for rendering things. +These are `Shape` and `Sprite` . + +Those classes have an initial method wich is called when the object +is added to the stage, this method, is named by the way `addedToStage` . +there we handle the drawing of our object. + +For example, a simple rendering of a square can be: + +``` dart +@override +void addedToStage(){ + graphics.beginFill(0x0000ff, .6) + ..drawRoundRect(100, 100, 40, 40, 4) + ..endFill(); +} +``` + +Output: + +![basic_square](https://user-images.githubusercontent.com/44511181/99677710-c8d7b300-2a58-11eb-849e-8a3a5e79f144.jpg) + +Always when we want to draw a shape, we have to start with the +`beginFill()` method. + +To draw a circle: + +``` dart +@override +void addedToStage() { + graphics.beginFill(0x0000ff, .6) + ..drawCircle( + 200, + 200, + 120, + ).endFill(); +} +``` + +Output: + +![basic_circle](https://user-images.githubusercontent.com/44511181/99679843-2a991c80-2a5b-11eb-95cb-0c77318dc9cd.jpg) + +To draw a line, it changes a little bit, use `lineStyle` instead, where we configure the `thickness` and the `color` with a hex value. + +``` dart +graphics.lineStyle(4.0, Colors.green.value); +``` + +Then the `moveTo(x,y)` method allow us to move the *pencil* to a particular place for start drawing, from there, we can use the `lineTo(x,y)` . + +``` dart +@override +void addedToStage() { + graphics.lineStyle(4.0, Colors.green.value) + ..moveTo(100, 100) + ..lineTo(100, 200) + ..endFill(); +} +``` + +![basic_line](https://user-images.githubusercontent.com/44511181/99682895-7f8a6200-2a5e-11eb-97c9-718a552d26c1.jpg) + +The `closePath()` method, provide us a way to close the shape. + +This is a shape without the `closePath()` + +``` dart +@override +void addedToStage() { +graphics.lineStyle(4.0, Colors.green.value) + ..moveTo(100, 100) + ..lineTo(100, 200) + ..lineTo(200, 100) + ..lineTo(100, 100) + ..endFill(); + } + +``` + +Output: + +![closePath](https://user-images.githubusercontent.com/44511181/99716119-7b723a80-2a86-11eb-8460-ad5aec26107e.jpg) + +and with the `closePath()` + +``` dart +@override +void addedToStage() { + graphics.lineStyle(4.0, Colors.green.value) + ..moveTo(100, 100) + ..lineTo(100, 200) + ..lineTo(200, 100) + ..closePath() + ..endFill(); +} + +``` + +Output: + +![closePathFinal](https://user-images.githubusercontent.com/44511181/99716537-fdfafa00-2a86-11eb-9167-e6e410320922.jpg) + +### Handling multiple objects + +To add multiple objects in the same scene, just need to create a `shape` and add it into the stage. This new shape has also a `graphics` property where we can draw. + +``` dart +@override +void addedToStage() { + final shape1 = Shape(); + final shape2 = Shape(); + shape1.graphics + .beginFill( + Colors.deepOrange.value, + ) + .drawStar(100, 100, 5, 60) + .endFill(); + shape2.graphics + .beginFill( + Colors.deepOrange.value, + ) + .drawStar(200, 200, 5, 60) + .endFill(); + addChild(shape1); + addChild(shape2); +} +``` + +Output: + +![multipleObjects](https://user-images.githubusercontent.com/44511181/99721646-4c5fc700-2a8e-11eb-8445-1d8f1c1d68a8.jpg) + +After the shape is created, we can change some properties, like +the + +* scale +* alpha +* etc. + +``` dart +@override +void addedToStage() { + final shape1 = Shape(); + final shape2 = Shape(); + shape1.graphics + .beginFill( + Colors.deepOrange.value, + ) + .drawStar(100, 100, 5, 60); + shape2.graphics + .beginFill( + Colors.deepOrange.value, + ) + .drawStar(200, 200, 5, 60); + shape1.scale = 1.2; + shape1.alpha = .9; + shape2.x = 150; + shape2.scaleY = 1.3; + addChild(shape1); + addChild(shape2); +} +``` + +Output: + +![properties_changed](https://user-images.githubusercontent.com/44511181/99722706-cfcde800-2a8f-11eb-9999-2a0301f36e2b.jpg) diff --git a/documentation/events.md b/documentation/events.md new file mode 100644 index 0000000..235bf8a --- /dev/null +++ b/documentation/events.md @@ -0,0 +1,20 @@ +# Events with **GraphX™** + +We have multiples callBacks to handle and add interactivity to our shapes like: + + * onMouseClick + * onMouseDoubleClick + * onMouseDown + * onMouseUp + * etc. + +Before start, we + +In each event we can use the `add()` method or `addOnce` +wich also provide you the event itSelf where you can add more interactivity. + + + + + + diff --git a/lib/src/core/scene_controller.dart b/lib/src/core/scene_controller.dart index cc750a3..bdb4db7 100644 --- a/lib/src/core/scene_controller.dart +++ b/lib/src/core/scene_controller.dart @@ -109,6 +109,7 @@ class SceneController { InputConverter $inputConverter; SceneConfig get config => _config; + final _config = SceneConfig(); int id = -1; bool _isInited = false; @@ -157,6 +158,15 @@ class SceneController { _ticker = null; } + set config(SceneConfig sceneConfig) { + _config.setTo( + sceneIsComplex: sceneConfig.painterIsComplex, + useKeyboard: sceneConfig.useKeyboard, + usePointer: sceneConfig.usePointer, + useTicker: sceneConfig.useTicker, + ); + } + CustomPainter buildBackPainter() => back?.buildPainter(); CustomPainter buildFrontPainter() => front?.buildPainter(); @@ -175,14 +185,25 @@ class SceneController { SceneController._(); - static SceneController withLayers({SceneRoot back, SceneRoot front}) { + static SceneController withLayers({ + Sprite back, + Sprite front, + SceneConfig backConfig, + SceneConfig frontConfig, + }) { assert(back != null || front != null); final controller = SceneController._(); if (back != null) { controller.back = ScenePainter(controller, back); + if (backConfig != null) { + controller.back.core.config = backConfig; + } } if (front != null) { controller.front = ScenePainter(controller, front); + if (frontConfig != null) { + controller.back.core.config = frontConfig; + } } return controller; } diff --git a/lib/src/core/scene_painter.dart b/lib/src/core/scene_painter.dart index fc46b5d..31ddc96 100644 --- a/lib/src/core/scene_painter.dart +++ b/lib/src/core/scene_painter.dart @@ -4,68 +4,68 @@ import 'package:flutter/widgets.dart'; import '../../graphx.dart'; -class SceneRoot extends Sprite { - ScenePainter scene; - - static SceneRoot get current { - return ScenePainter.current.root; - } - - bool _ready = false; - - bool get isReady => _ready; - - bool _autoUpdateAndRender; - bool _useTicker; - bool _useKeyboard; - bool _usePointer; - bool _sceneIsComplex; - - /// You can config the scene in [init()] or in your class constructor. - void config({ - bool autoUpdateAndRender = false, - bool useTicker, - bool useKeyboard, - bool usePointer, - bool sceneIsComplex, - }) { - _autoUpdateAndRender = autoUpdateAndRender; - _useTicker = useTicker; - _useKeyboard = useKeyboard; - _usePointer = usePointer; - _sceneIsComplex = sceneIsComplex; - _applyConfig(); - } - - void _applyConfig() { - if (scene == null) return; - if (_ready) { - throw 'You can not initScene() after ready() has happened. ' - 'Is only allowed during (or before) init().'; - } -// scene.shouldRepaint = needsRepaint; - scene.autoUpdateAndRender = _autoUpdateAndRender ?? false; - if (scene.autoUpdateAndRender) { - _useTicker = true; - } - scene.core.config.setTo( - useTicker: _useTicker, - useKeyboard: _useKeyboard, - usePointer: _usePointer, - sceneIsComplex: _sceneIsComplex, - ); - } - - /// Use to initialize engine properties. - @protected - void init() { - _applyConfig(); - } - - /// Called when stage is ready. - @protected - void ready() {} -} +// class SceneRoot extends Sprite { +// ScenePainter scene; + +// static SceneRoot get current { +// return ScenePainter.current.root; +// } + +// bool _ready = false; + +// bool get isReady => _ready; + +// bool _autoUpdateAndRender; +// bool _useTicker; +// bool _useKeyboard; +// bool _usePointer; +// bool _sceneIsComplex; + +// /// You can config the scene in [init()] or in your class constructor. +// void config({ +// bool autoUpdateAndRender = false, +// bool useTicker, +// bool useKeyboard, +// bool usePointer, +// bool sceneIsComplex, +// }) { +// _autoUpdateAndRender = autoUpdateAndRender; +// _useTicker = useTicker; +// _useKeyboard = useKeyboard; +// _usePointer = usePointer; +// _sceneIsComplex = sceneIsComplex; +// _applyConfig(); +// } + +// void _applyConfig() { +// if (scene == null) return; +// if (_ready) { +// throw 'You can not initScene() after ready() has happened. ' +// 'Is only allowed during (or before) init().'; +// } +// // scene.shouldRepaint = needsRepaint; +// scene.autoUpdateAndRender = _autoUpdateAndRender ?? false; +// if (scene.autoUpdateAndRender) { +// _useTicker = true; +// } +// scene.core.config.setTo( +// useTicker: _useTicker, +// useKeyboard: _useKeyboard, +// usePointer: _usePointer, +// sceneIsComplex: _sceneIsComplex, +// ); +// } + +// /// Use to initialize engine properties. +// @protected +// void init() { +// _applyConfig(); +// } + +// /// Called when stage is ready. +// @protected +// void ready() {} +// } class ScenePainter with EventDispatcherMixin { /// Current painter being processed. @@ -76,7 +76,7 @@ class ScenePainter with EventDispatcherMixin { /// Access to the `root` DisplayObject that will initialize /// the Scene layer. - SceneRoot root; + Sprite root; /// Allows to re-paint the internal CustomPainter on every tick() /// The flags allow the $render() `tick` process to know if it has to @@ -129,7 +129,7 @@ class ScenePainter with EventDispatcherMixin { ScenePainter(this.core, this.root) { _stage = Stage(this); - root.scene = this; + // root.scene = this; makeCurrent(); } diff --git a/lib/src/display/display_object.dart b/lib/src/display/display_object.dart index 1e78673..ecc99fb 100644 --- a/lib/src/display/display_object.dart +++ b/lib/src/display/display_object.dart @@ -12,6 +12,7 @@ import 'stage.dart'; abstract class DisplayObject with DisplayListSignalsMixin, RenderSignalMixin, MouseSignalsMixin { + DisplayObjectContainer $parent; static DisplayObject $currentDrag; diff --git a/lib/src/display/sprite.dart b/lib/src/display/sprite.dart index 7613b1d..ab6841e 100644 --- a/lib/src/display/sprite.dart +++ b/lib/src/display/sprite.dart @@ -8,6 +8,7 @@ class Sprite extends DisplayObjectContainer { return '$runtimeType (Sprite)$msg'; } + static final _sHelperMatrix = GxMatrix(); Graphics _graphics; @@ -44,7 +45,6 @@ class Sprite extends DisplayObjectContainer { @override void $applyPaint(Canvas canvas) { -// print("Apply paint!"); if (!$hasVisibleArea) return; _graphics?.alpha = worldAlpha; _graphics?.paint(canvas); diff --git a/lib/src/events/callback_params.dart b/lib/src/events/callback_params.dart index 8198588..4cbdd8a 100644 --- a/lib/src/events/callback_params.dart +++ b/lib/src/events/callback_params.dart @@ -1,4 +1,4 @@ -class CallbackParams { +class CallBackParams { List positional; /// Symbol is represented by the literal # in Dart. @@ -6,16 +6,19 @@ class CallbackParams { /// You'd use {#name: 'roi', #count: 10}. Map named; - CallbackParams([this.positional, this.named]); + CallBackParams([this.positional, this.named]); - static CallbackParams parse(Object args) { + static CallBackParams parse(Object args) { if (args == null) return null; - if (args is CallbackParams) return args; + + if (args is CallBackParams) return args; + if (args is List) { - return CallbackParams(args); + return CallBackParams(args); } else if (args is Map) { - return CallbackParams(null, args); + return CallBackParams(null, args); } - return CallbackParams([args]); + + return CallBackParams([args]); } } diff --git a/lib/src/events/mps.dart b/lib/src/events/mps.dart index 8a61161..6728ee9 100644 --- a/lib/src/events/mps.dart +++ b/lib/src/events/mps.dart @@ -13,7 +13,7 @@ class MPS { final _cache = >{}; final _cacheOnce = >{}; - void publishParams(String topic, CallbackParams args) { + void publishParams(String topic, CallBackParams args) { // final subs = _cache[topic]; // subs?.forEach((fn) => Function.apply(fn, args?.positional, args?.named)); @@ -158,7 +158,7 @@ class MPS { _cacheOnce.remove(topic); } - void emitParams(String topic, CallbackParams args) { + void emitParams(String topic, CallBackParams args) { void _send(Function fn) => Function.apply(fn, args?.positional, args?.named); _cache[topic]?.forEach(_send); diff --git a/lib/src/events/signal.dart b/lib/src/events/signal.dart index da47112..44c726f 100644 --- a/lib/src/events/signal.dart +++ b/lib/src/events/signal.dart @@ -1,3 +1,7 @@ +/// --- EVENT SIGNAL + +typedef EventSignalCallback = void Function(T event); + class Signal { final _listenersOnce = []; final _listeners = []; @@ -60,10 +64,6 @@ class Signal { } } -/// --- EVENT SIGNAL - -typedef EventSignalCallback = void Function(T); - class EventSignal { void call(EventSignalCallback callback) { add(callback); diff --git a/lib/src/extensions/display_object.dart b/lib/src/extensions/display_object.dart new file mode 100644 index 0000000..430cde6 --- /dev/null +++ b/lib/src/extensions/display_object.dart @@ -0,0 +1,43 @@ +import '../../graphx.dart'; + +extension DisplayObjectHelpers on DisplayObject { + void centerInStage() { + if (!inStage) return; + setPosition(stage.stageWidth / 2, stage.stageHeight / 2); + } + + void setProps({ + Object x, + Object y, + Object scaleX, + Object scaleY, + Object scale, + Object rotation, + Object pivotX, + Object pivotY, + Object width, + Object height, + Object skewX, + Object skewY, + Object alpha, + double delay = 0, + }) { + tween( + duration: 0, + delay: delay, + x: x, + y: y, + scaleX: scaleX, + scaleY: scaleY, + scale: scale, + rotation: rotation, + pivotX: pivotX, + pivotY: pivotY, + width: width, + height: height, + skewX: skewX, + skewY: skewY, + alpha: alpha, + ); + } +} diff --git a/lib/src/tween/src/extensions/display_object.dart b/lib/src/tween/src/extensions/display_object.dart index 8a6ad20..5e07ca2 100644 --- a/lib/src/tween/src/extensions/display_object.dart +++ b/lib/src/tween/src/extensions/display_object.dart @@ -31,7 +31,6 @@ extension GTweenDiplayObjectExt on DisplayObject { Object onCompleteParams, Function onUpdate, Object onUpdateParams, -// Map vars, bool runBackwards, bool immediateRender, Map startAt, @@ -56,24 +55,24 @@ extension GTweenDiplayObjectExt on DisplayObject { }; return GTween.to( - this, - duration, - targetValues, - GVars( - ease: ease, - delay: delay, - useFrames: useFrames, - overwrite: overwrite, - onStart: onStart, - onStartParams: onStartParams, - onComplete: onComplete, - onCompleteParams: onCompleteParams, - onUpdate: onUpdate, - onUpdateParams: onUpdateParams, -// vars: vars, - runBackwards: runBackwards, - immediateRender: immediateRender, - startAt: startAt, - )); + this, + duration, + targetValues, + GVars( + ease: ease, + delay: delay, + useFrames: useFrames, + overwrite: overwrite, + onStart: onStart, + onStartParams: onStartParams, + onComplete: onComplete, + onCompleteParams: onCompleteParams, + onUpdate: onUpdate, + onUpdateParams: onUpdateParams, + runBackwards: runBackwards, + immediateRender: immediateRender, + startAt: startAt, + ), + ); } } diff --git a/lib/src/tween/src/gtween.dart b/lib/src/tween/src/gtween.dart index a306894..3c5c70e 100644 --- a/lib/src/tween/src/gtween.dart +++ b/lib/src/tween/src/gtween.dart @@ -6,11 +6,11 @@ class GVars { bool useFrames; int overwrite; Function onStart; - CallbackParams onStartParams; + CallBackParams onStartParams; Function onComplete; - CallbackParams onCompleteParams; + CallBackParams onCompleteParams; Function onUpdate; - CallbackParams onUpdateParams; + CallBackParams onUpdateParams; bool runBackwards; bool immediateRender; @@ -19,26 +19,26 @@ class GVars { /// TODO: maybe in future use vars from this object. // Map vars; - GVars( - {this.ease, - this.delay, - this.useFrames, - this.overwrite, - this.onStart, - this.onComplete, - this.onUpdate, - onStartParams, - onCompleteParams, - onUpdateParams, -// this.vars, - this.runBackwards, - this.immediateRender, - this.startAt}) { + GVars({ + this.ease, + this.delay, + this.useFrames, + this.overwrite, + this.onStart, + this.onComplete, + this.onUpdate, + Object onStartParams, + Object onCompleteParams, + Object onUpdateParams, + this.runBackwards, + this.immediateRender, + this.startAt, + }) { /// For easy of use, you can send any Object to be parsed as function /// arguments... - this.onStartParams = CallbackParams.parse(onStartParams); - this.onCompleteParams = CallbackParams.parse(onCompleteParams); - this.onUpdateParams = CallbackParams.parse(onUpdateParams); + this.onStartParams = CallBackParams.parse(onStartParams); + this.onCompleteParams = CallBackParams.parse(onCompleteParams); + this.onUpdateParams = CallBackParams.parse(onUpdateParams); } void defaults() { @@ -64,7 +64,7 @@ class GVars { } static const String selfTweenKey = '{self}'; - void _setCallbackParams(GTween twn, CallbackParams params) { + void _setCallbackParams(GTween twn, CallBackParams params) { final named = params.named; final positional = params.positional; if (named != null) { @@ -347,7 +347,7 @@ class GTween { } } - void _signal(Function callback, CallbackParams params) { + void _signal(Function callback, CallBackParams params) { if (callback != null) { /// It's a very slow approach. Function.apply(callback, params?.positional, params?.named); @@ -453,7 +453,7 @@ class GTween { ..delay = delay ..useFrames = useFrames ..onComplete = callback - ..onCompleteParams = CallbackParams.parse(params); + ..onCompleteParams = CallBackParams.parse(params); return GTween( callback, 0, diff --git a/pubspec.lock b/pubspec.lock index c87af4f..3712ec2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,42 +7,42 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.5.0-nullsafety.3" + version: "2.4.2" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.0.0" characters: dependency: transitive description: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.5" + version: "1.0.0" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.1.3" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.0.1" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.15.0-nullsafety.5" + version: "1.14.13" convert: dependency: transitive description: @@ -63,7 +63,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.1.0" flutter: dependency: "direct main" description: flutter @@ -80,28 +80,28 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.10-nullsafety.3" + version: "0.12.8" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.6" + version: "1.1.8" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.3" + version: "1.7.0" pedantic: dependency: "direct dev" description: name: pedantic url: "https://pub.dartlang.org" source: hosted - version: "1.9.2" + version: "1.9.0" petitparser: dependency: transitive description: @@ -120,56 +120,56 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.4" + version: "1.7.0" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.6" + version: "1.9.5" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.0.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.0.5" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.1.0" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.19-nullsafety.6" + version: "0.2.17" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.5" + version: "1.2.0" vector_math: dependency: "direct main" description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.5" + version: "2.0.8" xml: dependency: "direct main" description: @@ -178,4 +178,4 @@ packages: source: hosted version: "4.5.1" sdks: - dart: ">=2.12.0-0.0 <3.0.0" + dart: ">=2.9.1 <3.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index b0a0fed..b696bcd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: dev_dependencies: - pedantic: ^1.9.2 + pedantic: ^1.9.0 flutter_test: sdk: flutter effective_dart: ^1.0.0 \ No newline at end of file