GithubHelp home page GithubHelp logo

Add support for dashed line about graphx HOT 10 OPEN

roipeker avatar roipeker commented on July 17, 2024
Add support for dashed line

from graphx.

Comments (10)

roipeker avatar roipeker commented on July 17, 2024 2

Hey @tlvenn , here's the updated example code with shaders for Image and Gradient. Maybe not the prettiest solution as it is, but might be easy to get some "helper" class to simplify the usage. Anyway, is just another simplified option to the Path.

import 'package:graphx/graphx.dart';

import 'commons.dart';

class DashShaderScene extends GSprite {
  @override
  void addedToStage() {
    stage!.color = Colors.white;
    drawImageLine();
    drawGradientLine();
    super.addedToStage();
  }

  Future<void> drawGradientLine() async {
    var dash = addChild(GShape());
    dash.graphics.lineStyle(2);

    /// Gradient is "tricky" for rotations, there's no Matrix on the Flutter API side.
    /// unless we use Gradient.linear(), which lineGradientStyle() doesn't support.
    /// So the bounding box and the Alignment defines the gradient transformation.
    /// You have to workaround the math to figure the "dash" spacing and rotation.
    dash.graphics.lineGradientStyle(
      GradientType.linear,
      [Colors.blue, Colors.transparent],
      ratios: [0.5, 0.5],
      begin: const Alignment(0, 0),
      end: const Alignment(.2, 0),
      tileMode: TileMode.repeated,
    );
    dash.graphics.moveTo(0, 0).lineTo(100, 0).endFill();

    dash.graphics.lineStyle(2);
    dash.graphics.lineGradientStyle(
      GradientType.linear,
      [Colors.blue, Colors.transparent],
      ratios: [0.5, 0.5],
      begin: const Alignment(0, 0),
      end: const Alignment(0, .2),
      tileMode: TileMode.repeated,
    );
    dash.graphics.moveTo(0, 0).lineTo(0, 100).endFill();

    dash.setPosition(50, 130);
  }

  Future<void> drawImageLine() async {
    // create a temporal shape to draw as Image texture.
    var drawer = GShape()
      ..graphics
          .beginFill(Colors.redAccent)
          .drawRect(0, 0, 4, 2)
          .endFill()
          .beginFill(Colors.transparent)
          .drawRect(4, 0, 4, 2)
          .endFill();
    final dashTexture = await drawer.createImageTexture();

    var lines = addChild(GShape());
    lines.setPosition(30, 30);

    lines.graphics.lineStyle(2).lineBitmapStyle(dashTexture);
    lines.graphics.moveTo(0, 0).lineTo(100, 0);
    lines.graphics.endFill();
    // diagonal line
    var matrix = GMatrix();
    matrix.rotate(deg2rad(45));
    lines.graphics
        .lineStyle(4)
        .lineBitmapStyle(dashTexture, matrix)
        .moveTo(0, 0)
        .lineTo(50, 50)
        .endFill();

    // vertical line
    matrix.identity();
    matrix.rotate(deg2rad(90));

    lines.graphics
        .lineStyle(0)
        .lineBitmapStyle(dashTexture, matrix)
        .moveTo(0, 0)
        .lineTo(0, 80)
        .endFill();

    /// For other rotations, you should take the angle of the line.
    var from = GPoint(60, 30);
    var to = GPoint(180, 18);
    var angle = Math.atan2(to.y - from.y, to.x - from.x);

    matrix.identity();
    matrix.rotate(angle);
    lines.graphics
        .lineStyle(2)
        .lineBitmapStyle(dashTexture, matrix, true, true)
        .moveTo(from.x, from.y)
        .lineTo(to.x, to.y)
        .endFill();

    /// animation example
    var lines2 = addChild(GShape());
    lines2.setPosition(150, 10);
    matrix.identity();
    stage!.onEnterFrame.add((time) {
      matrix.tx += .8;
      lines2.graphics
          .clear()
          .lineStyle(4)
          .lineBitmapStyle(dashTexture, matrix, true, true)
          .lineTo(80, 0)
          .endFill();
    });
  }
}

Video (red lines = texture, blue lines = gradient)

dashed_line_shaders.mov

from graphx.

roipeker avatar roipeker commented on July 17, 2024 1

Btw, by shaders i meant the classic Gradient or Image Shaders from flutter. Not the experimental GLSL (that will be probably removed with Impeller).

Give me a few mins and i will prepare a sample.

from graphx.

