diff --git a/README.md b/README.md index ea6ef0f..0baaa8c 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,39 @@ -# GraphX™ +
+ +

🎨

+

GraphX™

+
-GraphX™ rendering lib, - prototype code with a prototype lib +[![pub package](https://img.shields.io/pub/v/graphx.svg?label=graphx&color=blue)](https://pub.dev/packages/graphx) +[![style: effective dart](https://img.shields.io/badge/style-effective_dart-40c4ff.svg)](https://pub.dev/packages/effective_dart) +[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) -> *WARNING:* this is WIP code, based on a few days of experimentation. -> *NOTE:* GraphX™ uses the `$` prefix convention to all "internal/private" members (properties and methods). __DO NOT__ call them in your code... is meant to be consumed internally by the lib. -> until I cleanup and organize the code for an alpha version, then will probably moved all as part of the package. +| rendering | prototype | design | + + + +Making drawings and animations in Flutter extremely simple. + +___ + *WARNING:* this lib is on alfa stage, the api can change. + + *NOTE:* GraphX™ uses the `$` prefix convention to all "internal/private" members (properties and methods). __DO NOT__ call them in your code... is meant to be consumed internally by the lib. + until I cleanup and organize the code for an alpha version, then will probably moved all as part of the package. ___ ### wiki-tips. To get some extended, boring explanations, and eventually some sample codes, check the [GraphX™ Wiki](https://github.com/roipeker/graphx/wiki/GraphX-tips-and-random%5BnextInt()%5D-stuffs.#graphx-general-tips) +___ +
+ + + + +## Background. -## background. GraphX™ is here to help you build custom drawing in your Flutter apps. Providing an amazing versatility to power those screen pixels to a different level. @@ -29,7 +48,7 @@ It can be used to simple draw a line, a circle, a custom button, some splash eff So, let your imagination fly. -## concept. +## Concept. This repo is just a very early WIP to put something online... still lacks support for loading remote images, 2.5D and some other nicities. @@ -43,13 +62,15 @@ AssetLoader.loadJson(assetId) And some basic "raw" support for Text rendering with the `StaticText` class. + + ----------- GraphX™ drives a CustomPainter inside, the idea is to simplify the usage of Flutter's `Canvas`, plus adding the DisplayList concept, so you can manage and create more complex "scenes". GraphX™ has it's own rendering cycle (no AnimationController), and input capture, even if it runs on the Widget tree, you can enable the flags to capture mouse/touch input (through the `stage.pointer`), or keystrokes events (if u wanna do some simple game). -### sample code. +### Sample code. ```dart body: Center( @@ -166,7 +187,7 @@ They all emit a `MouseInputData` with all the needed info inside, like stage coo *I will keep adding further explanation in the upcoming days.* -### demos. +### Demos. _Some demos are only using **GraphX™** partially, and might have big CPU impact_ @@ -203,10 +224,11 @@ _Some demos are only using **GraphX™** partially, and might have big CPU impac Feel free to play around with the current API, even if it's still rough on edges and unoptimized, it might help you do things quicker. SKIA is pretty powerful! - +
------------- #### Donation + You can [buymeacoffee](https://www.buymeacoffee.com/roipeker) or support **GraphX™** via [Paypal](https://www.paypal.me/roipeker/) [![Donate via PayPal](https://cdn.rawgit.com/twolfson/paypal-github-button/1.0.0/dist/button.svg)](https://www.paypal.me/roipeker/) diff --git a/analysis_options.yaml b/analysis_options.yaml index 108d105..338c690 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1 +1,77 @@ -include: package:pedantic/analysis_options.yaml + +linter: + rules: + await_only_futures: true + # This one is desirable, but that's a lot of work for now + public_member_api_docs: false + # Desirable, but would be breaking changes: + avoid_positional_boolean_parameters: false + constant_identifier_names: false + include_file_not_found: false + + # INCLUDE_FIX (copy of effective dart 1.2.0) + # STYLE + camel_case_types: true + camel_case_extensions: true + library_names: true + file_names: true + library_prefixes: true + non_constant_identifier_names: true + directives_ordering: true + lines_longer_than_80_chars: true # avoid + curly_braces_in_flow_control_structures: true + + # DOCUMENTATION + slash_for_doc_comments: true + package_api_docs: true # prefer + #- comment_references # Unused because https://github.com/dart-lang/sdk/issues/36974 + + # USAGE + implementation_imports: true + avoid_relative_lib_imports: true # prefer + prefer_relative_imports: true # prefer + prefer_adjacent_string_concatenation: true + prefer_interpolation_to_compose_strings: true # prefer + unnecessary_brace_in_string_interps: true # avoid + prefer_collection_literals: true + avoid_function_literals_in_foreach_calls: true # avoid + prefer_iterable_whereType: true + prefer_function_declarations_over_variables: true + unnecessary_lambdas: true + prefer_equal_for_default_values: true + avoid_init_to_null: true + unnecessary_getters_setters: true + annotate_overrides: true + #- unnecessary_getters # prefer # Disabled pending fix: https://github.com/dart-lang/linter/issues/23 + #- prefer_expression_function_bodies # consider + unnecessary_this: true + prefer_initializing_formals: true + type_init_formals: true + empty_constructor_bodies: true + unnecessary_new: true + unnecessary_const: true + avoid_catches_without_on_clauses: true # avoid + avoid_catching_errors: true + use_rethrow_when_possible: true + + # DESIGN + use_to_and_as_if_applicable: true # prefer + one_member_abstracts: true # avoid + avoid_classes_with_only_static_members: true # avoid + prefer_mixin: true + prefer_final_fields: true # prefer + use_setters_to_change_properties: true + avoid_setters_without_getters: true + avoid_returning_null: true # avoid + avoid_returning_this: true # avoid + type_annotate_public_apis: true # prefer + #- prefer_typing_uninitialized_variables # consider + omit_local_variable_types: true # avoid + avoid_types_on_closure_parameters: true # avoid + avoid_return_types_on_setters: true # avoid + prefer_generic_function_type_aliases: true + avoid_private_typedef_functions: true # prefer + #- use_function_type_syntax_for_parameters # consider + hash_and_equals: true + avoid_equals_and_hash_code_on_mutable_classes: true # avoid + avoid_null_checks_in_equality_operators: true diff --git a/example/lib/demos/demos.dart b/example/lib/demos/demos.dart index 7533fe0..a3ffeb1 100644 --- a/example/lib/demos/demos.dart +++ b/example/lib/demos/demos.dart @@ -1,4 +1,4 @@ +export 'simple_interactions/simple_interactions.dart'; export 'simple_shape/simple_shapes.dart'; export 'simple_tween/simple_tween.dart'; export 'svg_icons/svg_icons.dart'; -export 'simple_interactions/simple_interactions.dart'; diff --git a/example/lib/demos/simple_interactions/simple_interactions.dart b/example/lib/demos/simple_interactions/simple_interactions.dart index c33500e..8c272c5 100644 --- a/example/lib/demos/simple_interactions/simple_interactions.dart +++ b/example/lib/demos/simple_interactions/simple_interactions.dart @@ -1,4 +1,4 @@ -import 'package:exampleGraphx/utils/utils.dart'; +import '../../utils/utils.dart'; import 'simple_interactions_scene.dart'; diff --git a/example/lib/demos/simple_interactions/simple_interactions_scene.dart b/example/lib/demos/simple_interactions/simple_interactions_scene.dart index 125dd15..4bcf3e9 100644 --- a/example/lib/demos/simple_interactions/simple_interactions_scene.dart +++ b/example/lib/demos/simple_interactions/simple_interactions_scene.dart @@ -55,14 +55,14 @@ class SimpleInteractionsScene extends SceneRoot { /// And also access the `rawEvent` dispatched by Flutter if we need to. /// Most of the times you are ok using `LogicalKeyboardKey` to check /// for the keyboard's keys constants. - /// Usually [onDown] fires keystrokes in constantly, although it depends on the - /// OS and keyboard, while you keep it pressed. + /// Usually [onDown] fires keystrokes in constantly, although it depends + /// on the OS and keyboard, while you keep it pressed. void _onKeyboardDown(KeyboardEventData event) { var pixelsToMove = 10.0; /// for access modifiers keys, is better to check the raw event itself. - /// as multiple physical keys have the same behaviour (shift, command, alt, etc) - /// but different key codes. + /// as multiple physical keys have the same behaviour (shift, command, + /// alt, etc) but different key codes. if (event.rawEvent.isShiftPressed) { pixelsToMove = 30.0; } @@ -85,9 +85,9 @@ class SimpleInteractionsScene extends SceneRoot { } } - /// [onUp], unlike [onDown], dispatches only once, when you release a keystroke. - /// use the A for scale down the ball, and S to scale it up by 20% on each - /// event. + /// [onUp], unlike [onDown], dispatches only once, when you release a + /// keystroke. use the A for scale down the ball, and S to scale it up + /// by 20% on each event. void _onKeyboardUp(KeyboardEventData event) { if (event.isKey(LogicalKeyboardKey.keyS)) { ball.scale += .2; diff --git a/example/lib/demos/simple_interactions/ui/my_button.dart b/example/lib/demos/simple_interactions/ui/my_button.dart index 3bfde1e..26aa864 100644 --- a/example/lib/demos/simple_interactions/ui/my_button.dart +++ b/example/lib/demos/simple_interactions/ui/my_button.dart @@ -186,7 +186,7 @@ class MyButton extends Sprite { /// height textY = textY.clamp(0.0, h - textH); _fillText.y = textY; - _fillText.text = (_fillPercent * 100).toStringAsFixed(0) + '%'; + _fillText.text = '${(_fillPercent * 100).toStringAsFixed(0)}%'; _fillText.alpha = _fillPercent.clamp(.3, 1.0); } } diff --git a/example/lib/demos/simple_shape/simple_shapes.dart b/example/lib/demos/simple_shape/simple_shapes.dart index 870191f..ceea288 100644 --- a/example/lib/demos/simple_shape/simple_shapes.dart +++ b/example/lib/demos/simple_shape/simple_shapes.dart @@ -1,4 +1,4 @@ -import 'package:exampleGraphx/utils/utils.dart'; +import '../../utils/utils.dart'; import 'simple_shapes_scene.dart'; diff --git a/example/lib/demos/simple_tween/simple_tween.dart b/example/lib/demos/simple_tween/simple_tween.dart index 9860e96..e7b0178 100644 --- a/example/lib/demos/simple_tween/simple_tween.dart +++ b/example/lib/demos/simple_tween/simple_tween.dart @@ -1,6 +1,6 @@ -import 'package:exampleGraphx/demos/simple_tween/simple_tween_scene.dart'; -import 'package:exampleGraphx/demos/simple_tween/tween_controller.dart'; -import 'package:exampleGraphx/utils/utils.dart'; +import '../../utils/utils.dart'; +import 'simple_tween_scene.dart'; +import 'tween_controller.dart'; class SimpleTweenMain extends StatelessWidget { final controller = TweenSceneController(); diff --git a/example/lib/demos/svg_icons/svg_icons.dart b/example/lib/demos/svg_icons/svg_icons.dart index 8a6d710..bea87be 100644 --- a/example/lib/demos/svg_icons/svg_icons.dart +++ b/example/lib/demos/svg_icons/svg_icons.dart @@ -1,4 +1,4 @@ -import 'package:exampleGraphx/utils/utils.dart'; +import '../../utils/utils.dart'; import 'svg_icons_scene.dart'; class DemoSvgIconsMain extends StatelessWidget { diff --git a/example/lib/demos/svg_icons/test_svg_scene.dart b/example/lib/demos/svg_icons/test_svg_scene.dart index 5321442..8da45f2 100644 --- a/example/lib/demos/svg_icons/test_svg_scene.dart +++ b/example/lib/demos/svg_icons/test_svg_scene.dart @@ -1,8 +1,9 @@ -import 'package:exampleGraphx/assets/svg_icons.dart'; -import 'package:exampleGraphx/utils/svg_utils.dart'; import 'package:flutter/material.dart'; import 'package:graphx/graphx.dart'; +import '../../assets/svg_icons.dart'; +import '../../utils/svg_utils.dart'; + class TestSvgScene extends Sprite { final groundHeight = 100.0; Sprite trees, ground; diff --git a/example/lib/utils/svg_utils.dart b/example/lib/utils/svg_utils.dart index a809142..35d51f9 100644 --- a/example/lib/utils/svg_utils.dart +++ b/example/lib/utils/svg_utils.dart @@ -17,7 +17,7 @@ class SvgUtils { bool clipCanvas = true, Size scaleCanvasSize, }) async { - final DrawableRoot svgRoot = await svg.fromSvgString(rawSvg, rawSvg); + final svgRoot = await svg.fromSvgString(rawSvg, rawSvg); if (scaleCanvas) { svgRoot.scaleCanvasToViewBox(canvas, scaleCanvasSize); } @@ -28,7 +28,7 @@ class SvgUtils { } static Future svgDataFromString(String rawSvg) async { - final DrawableRoot svgRoot = await svg.fromSvgString(rawSvg, rawSvg); + final svgRoot = await svg.fromSvgString(rawSvg, rawSvg); var obj = SvgData(); obj.hasContent = svgRoot.hasDrawableContent; obj.picture = svgRoot.toPicture(); diff --git a/example/lib/utils/utils.dart b/example/lib/utils/utils.dart index d1f0bf7..82b2ebc 100644 --- a/example/lib/utils/utils.dart +++ b/example/lib/utils/utils.dart @@ -1,3 +1,4 @@ -export 'demo_scene_widget.dart'; export 'package:flutter/material.dart'; export 'package:graphx/graphx.dart' show SceneBuilderWidget, SceneRoot; + +export 'demo_scene_widget.dart'; diff --git a/lib/src/animations/delayed_call.dart b/lib/src/animations/delayed_call.dart index bd999a8..efb43c8 100644 --- a/lib/src/animations/delayed_call.dart +++ b/lib/src/animations/delayed_call.dart @@ -40,9 +40,9 @@ class GxDelayedCall with IUpdatable, JugglerSignalMixin { // save objects cause they might be changed from event. var $callback = target; - /// during callback, people might wanna call [reset] and read this to the - /// juggler, so the signal has to be dispatched *before* executing the - /// callback. + /// during callback, people might wanna call [reset] and read + /// this to the juggler, so the signal has to be dispatched *before* + /// executing the callback. onRemovedFromJuggler.dispatch(_eventData); $callback?.call(); } diff --git a/lib/src/render/render.dart b/lib/src/render/render.dart index 6730fee..a6585e9 100644 --- a/lib/src/render/render.dart +++ b/lib/src/render/render.dart @@ -1,3 +1,5 @@ +export 'filters/blur_filter.dart'; +export 'filters/color_filter.dart'; export 'filters/color_filter.dart'; export 'graphics.dart'; export 'gx_icon.dart'; @@ -5,5 +7,3 @@ export 'movie_clip.dart'; export 'particles/simple_particle.dart'; export 'particles/simple_particle_system.dart'; export 'svg_shape.dart'; -export 'filters/blur_filter.dart'; -export 'filters/color_filter.dart'; diff --git a/lib/src/tween/src/gtween.dart b/lib/src/tween/src/gtween.dart index 3129a4e..74d1c67 100644 --- a/lib/src/tween/src/gtween.dart +++ b/lib/src/tween/src/gtween.dart @@ -283,7 +283,7 @@ class GTween { return v - start; } else if (val is String) { if (val.length > 2 && val[1] == '=') { - var multiplier = double.tryParse(val[0] + '1') ?? 1; + var multiplier = double.tryParse('${val[0]}1') ?? 1; var factor = double.tryParse(val.substring(2)); return multiplier * factor; } else { diff --git a/lib/src/tween/src/mixins/tweenable.dart b/lib/src/tween/src/mixins/tweenable.dart index 3e9dce8..68f8430 100644 --- a/lib/src/tween/src/mixins/tweenable.dart +++ b/lib/src/tween/src/mixins/tweenable.dart @@ -40,7 +40,7 @@ mixin GTweenable { final Map _lerps = {}; @override - String toString() => '[GTweenable] ' + target?.toString(); + String toString() => '[GTweenable] $target'; Map> _accessors; diff --git a/lib/src/tween/src/wraps/common_wraps.dart b/lib/src/tween/src/wraps/common_wraps.dart index 11fb905..5551c16 100644 --- a/lib/src/tween/src/wraps/common_wraps.dart +++ b/lib/src/tween/src/wraps/common_wraps.dart @@ -101,7 +101,8 @@ class GTweenableMap with GTweenable { targetMap.removeWhere((k, v) => !value.containsKey(k)); if (targetMap.isEmpty) { - throw "tween(targetMap) Map can't be empty. Or there are no matching keys with the tweenable target."; + throw ''' +tween(targetMap) Map can't be empty. Or there are no matching keys with the tweenable target.'''; } return GTween.to( @@ -169,7 +170,8 @@ class GTweenableList with GTweenable { assert(targetList != null); targetList.removeWhere((element) => element is! num); if (targetList.isEmpty) { - throw "tween(targetList) List can't be empty. Or values inside of it where not a number type"; + throw ''' +tween(targetList) List can't be empty. Or values inside of it where not a number type'''; } final targetMap = {}; for (var i = 0; i < targetList.length; ++i) { diff --git a/lib/src/tween/src/wraps/geom_wraps.dart b/lib/src/tween/src/wraps/geom_wraps.dart index e1aa245..572b488 100644 --- a/lib/src/tween/src/wraps/geom_wraps.dart +++ b/lib/src/tween/src/wraps/geom_wraps.dart @@ -38,7 +38,8 @@ class GTweenablePoint with GTweenable { Map startAt, }) { if ((x != null || y != null) && to != null) { - throw "GTween Can't use 'x, y' AND 'to' arguments for GxPoint tween. Choose one"; + throw ''' +GTween Can't use 'x, y' AND 'to' arguments for GxPoint tween. Choose one'''; } x = to?.x ?? x; y = to?.y ?? y; diff --git a/lib/src/utils/mixins.dart b/lib/src/utils/mixins.dart index a66c858..9c7c8e7 100644 --- a/lib/src/utils/mixins.dart +++ b/lib/src/utils/mixins.dart @@ -40,7 +40,7 @@ mixin RenderUtilMixin { final picture = createPicture( !needsAdjust ? null - : (Canvas c) { + : (c) { if (adjustOffset) { c.translate(-rect.left, -rect.top); } diff --git a/lib/src/utils/pools.dart b/lib/src/utils/pools.dart index a2c6dbb..c21251b 100644 --- a/lib/src/utils/pools.dart +++ b/lib/src/utils/pools.dart @@ -1,6 +1,6 @@ import '../../graphx.dart'; -abstract class Pool { +mixin Pool { static final _points = []; static final _rectangles = []; static final _matrices = []; diff --git a/lib/src/utils/texture_utils.dart b/lib/src/utils/texture_utils.dart index 74f3a45..e4ecaeb 100644 --- a/lib/src/utils/texture_utils.dart +++ b/lib/src/utils/texture_utils.dart @@ -1,6 +1,6 @@ import '../../graphx.dart'; -abstract class TextureUtils { +mixin TextureUtils { static final Shape _helperShape = Shape(); static Graphics get _g => _helperShape.graphics; diff --git a/pubspec.lock b/pubspec.lock index 1d9ea4c..203a97e 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.5.0-nullsafety.1" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.1.0-nullsafety.1" characters: dependency: transitive description: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.5" + version: "1.1.0-nullsafety.3" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.2.0-nullsafety.1" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.1.0-nullsafety.1" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.15.0-nullsafety.5" + version: "1.15.0-nullsafety.3" 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.2.0-nullsafety.1" flutter: dependency: "direct main" description: flutter @@ -80,21 +80,21 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.10-nullsafety.3" + version: "0.12.10-nullsafety.1" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.6" + version: "1.3.0-nullsafety.3" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.3" + version: "1.8.0-nullsafety.1" pedantic: dependency: "direct dev" description: @@ -120,56 +120,56 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.4" + version: "1.8.0-nullsafety.2" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.6" + version: "1.10.0-nullsafety.1" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.1.0-nullsafety.1" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.1.0-nullsafety.1" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.2.0-nullsafety.1" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.19-nullsafety.6" + version: "0.2.19-nullsafety.2" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.5" + version: "1.3.0-nullsafety.3" vector_math: dependency: "direct main" description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.5" + version: "2.1.0-nullsafety.3" 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.10.0-110 <2.11.0"