Coder Social home page Coder Social logo

vector_graphics's Introduction

Vector Graphics

This repo is a collection of Dart packages that can encode SVGs into a binary format that is efficient to decode and render at runtime.

vector_graphics's People

Contributors

asashour avatar bramp avatar c-h-i-a-m-a-k-a-2 avatar carloshpb avatar chunhtai avatar dnfield avatar fursanabdulhak avatar jason-simmons avatar jonahwilliams avatar marco4763 avatar sabifa avatar skreborn avatar tgucio avatar xvrh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

vector_graphics's Issues

Failure of clipping optimizer on fill-rule?

<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
    <g clip-path="url(#a)">
        <path fill-rule="evenodd" clip-rule="evenodd" d="M9.99 0C4.47 0 0 4.48 0 10s4.47 10 9.99 10C15.52 20 20 15.52 20 10S15.52 0 9.99 0zM11 11V5H9v6h2zm0 4v-2H9v2h2zm-9-5c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8-8 3.58-8 8z" fill="black" />
    </g>
    <defs>
        <clipPath id="a">
            <path fill="#fff" d="M0 0h20v20H0z" />
        </clipPath>
    </defs>
</svg>

Clipping optimizer currently just renders a black circle, which is incorrect.

I think we're probably dropping the fill-rule.

Consider applying color filters to the rasterized vector graphic instead of the resulting image

Context: https://github.com/dnfield/vector_graphics/pull/71/files/f6ebe3b00725a95710a345e9e0642fd2911e69ce#diff-6aefb41d5a9139706f33aa4ae6d68a7ed1c69f1ec5ae78f16dbb1f1cc2bee325

The idea is that since some filter types may be expensive, it could be beneficial to performance to instead rasterize them instead of using Paint on the drawImage call. The trade-off here is that we'd have to re-rasterize if the filter changed

an build error lass 'Picture'. - 'Picture' is from 'dart:ui'. Try correcting the name to the name of an existing method, or defining a method named 'toImageSync'. rasterPicture.toImageSync(scaledWidth, scaledHeight);

image

flutter doctot
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.3.4, on macOS 12.6 21G115 darwin-arm (Rosetta),
locale zh-Hans-AR)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 13.2.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.1)
Scanning for devices is taking a long time...[✓] Connected device (3 available)
[✓] HTTP Host Availability

Add support for drawPicture mode, allow limited configuration

This render object should support a drawPicture mode that behaves similarly to the previous flutter_svg implementaiton. This should avoid extra compositing by using canvas.saveLayer to apply opacity.

We can allow limited configuration of this mode, with this behavior being the default (outside of google3) and allowing an opt-in to the rasterization support.

Make the magic number public

Currently, the magic number is stored as a private constant in VectorGraphicsCodec.__magicNumber. At my company, we are building a program that will need to recognize whether some file is a raw text svg file or a compiled one using encodeSvg. A reliable way to do that seems to be to check the header of the binary. Unfortunately the magic number is private. Tests inside of this repo also use this fact and translate the magic number to a bytes list. This issue aims to request for that field to become public, or, understand the reasoning why it should stay private.

If it can be made public I am happy to send a PR for this change.

cc @dnfield

If a vector graphic fails to decode, it's very difficult to determine which one it is.

Exceptions look like this:

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following StateError was thrown running a test (but after the test had completed):
Bad state: Unknown type tag 2

When the exception was thrown, this was the stack:
#0      VectorGraphicsCodec.decode (package:vector_graphics_codec/vector_graphics_codec.dart:177:11)
#1      decodeVectorGraphics (package:vector_graphics/src/listener.dart:54:36)
#2      _VectorGraphicWidgetState._loadPicture.<anonymous closure> (package:vector_graphics/vector_graphics.dart:223:14)
<asynchronous suspension>
(elided 2 frames from dart:async)

It'd be nice to include the debugName somewhere.

Patterns not working for svg

Hey dnfield i am facing issue while rendering svg with pattern tag. In listerner.dart -> method name onPatternStart has _patterns map which is always empty. Getting below attached error.
image

