Search code examples
htmldelphisvgtwebbrowserdelphi-10.4-sydney

How to CENTER and STRETCH/SHRINK SVG display in TWebBrowser?


In a Delphi 10.4.2 Win32 VCL Application on Windows 10 x64, I use a TWebBrowser component to display local SVG files. The TWebBrowser component has these properties:

object wb1: TWebBrowser
  Left = 0
  Top = 0
  Width = 936
  Height = 578
  Align = alClient
  TabOrder = 0
  SelectedEngine = EdgeIfAvailable
  ExplicitLeft = -214
  ExplicitTop = -61
  ExplicitWidth = 856
  ExplicitHeight = 483
  ControlData = {
    4C00000078580000EB3100000000000000000000000000000000000000000000
    000000004C000000000000000000000001000000E0D057007335CF11AE690800
    2B2E12620A000000000000004C0000000114020000000000C000000000000046
    8000000000000000000000000000000000000000000000000000000000000000
    00000000000000000100000000000000000000000000000000000000}
end

Here I load a local SVG file:

procedure TForm1.FormCreate(Sender: TObject);
begin
  wb1.Navigate('file:///\\Mac\Home\Downloads\test\Vector SVG 2.svg');
end;

The display of the SVG file is very nice, but it is left-aligned in the TWebBrowser client area and it is not shrinked/stretched in the TWebBrowser client area:

enter image description here

So how can I make the SVG file image be centered in the TWebBrowser client area and shrinked/stretched in the TWebBrowser client area?

EDIT: I have followed the advice of @AndreasRejbrand and created this HTML page:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" http-equiv="X-UA-Compatible" content="IE=edge" />
</head>
<body>
<img src="Vector SVG 2.svg"
  style="position: absolute; top: 0; left: 0; width: 100%; height: 100%" />
</body>
</html>

This is the source of the "Vector SVG 2" SVG file: Too large to insert here

And this is where I load the HTML file:

procedure TForm1.FormCreate(Sender: TObject);
begin
  wb1.Navigate('file:///\\Mac\Home\Downloads\test\vector.html');
end;

However, the image is still left-aligned and not shrinked (and has no scrollbars anymore):

enter image description here


Solution

  • To some extent this depends on the properties of the SVG image. Specifically, it depends on the values of its width, height, preserveAspectRatio, and viewBox parameters.

    Consider the following example:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <svg xmlns="http://www.w3.org/2000/svg"
      xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
      width="650" height="650" viewBox="0 0 650 650">
    <title>A flower</title>
    <!-- Content -->
    </svg>
    

    This looks like this in the TWebBrowser:

    Screenshot of a VCL application form with a single TWebBrowser on it, displaying a SVG image. The SVG image doesn't fit vertically into the current view and is left-aligned.

    We have several options. One thing we can do is change the SVG so it doesn't have a fixed size:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <svg xmlns="http://www.w3.org/2000/svg"
      xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
      width="100%" height="100%" viewBox="0 0 650 650">
    <title>A flower</title>
    <!-- Content -->
    </svg>
    

    Result:

    Screenshot of same window. Now the image is proportionally scaled to fix into the view. It is centred horizontally.

    Another approach is to create a minimal HTML5 page containing the SVG image.

    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    </head>
    <body>
    <img src="test.svg"
      style="position: absolute; top: 0; left: 0; width: 100%; height: 100%" />
    </body>
    </html>
    

    Animation of the window being resized

    Here's the SVG: https://privat.rejbrand.se/flower.svg.

    If the SVG file doesn't have a viewBox attribute, the approach above doesn't work. One solution -- obviously -- is then to add a viewBox attribute. For example, the OP's file has width="600" height="1050". By adding viewBox="0 0 600 1050" it becomes scalable:

    <svg ... width="600" height="1050" viewBox="0 0 600 1050" ... >
    

    Screen recording