Perspective Custom SVG: Use Stroke, Not a Filled Path

Daniel Price7 min read
HMI ProgrammingOther ManufacturerTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

After the icon was packaged as a targetable 24 × 24 SVG and the open contour was rendered with stroke plus fill="none", Perspective could display the intended geometry instead of closing and filling the line. Follow the request from the component path to the SVG group, then test viewport scaling, fill/stroke semantics, style survival, and cached content in that order.

Where does the icon request stop?

The data path starts at the Perspective component. Its icon prop.path requests an icon file and a group inside that file. The working path was _testIcons/test1: _testIcons identifies the SVG file, while test1 identifies the target group.

The gateway must first find the file in its icon folder. The browser-side renderer must then resolve the requested fragment to <g class="icon" id="test1">. Only after both checks pass does SVG geometry, color, and scaling matter. A blank icon therefore requires a different first check from a visible but malformed icon.

Observed result Likely stopping point Reading or inspection Next check
No icon appears File or group resolution Compare prop.path with the SVG filename and group id Confirm the target CSS and group structure
An icon appears at the wrong size or is clipped Viewport-to-source coordinate mapping Read the inner viewBox and every geometry transform Normalize the 150-unit artwork to 24 units
A solid or triangular region crosses an intended line Fill/stroke interpretation Inspect the final path's computed fill and stroke Set fill="none" and define the stroke inline
Edits appear only after a project restart Previously loaded asset or project state Change one visible attribute and reload the consuming session Refresh the asset-loading path before changing geometry again

Does the requested path resolve the correct SVG group?

Use a target-based icon wrapper rather than placing the exported drawing alone in the icon folder. The wrapper hides icon groups by default and displays the group selected by the URL fragment:

<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <style>
      .icon { display: none }
      .icon:target { display: inline }
    </style>
  </defs>
  <svg viewBox="0 0 24 24">
    <g class="icon" id="test1">
      ...geometry...
    </g>
  </svg>
</svg>
  1. Read the icon component's path exactly. For _testIcons/test1, inspect the file named _testIcons.svg and the group whose id is test1.
  2. Check case, punctuation, and underscores character for character. A valid SVG file does not help if the requested group ID differs.
  3. Confirm that the group has class="icon". Without that class, the supplied target-display rules do not manage it as intended.
  4. Temporarily reduce the group to a simple circle. If the circle remains blank, continue tracing file and target resolution. If it appears, restore the paths and move to coordinate and paint checks.

Is the 150-unit artwork mapped into the 24-unit viewport?

The exported artwork uses viewBox="0 0 150 150". The working icon wrapper uses viewBox="0 0 24 24". Its geometry was reduced with transform="scale(0.16 0.16)", directly derived from 24 / 150 = 0.16.

Setting Exported drawing Icon adaptation Effect
Coordinate extent 150 × 150 24 × 24 Defines the coordinate system presented to the icon renderer
Geometry scale No reduction scale(0.16 0.16) Maps coordinates from 150 units to 24 units
Circle radius 72.5 72.5 × 0.16 = 11.6 Fits the circle within the 24-unit viewport
Path stroke width 5.29px in the exported style 8 before the group transform in the working revision Changes the visible line weight after scaling

Apply the same scale to every element that still uses the original 150-unit coordinates. Scaling only selected paths misaligns the circle, liquid shapes, and open contour. If the artwork is later redrawn directly in 24-unit coordinates, remove the scale rather than applying both conversions.

Is an open contour being filled as though it were a closed shape?

The final path represents the line that contains the liquid. It is an open contour and must be painted as a stroke. SVG fill processing implicitly closes an open path between its endpoints before computing the filled area. A white fill can therefore create a straight closing edge and a large filled region, even though the path data contains no explicit close command.

The two liquid paths are closed areas and legitimately use fill="#FFFFFF". The containing contour requires different paint settings:

<path
  stroke-width="8"
  stroke-linecap="round"
  stroke="#FFFFFF"
  fill="none"
  transform="scale(0.16 0.16)"
  d="M13.18,85.27l7.55-9.21c1-2.09,4.16-4.65,6.06-4.65h5.87c2.64,0,4.29,2.31,5.76,4.65L54.24,97.57H95.87l15.82-21.51c1.47-2.34,3.12-4.65,5.76-4.65h5.87c1.9,0,5,2.56,6.06,4.65l7.55,9.21"/>