Here is my svg content:
<svg width='512' height='512' viewBox='0 0 750 750' fill='none' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><defs><clipPath id='clip_text'><rect x='187' y='570' width='375' height='79' fill='white' /></clipPath><pattern id='pattern0' patternContentUnits='objectBoundingBox' width='1' height='1'><use xlink:href='#image0_27272_8541' transform='translate(0 -0.25) scale(0.003125)' /></pattern><clipPath id='clip0_27272_8541'><rect width='750' height='750' fill='white' /></clipPath><image id='image0_27272_8541' width='320' height='480' xlink:href='{profile_pic}' /></defs><image x='0' y='0' width='750' height='750' xlink:href='https://leadschool-static.s3.ap-south-1.amazonaws.com/parentapp/img/badge/hw_bg.png' /><g clip-path='url(#clip0_27272_8541)'><path opacity='0.08' d='M77.9167 704.167C77.9167 741.254 46.9582 771.667 8.33334 771.667C-30.2915 771.667 -61.25 741.254 -61.25 704.167C-61.25 667.08 -30.2915 636.667 8.33334 636.667C46.9582 636.667 77.9167 667.08 77.9167 704.167Z' stroke='white' stroke-width='15' /><path opacity='0.08' d='M775.833 206.25C775.833 226.105 759.305 242.5 738.542 242.5C717.779 242.5 701.25 226.105 701.25 206.25C701.25 186.395 717.779 170 738.542 170C759.305 170 775.833 186.395 775.833 206.25Z' stroke='white' stroke-width='15' /><circle cx='378' cy='215' r='129' fill='url(#pattern0)' /></g><g clip-path='url(#clip_text)'><text x='375' y='636.839' text-anchor='middle' fill='white' xml:space='preserve' style='white-space: pre' font-family='Poppins' font-size='24' font-weight='500' letter-spacing='0em'>threee</text><text x='375' y='600.839' text-anchor='middle' fill='white' xml:space='preserve' style='white-space: pre' font-family='Poppins' font-size='24' font-weight='bold' letter-spacing='0em'>DON</text></g><image x='0' y='0' width='750' height='750' xlink:href='https://leadschool-static.s3.ap-south-1.amazonaws.com/parentapp/img/badge/hw_strip.png' /></svg>

adjust vector_graphics errorBuilder (to trigger on BytesLoader errors)

COPIED FROM dnfield/flutter_svg#996

My use case: I am trying to fallback to a svg in assets if my SvgPicture.network() fails for any reason (wrong url, request returns 404, invalid svg format, ...)

widgets like the Flutter Image fully support this errorBuilder and any error in the process (image loading/parsing/rendering) triggers the errorBuilder callback

From my observations:

  • SvgPicture widget does not accept errorBuilder
  • The vector_graphics package does not trigger errorBuilder for BytesLoader objects loadBytes() calls, it only triggers it for errors in decodeVectorGraphics()

image from vector_graphics.dart
image

Exception while compiling svg

Steps to reproduce:

vector_graphics_compiler -i Rossmann_Logo.svg -o Rossmann_Logo.bin

The following exception will be thrown:

Logs
Unhandled exception:
RangeError (index): Invalid value: Valid value range is empty: 0
#0      _Array.[] (dart:core-patch/array.dart:10:36)
#1      _CircularIntervalList.next (package:vector_graphics_compiler/src/geometry/path.dart:668:17)
#2      _PathDasher.dash (package:vector_graphics_compiler/src/geometry/path.dart:753:25)
#3      Path.dashed (package:vector_graphics_compiler/src/geometry/path.dart:565:19)
#4      ResolvingVisitor.visitPathNode (package:vector_graphics_compiler/src/svg/resolver.dart:107:35)
#5      PathNode.accept (package:vector_graphics_compiler/src/svg/node.dart:357:20)
#6      ResolvingVisitor.visitParentNode (package:vector_graphics_compiler/src/svg/resolver.dart:64:19)
#7      ParentNode.accept (package:vector_graphics_compiler/src/svg/node.dart:205:20)
#8      ResolvingVisitor.visitViewportNode (package:vector_graphics_compiler/src/svg/resolver.dart:146:57)
#9      ViewportNode.accept (package:vector_graphics_compiler/src/svg/node.dart:105:20)
#10     SvgParser.parse (package:vector_graphics_compiler/src/svg/parser.dart:641:27)
<asynchronous suspension>
#11     encodeSvg (package:vector_graphics_compiler/vector_graphics_compiler.dart:92:43)
<asynchronous suspension>
#12     main ([...]/vector_graphics/packages/vector_graphics_compiler/bin/vector_graphics_compiler.dart:58:27)
<asynchronous suspension>
Flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel master, 3.1.0-0.0.pre.925, on macOS 12.2.1 21D62
    darwin-arm, locale en-DE)
