Can SVG designs be made to look uniform when applied to sharp corners using stroke-dasharray?

In my current project, I am developing an interactive application that allows for direct manipulation of shapes through SVG. To illustrate a specific issue, let's take a look at how a star is rendered in Chrome.

When experimenting with different values of stroke-dasharray, it becomes evident that the strokes on the arms of this star appear inconsistent. Some edges are blunt while others are sharp. Although adjusting stroke-linejoin can change the appearance of the star, it does not completely address the inconsistency across all arms.

<svg width="800" height="600" xmlns="http://www.w3.org/2000/svg"> 
  <polygon stroke="red"
           stroke-width="20"
           stroke-dasharray="5 5"
           points="350,75  379,161 469,161 397,215
                      423,301 350,250 277,301 303,215
                      231,161 321,161" />
</svg>

https://i.sstatic.net/1Glil.png

While adjusting each arm's stroke using stroke-dashoffset might achieve consistency in this scenario, it seems challenging to make sharp turns in strokes appear consistent in a more general context considering how stroke-dasharray operates. However, there is pressure from my team to find a solution to ensure consistency in stroke appearance, so I need to explore this further.

Therefore, I want to confirm: Is there a universal solution to ensure strokes appear consistent around sharp corners when utilizing stroke-dasharray?

Answer №1

UPDATE: This unique approach is now compatible with svg <path> elements, including curved segments, in addition to <polygon> elements. With some adjustments, it may be possible to use this strategy for various SVG shapes, although the demonstration focuses on polygons and paths.

Polygons Implementation (no polyfills needed)

The provided function enables you to dynamically calculate the necessary dash and gap lengths, applying them as a stroke-dasharray to a polygon element. Furthermore, it allows you to opt for dashes at ALL corners or NO corners of the shape.

https://i.sstatic.net/Q2BGQ.png

For each line segment of the polygon, the function computes the length of the segment, calculates the number of required dashes to start and end the segment with half-length gaps, determines the exact dash length, and generates the appropriate stroke-dasharray of dashes and gaps. For example, if there is space for 3 dashes of length d (equivalent to 6 dashes/gaps), the stroke-dasharray would be d/2 d d d d d d/2. This results in starting and ending the line segment with half-dashes.

Repeat this process for each edge, combining the last half-length dash of one edge with the first half-length dash of the next edge.

The function also provides an option to set the noneFlag to true (default is false), converting the stroke from having dashes at all corners to having dashes at no corners.

Refer to the code snippet below for the implementation details. Regarding Paths Usage (requires polyfill as of mid-February 2017) The existing strategy cannot be directly applied to path elements due to their ability to include both straight edges and curves. Adapting this strategy for path elements involves calculating the lengths of path segments and performing similar calculations as done for straight polygon edges but tailored for each type of path segment. While there are challenges transitioning between the older deprecated `pathSegList` API and the upcoming `getPathData` API, utilizing polyfills can bridge this gap. The provided code illustrates usage with paths using these APIs. Explore the attached images demonstrating the application of the strategy on paths.

Answer №2

When dealing with a complex polyline with segments of varying lengths, achieving a uniform dashed line effect is not a simple task.

In theory, it can be done by meticulously creating a dash pattern that matches the total length of the polyline and lists each segment individually. However, this approach would result in extremely lengthy dash patterns, making it impractical. Furthermore, such custom dash patterns would need to be generated for each unique polyline.

<svg width="400" height="400">
  
  <polygon points="50,100, 200,300, 350,300, 350,100"
           stroke="red" stroke-width="30"
           stroke-dasharray="50 50 50 50
                             100
                             50
                             90
                             40 40 40
                             100
                             60 60 60 60 0"/>
  
</svg>

Answer №3

One potential solution involves utilizing markers to mask any drawing inconsistencies. Here is an exaggerated example:

<svg width="900" height="700" xmlns="http://www.w3.org/2000/svg"> 
  <defs>
     <marker id="blue-square"
      viewBox="0 0 15 15" refX="7" refY="7" orient="auto" >
         <rect fill="blue" x="5" y="5" width="10" height="10"/>
      </marker>
    
  </defs>
  <polygon filter="url(#testthis)" stroke="blue"
           stroke-width="25"
           stroke-dasharray="8 8"
           points="450,85  379,171 459,161 387,225
                      433,301 350,260 297,291 333,205
                      261,151 341,135" 
                      marker-mid="url(#blue-square)"                                           
                      marker-end="url(#blue-square)"/>
</svg>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to change the size of a background image

I recently discovered a helpful tutorial on resizing background images that I found very insightful. If you're interested, you can check it out here. After attempting to apply this method to a 900px width div in order to resize only vertically, I enc ...

Ways to ensure a div is positioned beneath another div