Read the computed paint properties, not merely the path data. If fill is anything other than none, correct it before modifying coordinates. If the unwanted closing region disappears but the outline is faint or too heavy, adjust stroke-width; geometry is no longer the failing layer.

Are exported classes and gradients surviving the icon wrapper?

The original drawing stores paint rules in classes: .cls-1 selects url(#linear-gradient), .cls-2 supplies the white fill, and .cls-3 specifies no fill plus a white rounded stroke. The adapted icon attempt did not reproduce the gradient correctly. That result separates two issues: the geometry can render while an exported class or referenced paint definition fails in the packaged icon context.

Feature Dependency Isolation test Decision
Solid fill Direct fill value Set the value inline If it renders, retain inline paint while debugging packaging
Stroke stroke, stroke-width, stroke-linecap, and fill Place all four attributes on the path If the contour renders correctly, the path data is sound
Linear gradient A matching definition ID and fill="url(#linear-gradient)" Replace it temporarily with a solid fill If solid paint works, inspect definition scope and ID resolution
Class-based paint Embedded CSS plus matching class names Move the same properties inline If inline paint works, keep presentation explicit or repair the class scope

Inline presentation attributes provide the shortest diagnostic path because they remove CSS selector and definition-reference variables. After the icon works with solid inline values, reintroduce the gradient separately. Do not change scaling, path data, CSS, and gradient definitions in the same test.

Is stale content hiding a valid edit?

Changes made to the SVG on the gateway were reported as visible only after restarting the project. Treat that behavior as an asset-state branch: first prove whether the session is displaying the edited file, then decide whether the SVG remains wrong.

  1. Change one unmistakable attribute, such as the circle's solid color. Leave path data and scaling untouched.
  2. Reload or reopen the consuming Perspective session and observe the icon.
  3. If the marker change appears, the current asset is loaded; return to paint and geometry diagnostics.
  4. If it does not appear, refresh the project state using the same restart that exposed prior changes, then repeat the marker test.
  5. After the current asset is visible, remove the marker change and test the corrected contour.

A restart can expose a corrected file, but it cannot repair a wrong group ID, an unscaled coordinate system, or a filled open path. Use the marker test to avoid confusing stale content with SVG semantics.

How do you rebuild and verify the resolving branch?

  1. Create the SVG in the gateway icon folder with the target-display wrapper, an inner viewBox="0 0 24 24", and a group such as <g class="icon" id="test1">.
  2. Place all original 150-unit geometry inside that group and apply transform="scale(0.16 0.16)" consistently.
  3. Render the circle and the two closed liquid paths with fills. Use fill="#FFFFFF" on the two liquid paths where white fill is required.
  4. Render the containing contour with fill="none", stroke="#FFFFFF", stroke-linecap="round", and the tested stroke-width="8".
  5. Set the component path to _testIcons/test1, matching the filename and group ID.
  6. Reload the session. If the file remains stale, restart the project and confirm a deliberate marker change before evaluating the drawing.
  7. Verify that the icon fits the 24-unit viewport, both filled liquid paths appear, the containing contour has rounded ends, and no straight closing edge or filled region spans the contour endpoints.

FAQ

What happens if a Perspective SVG path has a white fill but is meant to be a line?

The SVG fill algorithm closes the open contour between its endpoints and paints the resulting area. Set fill="none" and define stroke, stroke-width, and stroke-linecap on that path.

What happens if I use 150 × 150 SVG coordinates in a 24 × 24 Perspective icon?

The geometry can render outside the intended viewport or at the wrong scale. For this artwork, apply scale(0.16 0.16) because 24 / 150 = 0.16.

What happens if the SVG gradient does not render but solid fills do?

The geometry and target path are already working. Keep a solid inline fill while checking the gradient definition ID, its scope, and the matching url(#linear-gradient) reference.

What happens if Perspective still shows the old SVG after I edit the gateway file?

Reload the session and test an unmistakable marker change; if it remains absent, restart the project as required by this installation. Finish by verifying the 24-unit fit, two white liquid shapes, rounded white contour, and absence of any filled closing region.

Back to blog