[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 13.3.1)
[✓] Chrome - develop for the web
[✓] Android Studio
[✓] Android Studio (version 2021.2)
[✓] IntelliJ IDEA Community Edition (version 2022.1.1)
[✓] IntelliJ IDEA Ultimate Edition (version EAP IC-221.5080.56)
[✓] VS Code (version 1.62.3)
[✓] Connected device (2 available)
[✓] HTTP Host Availability

• No issues found!

"simple" vg support

Based on some ideas from @dnfield and my own thoughts:

For very, very simple vgs : i.e. single path or stroke, we should avoid calling toImage and instead directly apply any opacity or colorblending to the encoded paint.

I had previously encountered some difficulty with this sort of conditional decoding, since we normally don't make the paths/paints accessible in an easy way. Instead perhaps we should use a different runtime structure for this sort of "simple" graphic that allows the vector graphic widget to easily blend its own opacity/colors with the paint.

<pattern> support

This is basically just an image shader.

It would also be good to optimize this so that it doesn't need to create an image shader when the pattern element is just being used to place the image at a particular location - which is relatively common IME.

Backwards/Forward compatibility

Overview

We'd still like the ability to make major revisions, so we'll communicate via semver: Major changes indicate that the format is completely incompatible with old clients. Minor changes indicate that both new clients can use old vg files and old clients can use new vg files. At the time of a major version release, we can increment the version number and possibly consider bundling the old decoder as a fallback - but this is out of scope at the time.

Background

The VG binary format is divided into sections which compose a topologically sorted description of a Flutter picture. The intention is that we can trivially convert the binary format into a Flutter picture "online" without creating and traversing a secondary tree structure. First, we describe shaders and gradients. Then we describe paints, which may reference those shaders/gradients. Then we describe paths. Then we describe text. Then finally we describe commands which may reference any of those objects.

Each section is composed of objects which are indicated by an integer identifier that is specific to that section. Each object is then composed of a fixed size number of fields that are implicit in the type of that object.

Adding backwards/forwards compatibility.

There are a few dimensions to backwards compatibility. One would be the ability to add new fields to existing objects.

Consider the encoded paint. Suppose we want to add the ability to provide a ColorFilter object. Today we would expand the size of the object, breaking old clients. An alternative to allow objects to consider growing is to include the size of the object as the first field after the type. This would allow old clients to ignore and read past unknown new fields, while new clients could fill in default values. This does not allow re-arranging of existing fields. Newly added values would need to be nullable in the decoder, or have default values provided. This would need to handled on a case by case basis.

Another dimension of backwards compatibility is new command types. This can be handled by making the command decode tolerate and skip over these commands with an embedded size tag.

The next dimension would be the addition of new sections. Because the sections are in a reasonable topological order, we need to be more careful. Instead of a more generic solution, let us consider some known missing features: filters and _. We know that these will need to be defined before paint, so we will simply insert an empty section that could be filled in later on. We also give each command section a header size and update the decoder to skip over them.

This does not address all possible backwards compatibility problems, but does allow continued iteration. A major backwards compatibility change could allow us to make further changes, but none are known at this time

`text.transform` does not work with `x` and `y`

SVG sample:

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="700" height="500" viewBox="0 0 700 500">
   <g>
      <text text-anchor="end" x="50" y="20" transform="translate(0,300)">1</text>
   </g>
   <g class="ytick">
      <text text-anchor="end" x="50" y="20" transform="translate(0,200)">2</text>
   </g>
   <g class="ytick">
      <text text-anchor="end" x="50" y="20" transform="translate(0,100)">3</text>
   </g>
</svg>

