lishu / vscode-svg2

A vscode svg langauge support extension
MIT License
200 stars 10 forks source link

Please add dimmed area to depict area outside viewBox to preview #49

Open SetTrend opened 3 years ago

SetTrend commented 3 years ago

I noticed that the current "100%" option doesn't seem to be a true "Scale to Fit" option, because it apparently crops the viewBox area occasionally:

grafik

Would you mind adding a "Scale to Fit" or, resp., "105%" option to the preview, matching the viewBox * 1.05, having the area outside the viewBox slightly dimmed, so the preview window will always encompass and depict the viewBox area?

Preview suggestion

lishu commented 3 years ago

Because of the scalability of SVG, the browser automatically zooms when the size is not set (generally based on the width of the view). Therefore, the implementation of "scale to fit" is somewhat complicated and takes some time.

SetTrend commented 3 years ago

Let me propose a preview implementation

... for displaying an out-of-canvas clipping area in the preview window:

  1. Create a copy of the SVG file in memory and use this copy for the following preview process:
  2. Parse the outermost svg element for width and height properties.
  3. If any of the above two values is undefined, try to parse viewBox property for width and height.
  4. If width > 0 && height > 0 then

    1. Add a value of 10 to the x and x properties of outermost svg element.
    2. Set width and height of outermost svg element (in case they weren't set).
    3. surround outermost svg element with the following content: (I'm using curly brackets to indicate placeholders, and a width and height of 1.000 to be sure the rects will exceed the display area.)
    <svg viewBox="0 0 {width + 20} {height + 20}" overflow="visible" xmlns="http://www.w3.org/2000/svg">
     <rect x="0" y="-10" width="10" height="1000" opacity=".15" fill="#101" />
     <rect x="{width + 10}" y="-10" width="1000" height="1000" opacity=".15" fill="#101" />
     <rect x="10" y="0" width="{width}" height="10" opacity=".15" fill="#101" />
     <rect x="10" y="{height + 10}" width="{width}" height="1000" opacity=".15"    fill="#101" />
    
     {content}
    
    </svg>
    1. Render the result to preview window.

So, for example

A file like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg
 [ <!ENTITY nbsp "&#160;">
 ]>

<svg xmlns="http://www.w3.org/2000/svg" viewBox="-15 -75 270 330" x="10" y="10" width="270" height="330" >
</svg>

... will become like this for preview:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg
 [ <!ENTITY nbsp "&#160;">
 ]>

<svg viewBox="0 0 290 350" overflow="visible" xmlns="http://www.w3.org/2000/svg">
  <rect x="0" y="-10" width="10" height="1000" opacity=".15" fill="#101" />
  <rect x="280" y="-10" width="1000" height="1000" opacity=".15" fill="#101" />
  <rect x="10" y="0" width="270" height="10" opacity=".15" fill="#101" />
  <rect x="10" y="340" width="270" height="1000" opacity=".15" fill="#101" />

  <svg xmlns="http://www.w3.org/2000/svg" viewBox="-15 -75 270 330" x="10" y="10" width="270" height="330" >
  </svg>
</svg>


Ready. That's it! 🎉 🚀

Screenshots depicting the result

Without drawing out-of-canvas region: Preview without drawing out-of-canvas region

With drawing out-of-canvas region: Preview with drawing out-of-canvas region
NB: I used 10 and 1000 for width and height of the out-of-canvas rects here because it matched the svg viewBox I've been using in my sample. You might want to compute both values according to actual width and height of the outermost canvas.

lishu commented 3 years ago

Thank you for your help. For now, the scenarios you provide clearly affect the scroll bars and rulers of existing implementations. So it can't be achieved directly.