roipeker avatar roipeker commented on July 17, 2024 1

Reopening the issue for future code references.

from graphx.

roipeker avatar roipeker commented on July 17, 2024

Hi @tlvenn, I forgot to reply earlier today, sorry.

You can totally use that library.
Graphics class has getPaths() and drawPath() as input/output for raw Paths.

source:
graphx dash line

Output:
dash_example

Good luck!

from graphx.

roipeker avatar roipeker commented on July 17, 2024

Feel free to reopen the issue if the solution doesn't fit your needs.

from graphx.

tlvenn avatar tlvenn commented on July 17, 2024

Hi @roipeker ,

Thanks a lot for the example, that is super useful !

The implementation for this within Graphics is simply a wrapper leveraging path_drawing lib. Could we do something similar so that we could draw dashed paths without importing an entire graph lib ? I might be able to contribute this given the example you provided.

Do you have a preference on how we should provide this within Graphx ?

from graphx.

roipeker avatar roipeker commented on July 17, 2024

Probably as a lineStyle parameter?, although flash had no support for it i believe (api wise).

Anyway, depending on the level of complexity that u need, for straight dashed lines is much more performant to use shaders i think (gradients or image) than compute path segmentation.

from graphx.

tlvenn avatar tlvenn commented on July 17, 2024

Ya computing path segmentations seems pretty painful and expensive.. And yes while looking at it, I also discovered that Flash had no native support for this and people came with some pretty crazy stuff to do path segmentations on their own.

Right now my use cases is all around very simple straight lines so probably the path segmentation is relatively simple but would be curious to see how you would approach it using shaders if you can spare a little time.

Thanks in advance.

from graphx.

tlvenn avatar tlvenn commented on July 17, 2024

Thanks a lot @roipeker !

Speaking of which, what is the impact of Impeller on Graphx roughly ?

from graphx.

roipeker avatar roipeker commented on July 17, 2024

No clue, never tried Impeller myself... but I mostly heard good things about it.

(This code uses the latest from master channel, generic Type for the addChild<T>) ;

Image shader example:

import 'package:graphx/graphx.dart';

import 'commons.dart';

class DashShaderScene extends GSprite {
  @override
  void addedToStage() {
    stage!.color = Colors.white;
    drawImageLine();
    super.addedToStage();
  }

  Future<void> drawImageLine() async {
    // create a temporal shape to draw as Image texture.
    var drawer = GShape()
      ..graphics
          .beginFill(Colors.redAccent)
          .drawRect(0, 0, 4, 2)
          .endFill()
          .beginFill(Colors.transparent)
          .drawRect(4, 0, 4, 2)
          .endFill();
    final dashTexture = await drawer.createImageTexture();

    var lines = addChild(GShape());
    lines.setPosition(100, 100);

    lines.graphics.lineStyle(2).lineBitmapStyle(dashTexture);
    lines.graphics.moveTo(0, 0).lineTo(100, 0);
    lines.graphics.endFill();
    // diagonal line
    var matrix = GMatrix();
    matrix.rotate(deg2rad(45));
    lines.graphics
        .lineStyle(4)
        .lineBitmapStyle(dashTexture, matrix)
        .moveTo(0, 0)
        .lineTo(100, 100)
        .endFill();

    // vertical line
    matrix.identity();
    matrix.rotate(deg2rad(90));

    lines.graphics
        .lineStyle(0)
        .lineBitmapStyle(dashTexture, matrix)
        .moveTo(0, 0)
        .lineTo(0, 80)
        .endFill();

    /// For other rotations, you should take the angle of the line.
    var from = GPoint(60, 30);
    var to = GPoint(180, 18);
    var angle = Math.atan2(to.y - from.y, to.x - from.x);

    matrix.identity();
    matrix.rotate(angle);
    lines.graphics
        .lineStyle(2)
        .lineBitmapStyle(dashTexture, matrix, true, true)
        .moveTo(from.x, from.y)
        .lineTo(to.x, to.y)
        .endFill();

    /// animation example
    var lines2 = addChild(GShape());
    lines2.setPosition(50, 20);
    matrix.identity();
    stage!.onEnterFrame.add((time) {
      matrix.tx += .8;
      lines2.graphics
          .clear()
          .lineStyle(4)
          .lineBitmapStyle(dashTexture, matrix, true, true)
          .lineTo(120, 0)
          .endFill();
    });
  }
}

Example video:

dashed_line_bitmap.mov

from graphx.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.