Expected result (Microsoft Edge):

image

Actual result:

image

Might be related to #44

Optimize masks

Masks should be optimized away. Today they have to be implemented with a saveLayer/RT switch, which is especially sad.

Consider this SVG:

<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
  <path fill-rule="evenodd" clip-rule="evenodd" d="M15.094 17.092a.882.882 0 01-.623-1.503l2.656-2.66H4.28a.883.883 0 010-1.765h12.846L14.47 8.503a.88.88 0 011.245-1.245l4.611 4.611a.252.252 0 010 .354l-4.611 4.611a.876.876 0 01-.622.258z" fill="#424242" />
  <mask id="a" maskUnits="userSpaceOnUse" x="3" y="7" width="18" height="11">
    <path fill-rule="evenodd" clip-rule="evenodd" d="M15.094 17.092a.882.882 0 01-.623-1.503l2.656-2.66H4.28a.883.883 0 010-1.765h12.846L14.47 8.503a.88.88 0 011.245-1.245l4.611 4.611a.252.252 0 010 .354l-4.611 4.611a.876.876 0 01-.622.258z" fill="#fff" />
  </mask>
  <g mask="url(#a)">
    <path fill-rule="evenodd" clip-rule="evenodd" d="M0 0h24v24.375H0V0z" fill="#fff" />
  </g>
</svg>

It is trivially expressed as a single path that should be fast to draw. We should be able to easily calculate everything here and just encode that path.

Optimize overdraw

We should be able to eliminate overdraw. This will also require that we pre-calculate blends especially for overlapping transparent shapes. This will mean we can eliminate saveLayers related to group/overlapping opacity.

Updating colors and shaders at runtime

One of the benefits of vector graphics is their ability to be updated at runtime. It is pretty common, for example, to change icon's color regarding the brightness or accent color.

I know that ColorMapper allows us to do it with SVG, but it would be even better to allow this for binary vector graphics too. My idea is that I will pre-compile all my SVG assets as binary content to make it more efficient to load.

Therefore it would be great if we could override the color table directly in FlutterVectorGraphicsListener to update several colors of our vector images.

I would probably create a class like :

class VectorStylesOverride {
     const VectorStylesOverride({
         this.shaders = const <int,Shader>{},
         this.paints = const <int,Paint>{},
     });
     final Map<int,Shader> shaders; 
     final Map<int,Paint> paints; 
}

Add a property to FlutterVectorGraphicsListener :

final VectorStylesOverride? styleOverrides;

