Jump to content

vfbb

Members
  • Content Count

    281
  • Joined

  • Last visited

  • Days Won

    31

Posts posted by vfbb


  1. @David_Lyon  We still don't have an ideal renderer, the complete and correct job would be to replace 25% of the FMX, that is, the entire rendering:

    • TCanvas (of screen and bitmaps),
    • TContext (rendering of 3D forms and shaders)
    • TTextLayout,
    • Codecs,
    • Shaders code (Filters and Effects),
    • Printers,
    • Backends graphic libraries (GLES, Metal, DirectX, ...),
    • Caching systems,
    • and others;

    Making implementations that use Skia, because Skia is a layer that adds new features, quality, reliability and important optimizations.

    Much of the work has already been done and works perfectly, and is already faster overall than the default system (see the Benchmark/FmxFPS project in your Skia4Delphi folder). But there are still parts that need to be improved, for example, the performance of bitmaps and effects.

     

    About the quality, we did something that FMX should have done: we considered the already existing property Form.Quality to define the quality of the drawings, which can be HighPerformance, SystemDefault or HighQuality. Anti-alias is only disabled when Form.Quality = HighPerformance, which should be your case.

     

    Over the past few months we have focused on full API stability, adding features and rendering reliability. It is likely that the performance is in the next targets but, as I said, in the current implementation there are already some gains in the main operations, mainly in the texts, and only some types of applications or hardware show worsening.

     

    Note: do not use VM or Debug mode to run the benchmark and I advise leaving Form.Quality = SystemDefault.

    Furthermore, Skia4Delphi's renderer is optional, that is, you can disable it and use only the library controls for example. In this case, just remove the "GlobalUseSkia := True;" make your .dpr.


  2.  

    v4.0.1

     

    • Added option to "Enable Skia" in dll projects; [Plugin]
    • Fixed AV with GPU canvas; [Render]
    • Fixed exceptions with OpenGLES backend on Android; [Render]
    • Fixed issue with creating bitmap cache (texture); [Render]
    • Fixed 3D controls (TViewPort3D) rendering with OpenGLES backend; [Render]
    • Fixed wrong draw of text with attributes in TTextLayout; [Render]
    • Minor improvements.

      Skia version: 107.0.0

     

    • Like 2

  3. github-social-preview.thumb.png.06fa9b6d00c8816b8daf0bf167ba7080.png

     

     

    v4.0.0

     

     

    • Skia library version has been updated from Milestone 98 to 107; [API]
    • Added support for iOS Simulator ARM 64-bit to RAD Studio 11.2 Alexandria or newer. [API]
    • Added TBitmap.CreateFromSkImage; [Framework]
    • Added LinesCount and DidExceedMaxLines properties to TSkLabel; [Framework]
    • Added new splashscreen to our main demo; [Samples]
    • Added ISkParagraph.Visit method; (#136) [API]
    • Rewritted TSkAnimatedImage and TSkAnimatedPaintBox, adding features to have full control over the animation; (#104) [Framework]
      Some of them are: Start and Stop methods, and AutoReverse, CurrentTime, Delay, Duration, Enabled, Inverse, Loop, Pause, Progress, Running, Speed, StartFromCurrent, StartProgress and StopProgress properties. All these properties and methods are in the Animation property of the TSkAnimatedImage and TSkAnimatedPaintBox.
    • Improved automatic tests; [Tests]
    • Fixed issue in edit controls with emoji or Chinese char; (#159) [Render]
    • Fixed custom fonts on Android deployed to assets\internals that was not automatically loaded; (#153) [Render]
    • Fixed webinar demo splashscreen; [Samples]
    • Fixed exception loading images from stream or bytes; (#111) [Framework]
    • Fixed TSkAnimatedImage exceeding bounds in some WrapMode [Framework]
    • Fixed TBitmap.SkiaDraw issues in VCL; [Framework]
    • Fixed TBitmap.ToSkImage AV in VCL; [Framework]
    • Fixed flicker problem in TSkAnimatedImage in VCL; [Framework]
    • Fixed text print; (RSP-16301) [Render]
    • Fixed TSkAnimatedImage with 90° rotation that fails to play; [Framework]
    • Fixed high DPI issues of TSkLabel in VCL; [Framework]
    • Fixed high DPI issues in VCL demo; [Samples]
    • Fixed SkRegion.IsEqual; [API]
    • Fixed link with runtime packages; (#163) [Setup]
    • Fixed big GIF issue; (#118) [API]
    • Fixed wrong pixel format on Android in Delphi 10.3 Rio; [Render]
    • Minor improvements and fixes.

      Skia version: 107.0.0

     

    Compatibility break

    We are in continuous development, so some updates will bring compatibility breaks. So, pay attention to version numbers, we use semantic versions (for major versions there is some compatibility break). See some breaking changes in this version:

    • No longer use TSkAnimatedImage.Enabled to start or stop an animation. Now use TSkAnimatedImage.Animation.Enabled.
    • The class TSkTypefaceManager is deprecated in favor to TSkDefaultProviders;
    • Several changes in API (Skia.pas);

     

    Supported platforms

    • RAD Studio 11 Alexandria: All platforms
    • RAD Studio 10.3 Rio or newer: Windows and Android
    • RAD Studio XE7 or newer: Windows

     

    Github: github.com/skia4delphi/skia4delphi

    Website: skia4delphi.org

     

    • Like 12
    • Thanks 3

  4. 51 minutes ago, Linuxuser1234 said:

    @vfbb ok so i added that to my dbr project file so in my unit7 file how would i apply that font to TLabel2 

    You should use the font family name (which is not necessarily the same as the file name) in family property of controls. 

    One problem you will face is that this property in designtime only lists the fonts registered on your system, so you must install the font on your system (by double clicking on it), and reopen your IDE, so that you can select your font on the Family property.

     

    Note: only you will install the font on the system (to be able to select it inside the IDE), your clients will not need it.


  5. @Linuxuser1234 To be clearer, follow the steps:

    1. Install Skia4Delphi via GetIt or by downloading the installer from github.
    2. Enable the use of Skia in your project: right click on the project > "Enable Skia"
    3. Open your project's dpr to enable Skia as your app's renderer and to register the custom font you want:
    uses
      System.StartUpCopy,
      FMX.Forms,
      Skia, // <<
      Skia.FMX, // <<
      Unit1 in 'Unit1.pas' {Form1};
    
    {$R *.res}
    
    begin
      GlobalUseSkia := True; // <<
      TSkTypefaceManager.RegisterTypeface('C:\Boltgui\Popups\Font\DSEG14ClassicMini-Bold.ttf'); // <<
      Application.Initialize;
      ...

     


  6. You can try with refit unit https://github.com/viniciusfbb/ipub-refit

    The implementation could be something like this:

     

    unit MerchantApi;
    
    interface
    
    uses
      iPub.Rtl.Refit; // https://github.com/viniciusfbb/ipub-refit
    
    type
      TCountry = (MG);
      TCurrency = (MGA);
    
      TPaymentSubscriber = record
        Country: TCountry;
        Currency: TCurrency;
        Msisdn: Cardinal;
      end;
    
      TPaymentTransaction = record
        Amount: Integer;
        Country: TCountry;
        Currency: TCurrency;
        Id: string;
      end;
    
      TPaymentRequest = record
        Reference: string;
        Subscriber: TPaymentSubscriber;
        Transaction: TPaymentTransaction;
      end;
    
      [BaseUrl('https://API_server_host/merchant/v1')]
      IMerchantApi = interface(IipRestApi)
        ['{1D10C463-1567-4DE0-88F2-099CC0442E43}']
    
        [Post('/payments')]
        [Headers('Authorization', 'Bearer {AuthToken}')]
        [Headers('X-Country', '{XCountry}')]
        [Headers('X-Currency', '{XCurrency}')]
        function Payments(AXCountry: TCountry; AXCurrency: TCurrency; const ABody: TPaymentRequest): string;
    
        function GetAuthToken: string;
        procedure SetAuthToken(const AValue: string);
        property AuthToken: string read GetAuthToken write SetAuthToken;
      end;
    
    var
      FMerchantApi: IMerchantApi;
    
    implementation
    
    initialization
      FMerchantApi := GRestService.&For<IMerchantApi>;
    end.

     

    And your code could be this:

     

     

    uses
      MerchantApi;
    
    procedure TForm1.FormCreate(Sender: TObject);
    var
      LPaymentRequest: TPaymentRequest;
    begin
      LPaymentRequest.Reference := 'Testing API';
      LPaymentRequest.Subscriber.Country := TCountry.MG;
      LPaymentRequest.Subscriber.Currency := TCurrency.MGA;
      LPaymentRequest.Subscriber.Msisdn := 331170348;
      LPaymentRequest.Transaction.Amount := 1000;
      LPaymentRequest.Transaction.Country := TCountry.MG;
      LPaymentRequest.Transaction.Currency := TCurrency.MGA;
      LPaymentRequest.Transaction.Id := 'FE9833FE-D5A3-4450-9786-90735F75EBFB';
    
      FMerchantApi.AuthToken := 'koeQidreesddfzsbxOXKjccccccc';
      ShowMessage(FMerchantApi.Payments(TCountry.MG, TCurrency.MGA, LPaymentRequest));
    end;

     


  7. On 9/6/2022 at 2:43 PM, dkprojektai said:

    Can you share an example?

     

    Yes! See a very simple sample:
     

    uses
      System.Net.HttpClient, System.Net.Mime, Skia, Skia.FMX {or Skia.Vcl};
    
    function SendBitmap(const AUrl: string; ABitmap: TBitmap): string;
    var
      LRequest: THTTPClient;
      LFormData: TMultipartFormData;
      LResponse: TStringStream;
    begin
      LRequest := THTTPClient.Create;
      LFormData := TMultipartFormData.Create;
      LResponse := TStringStream.Create;
      try
        LFormData.AddBytes('img', ABitmap.ToSkImage.EncodeToStream(LImageStream, TSkEncodedImageFormat.WEBP, 80));
        LRequest.Post(AUrl, LFormData, LResponse);
        Result := LResponse.DataString;
      finally
        LFormData.Free;
        LResponse.Free;
        LRequest.Free;
      end;
    end;

     

    This is a simple example for you to understand how it works. In practice I use something different. On the client (API consumer), I declare the whole API in a single unit using the Refit library. This removes a lot of complexity throughout the project, as it already magically serializes records and classes, query parameters, headers automatically.

     

    The example above using Refit would look like this:

     

    This is the unit of your api for the client-side (consumer):

    unit MyApiConsumer;
    
    interface
    
    uses
      System.SysUtils, iPub.Rtl.Refit; // https://github.com/viniciusfbb/ipub-refit
    
    type
      [BaseUrl('http://localhost/api/v1')]
      IMyAPI = interface(IipRestApi)
        ['{1D10C463-1567-4DE0-88F2-099CC0442E43}']
    
        [Post('/image-upload')]
        [ContentType(TBodyKind.MultipartFormData)]
        function TryImageUpload(const [Body] AImg: TBytes; out AResponse: string): Boolean;
      end;
    
    var
      FMyApi: IMyAPI;
    
    implementation
    
    initialization
      FMyApi := GRestService.&For<IMyAPI>;
    end.

    And in your code:

    uses
      MyApiConsumer, Skia, Skia.FMX {or Skia.Vcl};
    
    function SendBitmap(ABitmap: TBitmap): string;
    begin
      if not FMyApi.TryImageUpload(ABitmap.ToSkImage.EncodeToStream(LImageStream, TSkEncodedImageFormat.WEBP, 80), Result) then
        Result := 'Failed!';
    end;

     


  8. Also Skia4Delphi (FMX & VCL). If it's just VCL, SVGIconImageList is the one that has better integration with Delphi controls because it has a TSVGIconImageCollection and TSVGIconVirtualImageList.

    • Like 1
    • Thanks 1

  9. I've never tried to print anything on Android, but on iOS, when sharing a PDF, the "Print" option appears in the system menu. If this happens on Android, it would be a very simple solution to implement. To make the PDF just use Skia4delphi, and to share the PDF, it's very simple, I even have a code ready (if you confirm that this solution works, I'll send it to you).

    • Like 1

  10. 31 minutes ago, Vincent Parrett said:

    I recently spent an entire week trying to fix a bug where in heavily threaded situations customers were seeing random av's. The av's and the stack traces were very random, which made it very difficult to pin down. Debugging threads in delphi is painful at best - any changes to timing can completely mask bugs so using breakpoints was not going to work (and the bug would occur in around 4 out of 40 identical threads).  After spending days adding even more (pointless as it turned out) locks all over the show I wasnt' much closer to figuring it out.

     

    I suspected it could be a reference counting issue (since I use interfaces a lot), so started sprinkling some FreeAndNils around the code (in destructors) - suddenly those random av's turned into nil pointer exceptions that were much less random. That confirmed to me that the issue was with accessing objects already free'd. The problem turned out to be that I was using weak references where I really needed strong references - a 70hr week of frustration turned into a 4 line change 🤦‍♂️

     

    That's why I made a topic warning that Weak is not thread safe (confirmed by @Dalija Prasnikar). So cast Weak to strong reference, and even if the strong reference is not nil, it can represent a destroyed object, generating a totally random AV, and this is not documented anywhere on the internet. More information: https://en.delphipraxis.net/topic/4020-weak-reference-is-dangerous/?tab=comments#comment-34379


  11. @3delite 

    Loading dynamic libraries on Android is not that trivial, you will still have problems on some devices of some manufacturers. Here are 3 main tips:

     

    1) Filename: ALWAYS suffix "lib", like "libbass.so"

     

    2) Deployment:

    • On 32bit, the remote path "library\lib\armeabi-v7a\"
    • On 64bit, the remote path "library\lib\arm64-v8a\"
    • Also on 64bit, add the 32bit binary with the remote path "library\lib\armeabi-v7a\" and the condition "'$(AndroidAppBundle)''==''true'" (with the quotes). The condition you can only change via ToolsApi or manually in .dproj.

    See how we do it: https://github.com/skia4delphi/skia4delphi/blob/eed4afbf8a34137a9bfa308bcb5ef87cee84abcb/Source/VCL/Designtime/Skia.Vcl.Designtime.ProjectMenu.pas#L219-L221

     

    3) Loading:
    First try to load using only the filename, and in case of failure use the library path + filename.
    See how we do it: https://github.com/skia4delphi/skia4delphi/blob/eed4afbf8a34137a9bfa308bcb5ef87cee84abcb/Source/Skia.API.pas#L2119-L2124

     

     


  12. Moving away from the profile issue and talking specifically about the CPU usage of FMX on macOS, the same can be related to the use or not of metal. I advise using GlobalUseMetal := True; to take some of the CPU load off.


  13. 2 hours ago, A.M. Hoornweg said:

    Such rounded edges "miss" the points of the polygon, they deviate before hitting the point.

    Here's an example:

     

    uses
      Skia;
    
    function MakeCubicSplineInterpolation(const APoints: TArray<TPointF>): ISkPath;
    var
      LPathBuilder: ISkPathBuilder;
      LSegments: Integer;
      I: Integer;
      mx: Single;
      my: Single;
      LScratches: array of
        record
          a, b, c, r, p: TPointF;
        end;
    begin
      LPathBuilder := TSkPathBuilder.Create;
      if Length(APoints) < 2 then
        Exit(LPathBuilder.Detach);
      if Length(APoints) = 2 then
      begin
        LPathBuilder.MoveTo(APoints[0]);
        LPathBuilder.LineTo(APoints[1]);
        Exit(LPathBuilder.Detach);
      end;
      LSegments := Length(APoints) - 1;
      SetLength(LScratches, LSegments);
      LScratches[0].a := PointF(0, 0);
      LScratches[0].b := PointF(2, 2);
      LScratches[0].c := PointF(1, 1);
      LScratches[0].r := PointF(APoints[0].X + 2 * APoints[1].X, APoints[0].Y + 2 * APoints[1].Y);
      for I := 1 to LSegments - 2 do
      begin
        LScratches[I].a := PointF(1, 1);
        LScratches[I].b := PointF(4, 4);
        LScratches[I].c := PointF(1, 1);
        LScratches[I].r := PointF(4 * APoints[i].X + 2 * APoints[I + 1].X, 4 * APoints[I].Y + 2 * APoints[I + 1].Y);
      end;
      LScratches[LSegments - 1].a := PointF(2, 2);
      LScratches[LSegments - 1].b := PointF(7, 7);
      LScratches[LSegments - 1].c := PointF(0, 0);
      LScratches[LSegments - 1].r := PointF(8 * APoints[LSegments - 1].X + APoints[LSegments].X, 8 * APoints[LSegments - 1].Y + APoints[LSegments].Y);
      for I := 1 to LSegments - 1 do
      begin
        mx := LScratches[I].a.X / LScratches[I - 1].b.X;
        my := LScratches[I].a.Y / LScratches[I - 1].b.Y;
        LScratches[I].b := LScratches[I].b - PointF(mx * LScratches[I - 1].c.X, my * LScratches[I - 1].c.Y);
        LScratches[I].r := LScratches[I].r - PointF(mx * LScratches[I - 1].r.X, my * LScratches[I - 1].r.Y);
      end;
      LScratches[LSegments - 1].p := PointF(LScratches[LSegments - 1].r.X / LScratches[LSegments - 1].b.X,
        LScratches[LSegments - 1].r.Y / LScratches[LSegments - 1].b.Y);
      for I := Length(APoints) - 3 downto 0 do
      begin
        LScratches[I].p := PointF((LScratches[I].r.X - LScratches[I].c.X * LScratches[I + 1].p.X) / LScratches[I].b.X,
          (LScratches[I].r.Y - LScratches[I].c.Y * LScratches[I + 1].p.Y) / LScratches[I].b.Y);
      end;
      LPathBuilder.MoveTo(APoints[0]);
      for I := 0 to LSegments - 2 do
      begin
        LPathBuilder.CubicTo(LScratches[I].p,
          PointF(2 * APoints[I + 1].X - LScratches[I + 1].p.X, 2 * APoints[I + 1].Y - LScratches[I + 1].p.Y), APoints[I + 1]);
      end;
      LPathBuilder.CubicTo(LScratches[LSegments - 1].p,
        PointF(0.5 * (APoints[LSegments].X + LScratches[LSegments - 1].p.X),
        0.5 * (APoints[LSegments].Y + LScratches[LSegments - 1].p.Y)), APoints[LSegments]);
      Result := LPathBuilder.Detach;
    end;
    
    procedure TForm1.SkPaintBox1Draw(ASender: TObject; const ACanvas: ISkCanvas;
      const ADest: TRectF; const AOpacity: Single);
    var
      LPaint: ISkPaint;
      LMyPoints: TArray<TPointF>;
    begin
      LMyPoints := [PointF(62, 511), PointF(162, 605), PointF(262, 610),
        PointF(362, 402), PointF(462, 959), PointF(562, 58), PointF(662, 272),
        PointF(762, 99), PointF(862, 759), PointF(962, 945)];
    
      LPaint := TSkPaint.Create(TSkPaintStyle.Stroke);
      LPaint.Color := TAlphaColors.Red;
      LPaint.AntiAlias := True;
      LPaint.StrokeWidth := 3;
      LPaint.StrokeCap := TSkStrokeCap.Round;
      ACanvas.DrawPath(MakeCubicSplineInterpolation(LMyPoints), LPaint);
      LPaint.StrokeWidth := 10;
      LPaint.Color := TAlphaColors.Black;
      ACanvas.DrawPoints(TSkDrawPointsMode.Points, LMyPoints, LPaint);
    end;

     

    Result:

    image.thumb.png.8e591b43296bb2c8cd20f3fe88c773b2.png

     

    Note: You don't need to use Skia, it was just a facilitator for the example.

    • Like 10

  14. We started porting the Skia4Delphi library to C++Builder and we came across a problem in the static linking of objects, specifically linking the file “/usr/lib/clang/lib/darwin/libclang_rt.ios.a” which is in the SDK path (ex: “C:\Users\<username>\Documents\Embarcadero\Studio\SDKs\iPhoneOS15.2.sdk\usr\lib\clang\lib\darwin\libclang_rt.ios.a”)

     

    In Delphi, this linking is very simple to do. We can simply declare a fake method and add the external '/<sdk_sub_path>/<filename>.a', which is exactly what we do in our Delphi implementation:

    procedure libcompiler_rt; external '/usr/lib/clang/lib/darwin/libclang_rt.ios.a';

     

    In C++Builder however, we didn't find anything similar. So far we've only been able to force this link in two different (but very rudimentary) ways:

     

    Method 1 - Configuring project linking:

    1. Adding to the project library path “$(BDSPLATFORMSDKSDIR)\<DefaultPlatformSDK>\usr\lib\clang\lib\darwin\”
      Note: This is necessary because although some SDK paths are automatically passed to the linker, this is not.
    2. Adding the command -lclang_rt.ios to the project link

    The problem with this method is that apparently there is no environment variable for the <DefaultPlatformSDK>, and adding only relative paths, in this case “\usr\lib\clang\lib\darwin\”, doesn't work. We also tried “$(SDKROOT)\usr\lib\clang\lib\darwin\” but to no avail.

     

    Method 2 – Adding objects to the project

    1. Directly add the file “libclang_rt.ios.a” to the project.

    It also works, but this is also a bad option.

     

    Questions

    1. Is there any other way to force link an SDK object in C++Builder?
      It would be nice to have a simple solution that requires no configuration:
      #pragma link "/usr/lib/clang/lib/darwin/libclang_rt.ios.a" // But this don't work
    2. Would there be any variables we could use to represent the path of the SDK being used? (Ex: “$(SDKROOT)\usr\lib\clang\lib\darwin\”)

     

     


  15. 1 hour ago, schaumermal said:

    Especially since it is recreated each time it is compiled.

    This can be avoided by simply disabling it from the project deployment and creating yours with the same remotedir and remotename. Whenever possible, it's better to do this in your project than in the default delphi files, because you won't be able to share your project with someone else without them having the same issue unless they also edit their default splash . Here's a practical example of a project that does this: https://github.com/skia4delphi/skia4delphi/tree/main/Samples/Webinar - Demo/FMX

    • Like 1

  16. 15 hours ago, domus said:

    As an aside, this test rendered the animation perfectly when loaded and played in the https://lottiefiles.com/ site.

     

    Don't know if this is useful info.

    Can you send me your lottie file?

     

    10 minutes ago, domus said:

    Is there any Skia4delphi specific documentation for TSkShader etc.? Or do we use https://api.skia.org/?

    Official skia documentation is incomplete, but it helps. The official skia api is very similar to Skia4Delphi, just few methods and functions have been renamed for readability.

     

    I imagine you want to know more about custom shaders. They are made in SKSL language, using the SkRuntimeEffect class to build the shader. See some useful links below:

     

    SKSL doc: https://skia.org/docs/user/sksl/
    SKSL playground: https://shaders.skia.org/

     

    SkiaSimpleShaderViewer - Demo using custom shaders in skia4delphi: https://github.com/jimmckeeth/SkiaSimpleShaderViewer
    BricksGame - Game using custom shaders in skia4delphi: https://github.com/skia4delphi/skia4delphi/tree/main/Samples/Webinar - Game/FMX

     

    Skia4Delphi Demo using custom shaders in two units: https://github.com/skia4delphi/skia4delphi/blob/main/Samples/Demo/FMX/Source/Sample.Form.RuntimeEffects.pas
    https://github.com/skia4delphi/skia4delphi/blob/main/Samples/Demo/FMX/Source/Sample.Form.Filter.pas

     

    There is also new documentation from the android team, which is AGSL section. Android Graphics Shader Language (AGSL) is Skia Shader Language (SKSL), the android team just changed the name:

    https://developer.android.com/guide/topics/graphics/agsl

     

    You can also solve all your doubts on our telegram channel: https://t.me/skia4delphi

     

     


  17. 2 hours ago, domus said:

    my test used a Gaussian blur effect and that seemed to work fine, so I hope it doesn't concern all of them...

    AE covers all kinds of animation, there are effects and raster features, for example, that would not even make sense to be supported in lottie, because the idea of lottie is to be vectorized and lightweight.
     

    Lastly, lottie and the bodymovin plugin are constantly developing and adding new features every day, so blogs from 1 year ago may no longer reflect reality.


  18. 1 hour ago, domus said:

    First test with a Lottie export from AE. Two superimposed circles with animated trim paths (connected parameters). Only one circle is animated, the other not. In the Lottie preview in the AE Plugin, all seems fine. In Delphi, only one circle is animated.

     

    Are there any limitations to the complexity of these Lottie imports (or unsupported functionality)?

    There are several limitations of Adobe After Effects to lottie (using bodymovin plugin) and they are not very well documented.

    This site lists some: https://www.elpassion.com/blog/lottie-who-common-mistakes-in-after-effects-animation-for-lottie

     

    Your case may have something to do with Keyframe or expressions...


  19. 37 minutes ago, domus said:

    So, no (truly) interactive animations possible? Only fixed animation sequences?

    No truly interactive animations. But you could create these iterations artificially. Consider this example: https://lottiefiles.com/5222-switch between progress 0% to 50% is the animation enabling a switch, and progress 50% to 100% is the animation disabling a switch. Based on that you can configure the animation in your control so that when you click it execute the progress from 0% to 50% or from 50% to 100%.

     

    Note: Currently our TSkAnimatedImage control is capable of running lottie animations but it is not "so tunable". Either it automatically runs the entire animation or you activate the manual mode and change the progress on your own (for example by adding a timer and changing the progress manually every 15 ms).

     

    In our next release (in a few weeks) we will improve this a lot, we will add new properties to get better control of the animations in the TSkAnimatedImage control.

     

    37 minutes ago, domus said:

    I noticed there is a way to create SVGs in runtime. Maybe I'll experiment with that.

     

    Yes it is possible with Skia4Delphi.

     

    37 minutes ago, domus said:

    Is the entire SKIA library exposed in Delphi, or just part of it?

     

    Excluding experimental or deprecated modules, 99% of the library is exposed.

×