I am facing an issue with two divs; one on the right and the other on the left. When I try to add a third div below the right div, it ends up appearing under the left div or at the left side of the left div. Here is my current setup: https://i.sstatic.n ...

Issue with local file directory

Hey there, I'm having an issue with my local path for the style sheet. Can anybody figure out what's wrong? <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> < ...

What is the formula to determine the sizes of grandchildren div containers?

Hey everyone, I'm having some trouble with my jQuery code and I can't seem to figure out what's going on. Here's the scenario: I'm creating a few divs (based on entries from MySQL) and I'd like to show you the end result: ...

What is the best way to create spacing between images in a CSS image slider?

UPDATE: I've made significant progress by modifying the code provided in the link below. I am very close to achieving my desired result, but there are parts of it that still puzzle me. The transition now has spacing on both sides and the hidden space ...

What are the recommended web-safe colors to use for styling an <hr> element?

Having an <hr> element with the color #ac8900 is what I require. When I apply the style in the traditional way <hr color="#ac8900"> it functions perfectly. However, the expectation is to style everything using CSS, so I attempted the followin ...

What is the method for incorporating a link in an accordion header next to the toggle button with Bootstrap?

I'm attempting to enhance a link in the accordion-button so that only the arrow is clickable for collapsing. The CSS I added below makes the arrow clickable, but I am having trouble getting the link in the accordian-button to work. I want users to be ...

Is it possible to disable the pointer event on the parent element only in CSS

Here's the structure I'm working with: <div class='offline'>some text <button class='delete'>Delete</button></div> I want to disable the div using pointer-events: none, but still keep the button activ ...

JavaScript appends a backslash character to a CSS class

I am attempting to populate index.html with the contents from an array using a JavaScript loop. However, I am encountering an issue where a CSS class for picture formatting is displaying some odd characters when rendered in the latest version of Firefox. ...

Increase the border at the bottom while hovering with React.js and the Material UI library

Can someone help me achieve a hover effect similar to the one in this question on Stack Overflow: Hover effect : expand bottom border I am attempting to create the same effect in React using makeStyles of Material UI. Here is my current code: const useSty ...

Is there a way to use jQuery to make a div fade in and toggle over another

I have created a test page and I am looking to achieve a specific effect when the page loads. I want everything on the page to be hidden initially. When I click on the "About" text, I want it to fade in using fadeToggle(); however, when I click on "My work ...

How can jQuery be utilized to dynamically update the text in a navbar?

<div id="page1" data-role="page"> <div data-role="header" data-position="fixed" align="center"><img src="img/VAWE-long-300x30-transparent.png" width="300" height="30" alt="" /></div> <div data-role="content" style="margin ...

Navigating Your Way Through the Center (ASP.NET MVC)

My navbar has elements that I want to center within it, but using margin hasn't been successful. Do you have any suggestions on how I can achieve this alignment using CSS? This is the code snippet: <div class="navbar "> <div class="cont ...

How can I properly save a PNG image with alpha transparency to be compatible with IE6?

Seeking advice on saving a visually pleasing 1 or 8-bit PNG image that renders well in IE6. Open to suggestions on alternative methods as I have experience with Fireworks but exploring new options. Thank you in advance! ...

Align the h2 header vertically within a div container

So, here's the HTML structure that I'm working with: <div class="category"> <div class="container bottom"> <h2>Name1</h2> </div> <div class="container top"> <h2>Name2</h2&g ...

Fix a carousel layout problem

I've made changes to an HTML-PHP module to display portfolio images as a carousel, and I'm using the same module on this website too. However, I've encountered an issue with duplicate content and the previous-next navigation buttons. Can so ...

Upgrade your input button style using jQuery to swap background images

I have an input button with an initial background image. When a certain condition changes, I want to update its image using jQuery without overriding the button's global CSS in the stylesheet. Is there a way to only change the background attribute wit ...

Are the dimensions of <TD> and <table> not displaying properly?

I've encountered a peculiar issue that I need help with. Here is the Fiddle link: http://jsfiddle.net/H3W4X/ If you want to view it in fullscreen: http://jsfiddle.net/H3W4X/embedded/result/ This is the code snippet causing trouble: <div id="wor ...

Angular Markdown Styling: A Guide

Currently, I am using Angular and Scully. I would like to add style to the image in a markdown file within Angular, but I am unsure of how to accomplish this task. The image is currently displaying too large. Can anyone provide me with useful advice on how ...

What are some effective methods for overriding materialui styles?

Here is the CSS style for a checkbox in Material-UI that I captured from the console: .MuiCheckbox-colorPrimary-262.MuiCheckbox-checked-260 I attempted to override this style using the following code, but it was unsuccessful: MuiCheckBox: { colorP ...