And then in the code, when we inserting a paint or shader, we first look at overrides :

  @override
  void onPaintObject({
    required int color,
    required int? strokeCap,
    required int? strokeJoin,
    required int blendMode,
    required double? strokeMiterLimit,
    required double? strokeWidth,
    required int paintStyle,
    required int id,
    required int? shaderId,
  }) {
    assert(_paints.length == id, 'Expect ID to be ${_paints.length}');

    /// If we add an override we add it to the paints instead
    final Map<int, Paint>? overrides = _styleOverrides?.paints;
    if (overrides != null) {
      final Paint? override = overrides[id];
      if (override != null) {
        _paints.add(override);
        return;
      }
    }
    // ...

Also since FlutterVectorGraphicsListener constructor's is private I can't even override this method in a subclass.

image

Another way of doing this would be to update the binary data from the overrides before reading it, like the ColorMapper for SVG.

When using an image we probably would have to create a unique id when giving overrides to cache this alternate version.

Combine shapes where possible

We can do this for shapes with identical painting properties when

  • The shapes have no overlap
  • Any overlap is completely opaque

This would have the benefit of safely removing overdraw in some cases.

Question/Improvement: Invalid double "100%"

Hey,

I saw this issue reported in Crashlytics. Seems that one SVG contains a percentage instead of a double value somewhere. Not sure whether this is something that could be supported as a feature, or if it's a bad SVG in the first place.

Unfortunately my app deals with a lot of unmanaged online content and I do not have means to obtain the actual SVG that caused this issue.

Sorry for being a bit vague ; I don't really have more info I can provide though.

image

Differences between 1.1.9 and 1.1.7

In version 1.1.9, there is a picture of Scientific notation in SVG that cannot be displayed, but in version 1.1.7, this picture can be displayed。

this is a example �for svg string

Pattern sizing is wrong

The size of the pattern is being calculated - it's being done in reference to the root viewbox instead of the destination shape - this will often mean that the pattern image is being drawn with too much spacing around it instead of tiling nicely inside the shape. I'll file a separate bug for that.

For example, the SVG at https://developer.mozilla.org/en-US/docs/Web/SVG/Element/pattern shoudl show ten repeated "stars" across the first circle, but in our case it's calculating the width of the star image based on the viewbox (so 10% of 230 which is 23) instead of the width of the circle (which is 100, so 10% should be 10).

SVG:

<svg viewBox="0 0 230 100" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <pattern id="star" viewBox="0,0,10,10" width="10%" height="10%">
      <polygon points="0,0 2,5 0,10 5,8 10,10 8,5 10,0 5,2" />
    </pattern>
  </defs>

  <circle cx="50" cy="50" r="50" fill="url(#star)" />
  <circle
    cx="180"
    cy="50"
    r="40"
    fill="none"
    stroke-width="20"
    stroke="url(#star)" />
</svg>

can't find ibpath_ops.so on linux

running:
✗ flutter pub run vector_graphics_compiler -i assets/icon.svg -o assets/icon.svg.vec
results in:

Ensure you are on a supported version of flutter and then run 
"flutter precache".
pub finished with exit code 1```

I've run `flutter precache -af` but this doesn't help and the file is still missing.

Question: Points of Path are Accessible using this package?

Hii Dan! I'm exploring a solution to this issue. flutter/flutter#29125 and found this repo in the comments. I spent the last one hour to figure out if is possible to solve this issue using this package or not.

I found another issue from you on the Flutter repo about the serializing path and deserializing it. I guess it seems like this repo is solving the issue.

What I'm trying to do here is creating Path() using svg and also create svg path points from the Path and create it back to svg.

Thank you!

Add support for text transform

Not the css text-transform, just actually encoding the transform on text elements. We could pre-process translations but any more complex operations will require us to transform at runtime

Set up Skia Gold

This may require moving to a flutter org repo.

I'd like to use an existing SVG test suite to ensure we're rendering correctly, especially as we work on new optimizations and features. I'd also like to not rely so much on customer scubas, as the volume itself is difficult to deal with

Overdraw optimization can leave artifacts

This svg:

<svg xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="57 42 20 20">
    <g>
        <g>
            <path d=" M 77 49.767 L 74.095 49.767 L 74.095 44.905 L 69.233 44.905 L 69.233 42 L 77 42 L 77 49.767 Z " fill="rgb(111,161,234)"/>
            <rect x="70.937" y="42.145" width="2.905" height="8.93" transform="matrix(-0.707,-0.707,0.707,-0.707,90.618,130.756)" fill="rgb(111,161,234)"/>
        </g>
    </g>
</svg>

image

Tessellation fails on M1 Mac

Steps to reproduce:

  • Run the following command on an ARM Mac
vector_graphics_compiler -i example.svg -o example.bin --tessellate 

vector_graphics_compiler -i example.svg -o example.bin --no-tessellate works as expected.

The following exception will be thrown:

Logs
Unhandled exception:
Invalid argument(s): Failed to load dynamic library '/Users/[...]/flutter/bin/cache/artifacts/engine/darwin-x64/libtessellator.dylib': dlopen(/Users/[...]/flutter/bin/cache/artifacts/engine/darwin-x64/libtessellator.dylib, 0x0001): tried: '/Users/[...]/flutter/bin/cache/artifacts/engine/darwin-x64/libtessellator.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e')), '/usr/local/lib/libtessellator.dylib' (no such file), '/usr/lib/libtessellator.dylib' (no such file)
#0      _open (dart:ffi-patch/ffi_dynamic_library_patch.dart:12:43)
#1      new DynamicLibrary.open (dart:ffi-patch/ffi_dynamic_library_patch.dart:23:12)
#2      _dylib (package:vector_graphics_compiler/src/svg/tesselator.dart:16:54)
#3      _dylib (package:vector_graphics_compiler/src/svg/tesselator.dart)
#4      _createPathFn (package:vector_graphics_compiler/src/svg/tesselator.dart:291:5)
#5      _createPathFn (package:vector_graphics_compiler/src/svg/tesselator.dart)
#6      new VerticesBuilder (package:vector_graphics_compiler/src/svg/tesselator.dart:210:34)
#7      Tesselator.visitResolvedPath (package:vector_graphics_compiler/src/svg/tesselator.dart:108:39)
#8      ResolvedPathNode.accept (package:vector_graphics_compiler/src/svg/resolver.dart:251:20)
#9      Tesselator.visitViewportNode (package:vector_graphics_compiler/src/svg/tesselator.dart:188:57)
#10     ViewportNode.accept (package:vector_graphics_compiler/src/svg/node.dart:105:20)
#11     SvgParser.parse (package:vector_graphics_compiler/src/svg/parser.dart:643:25)
<asynchronous suspension>
#12     encodeSvg (package:vector_graphics_compiler/vector_graphics_compiler.dart:92:43)
<asynchronous suspension>
#13     main ([...]/vector_graphics/packages/vector_graphics_compiler/bin/vector_graphics_compiler.dart:58:27)
<asynchronous suspension>
Flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel master, 3.1.0-0.0.pre.925, on macOS 12.2.1 21D62
    darwin-arm, locale en-DE)
[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 13.3.1)
[✓] Chrome - develop for the web
[✓] Android Studio
[✓] Android Studio (version 2021.2)
[✓] IntelliJ IDEA Community Edition (version 2022.1.1)
[✓] IntelliJ IDEA Ultimate Edition (version EAP IC-221.5080.56)
[✓] VS Code (version 1.62.3)
[✓] Connected device (2 available)
[✓] HTTP Host Availability

• No issues found!

RRect/Circle/oval approximation is slightly different than flutter_svg

This might be a wontfix, but it makes fidelity comparisons harder to automate.

flutter_svg uses some higher level primitives from SkPath/Canvas to draw RRects and Ovals/Circles. This lib is currently converting them to cubics. This results in slightly different curves than what Skia generates.

One option would be to have a mode in flutter_svg that uses the same approximation values for testing. Alternatively, having a mode in this library that uses the same API as flutter_svg would work too.

Optimize patterns

Patterns which only ever tile their image once do not need to create an image shader and can be replaced with a simple draw call.

Optimize: clips

We should be able to pre-process clips such that we do not require any clipping at runtime.

For example, use path intersection logic to produce a path or set of paths that fit within the clipped area.

[Suggestion] Automatically convert and create asset class

I've played around with the vector graphics and have a suggestion, a simple annotation where you can set all data to convert the svg's into vector files. I've made a working PoC (fork) that does the following:

This package provides a tool to generate vector graphics from svg files and creates a dart file with the vector graphics locations.

For example if you have the following structure:

- assets
  - images
    - subfolder
      - squares.svg
    - flutter.svg
  - different_folder
    - green_rectangle.svg

And the following annotation:

@VectorGraphics(
  svgSources: [
    VectorGraphicsSource(
      input: 'assets/different_folder/green_rectangle.svg',
    ),
    VectorGraphicsSource(
      inputDir: 'assets/images',
    ),
  ],
)
class VectorGraphicsAssets {}

The generator will create .vec files for each svg and create a dart file with the following content:

class VectorGraphicsAssets {
  static const greenRectangle = 'assets/different_folder/green_rectangle.vec';

  static const squares = 'assets/images/subfolder/squares.vec';

  static const flutter = 'assets/images/flutter.vec';
}

I'd love to hear some opinions. The upside is that it is easier to convert, there is automatically a class with all paths and it is updated quite easily. The downside is the use of build_runner, this might not be the best place and the converter command might already be sufficient. 🤔

runtime themeing of colors

I've spoken to several client teams that use some combination of SVG parsing and the SVG theme API to provide dynamic colors to an SVG. We should support a compile time option for this, perhaps accepting a map of identifier -> color in the VectorGraphic constructor.

TBD: how should we indicate dynamic color in the SVG?

Optimize paths

Tessellating paths is showing good results. We should extend this to strokes as well as fills.

Transforms on gradients aren't always working

For example, after #30 the devil SVG is rendering correctly (except the one path that has a blend mode on it directly), but these are not:

<svg viewBox="0 0 667 667" fill="none" 
    xmlns="http://www.w3.org/2000/svg">
    <defs>
        <radialGradient id="paint0_radial" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(901 787) rotate(39.029) scale(557.396)">
            <stop stop-color="#47E9FF" stop-opacity="0.8"/>
            <stop offset="1" stop-color="#414CBE" stop-opacity="0"/>
        </radialGradient>
    </defs>
    <rect x="667" y="667" width="667" height="667" transform="rotate(180 667 667)" fill="url(#paint0_radial)"/>
</svg>
<svg viewBox="0 0 667 667" fill="none" 
    xmlns="http://www.w3.org/2000/svg">
    <defs>
        <radialGradient id="paint0_radial" cx="2%" cy="2%" r="50%" gradientTransform="translate(0.3 0.6)">
            <stop stop-color="#47E9FF" stop-opacity="0.8"/>
            <stop offset="1" stop-color="#414CBE" stop-opacity="0"/>
        </radialGradient>
    </defs>
    <rect x="667" y="667" width="400" height="400" transform="rotate(180 667 667)" fill="url(#paint0_radial)"/>
</svg>
<svg viewBox="0 0 667 667" fill="none" xmlns="http://www.w3.org/2000/svg">
    <defs>
        <linearGradient id="paint1_linear" x1="0%" y1="0%" x2="50%" y2="50%" gradientTransform="translate(0.4 0.7)" gradientUnits="userSpaceOnUse">
        <stop stop-color="blue" stop-opacity="0.5"/>
        <stop offset="1" stop-color="red" stop-opacity="0.1"/>
        </linearGradient>
    </defs>
    <rect x="300" y="0" width="500" height="400" transform="translate(0 100) rotate(45, 250, 250)" fill="url(#paint1_linear)"/>
</svg>

(this one is actually good)

<svg viewBox="0 0 667 667" fill="none" xmlns="http://www.w3.org/2000/svg">
    <defs>
        <linearGradient id="paint0_linear" x1="-198.705" y1="60.4043" x2="38.4005" y2="785.553" gradientUnits="userSpaceOnUse">
        <stop stop-color="#2346F3" stop-opacity="0.5"/>
        <stop offset="1" stop-color="#3F2894" stop-opacity="0.01"/>
        </linearGradient>
    </defs>
    <rect x="200" y="200" width="667" height="667" transform="rotate(33, 400, 400)" fill="url(#paint0_linear)"/>
</svg>
<svg viewBox="0 0 667 667" fill="none" xmlns="http://www.w3.org/2000/svg">
    <defs>
        <linearGradient id="paint1_linear" x1="0%" y1="0%" x2="50%" y2="50%" gradientTransform="translate(0.4 0.7)">
        <stop stop-color="blue" stop-opacity="0.5"/>
        <stop offset="1" stop-color="red" stop-opacity="0.1"/>
        </linearGradient>
    </defs>
    <rect x="300" y="0" width="500" height="400" transform="translate(0 100) rotate(45, 250, 250)" fill="url(#paint1_linear)"/>
</svg>

Rendering large SVGs.

Hello Dan,

I'm maintaining an SVG renderer for Flutter that is optimized for rendering huge GraphViz graphs (i.e. hundreds of bezier curves and thousands of text/rectangle/ellipse nodes).

It employs various necessary optimizations (that make little sense for small SVGs) such as rendering at different levels of detail or an RTree for efficiently finding groups that need to be rendered for any given viewport.

Would it be correct to assume that it's not a goal of vector_graphics to support rendering vector graphics that are that big, or do you plan to eventually support use cases like that?

Allow transition between placeholder and loaded image to have an animation

Images fetched from the network can take significant time to load.
Unfortunately, when a placeholder is defined and the remote asset is loaded we see an immediate switch (pop-in).

Could we provide animation for the transition or have a crossfade (with user-defined duration) between the placeholder and the final image?

The original flutter_svg already had this question posted.

P.S. Thank you for the package. It is really useful

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.