Make SVG Path (Vector Graphic) Simplification easier

Provided Input:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="800pt" height="600pt" viewBox="0 0 800 600">
    <g enable-background="new">
    <path style="fill:none;stroke-width:0.074;stroke-linecap:round;stroke-linejoin:round;stroke:rgb(50.19989%,50.19989%,50.19989%);stroke-opacity:1;stroke-miterlimit:10;" d="M 110.949219 265.421875 L 109.730469 265.691406 L 108.699219 266.410156 L 108.011719 267.460938 L 107.78125 268.679688 " transform="matrix(1,0,0,-1,0,600)"/>
    <path style="fill:none;stroke-width:0.074;stroke-linecap:round;stroke-linejoin:round;stroke:rgb(50.19989%,50.19989%,50.19989%);stroke-opacity:1;stroke-miterlimit:10;" d="M 111.050781 268.679688 L 111.050781 265.421875 " transform="matrix(1,0,0,-1,0,600)"/>
    <path style="fill:none;stroke-width:0.074;stroke-linecap:round;stroke-linejoin:round;stroke:rgb(50.19989%,50.19989%,50.19989%);stroke-opacity:1;stroke-miterlimit:10;" d="M 110.949219 268.679688 L 110.949219 265.421875 " transform="matrix(1,0,0,-1,0,600)"/>
      </g>
    </svg>

Expected Output:

    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="800pt" height="600pt" viewBox="0 0 800 600">
        <g enable-background="new">
        <path transform="matrix(1,0,0,-1,0,600)" stroke-width="0.07" stroke-linecap="round" stroke-linejoin="round" fill="none" stroke="#929292" d="M 110.95 265.42 L 109.73 265.69 L 108.7 266.41 L 108.01 267.46 L 107.78 268.68 "/>
        <path transform="matrix(1,0,0,-1,0,600)" stroke-width="0.07" stroke-linecap="round" stroke-linejoin="round" fill="none" stroke="#929292" d="M 111.05 268.68 L 111.05 265.42 "/>
        <path transform="matrix(1,0,0,-1,0,600)" stroke-width="0.07" stroke-linecap="round" stroke-linejoin="round" fill="none" stroke="#929292" d="M 110.95 268.68 L 110.95 265.42 "/>
          </g>
        </svg>

This pertains to enhancing the appearance of SVG paths. The expected output should include elements like path transform, stroke-width, stroke-linecap, stroke-linejoin, fill, stroke, and d (rounded to 2 decimal points for simplicity).

I attempted to use

svg_object_alt=document.querySelector('svg').outerHTML;
to convert the SVG to a string for processing, but I am unsure how to extract and format all the necessary information to match the expected output. Any assistance on this matter would be greatly appreciated :)

I believe that the stroke color can be set directly as #929292 instead of using the rgb color values :)

Answer №1

If you're looking to perform various conversions, one tool that can help is SVGOMG. However, if you prefer a custom script, here's a working example for style to attributes, rounding pathData, and converting RGB to Hex:

1. Replace Inline CSS Style with SVG Attributes

Access each path's style and replace it with attributes:

let style = path.style;

for (let i = 0; i < style.length; i++) {
  let propertyName = style.item(i);
  let value = style.getPropertyValue(propertyName);

  // Convert RGB colors to Hex
  if ((propertyName === 'stroke' || propertyName === 'fill') && value !== 'none') {
    let [r, g, b] = value.replaceAll('rgb(', '').replaceAll(')', '').split(',');
    let colorHex = rgbToHex(r, g, b);
    value = colorHex;
  }

  // Set attribute
  path.setAttribute(propertyName, value);
}

// Remove style attribute
path.removeAttribute('style');

1.2 Color Conversion RGB to Hex

Referencing the approach in this Stack Overflow post, convert RGB to Hex for color values.

1.3 Optional: Decompose the Transform Matrix

For a more detailed transformation breakdown, consider decomposing the transform matrix into separate properties like scaling, translation, rotation, etc. This is inspired by @AndreaBogazzi's solution.

2. Round PathData

Utilize a reliable parser such as getPathData() polyfill to handle pathData rounding. Here's an example implementation:

let pathData = path.getPathData();
roundPath(path, 2);

function roundPath(path, decimals = 3) {
  let pathData = path.getPathData();
  pathData.forEach((com, c) => {
    if (decimals >= 0) {
      com.values.forEach((val, v) => {
        pathData[c].values[v] = +val.toFixed(decimals);
      });
    }
  });
  // Apply rounded values
  path.setPathData(pathData);
}

By handling each command value individually, we can ensure precise rounding for pathData elements.

Answer №2

you have the option to utilize the following code snippet:

const mySvg_Paths = document.querySelectorAll('#my-svg > g > path');
 

for ( let attr of mySvg_Paths[2].attributes ) 
  {
  console.log(attr.name,'-->\n', attr.value);
  }
  
//  or
// console.log( 'outerHTML -->\n', mySvg_Paths[2].outerHTML );
// console.log( 'path.d -->\n', mySvg_Paths[2].getAttribute('d'));
#my-svg {
  width  : 800pt;
  height : 600pt;
  background : lightgreen;
  }
#my-svg path {
  fill              : none;
  stroke-width      : 0.074;
  stroke-linecap    : round;
  stroke-linejoin   : round;
  stroke            : rgb(50.19989%, 50.19989%, 50.19989%);
  stroke-opacity    : 1;
  stroke-miterlimit : 10;
  }
<svg id="my-svg" viewBox="0 0 800 600">
  <g enable-background="new">
    <path
      d="M 110.949219 265.421875 L 109.730469 265.691406 L 108.699219 266.410156 L 108.011719 267.460938 L 107.78125 268.679688 "
      transform="matrix(1,0,0,-1,0,600)"/>
    <path
      d="M 111.050781 268.679688 L 111.050781 265.421875 "
      transform="matrix(1,0,0,-1,0,600)" />
    <path
      style="fill:none;stroke-width:0.074;stroke-linecap:round;stroke-linejoin:round;stroke:rgb(50.19989%,50.19989%,50.19989%);stroke-opacity:1;stroke-miterlimit:10;" 
      d="M 110.949219 268.679688 L 110.949219 265.421875 " 
      transform="matrix(1,0,0,-1,0,600)"/>
  </g>
</svg>

afterwards, you can refer to this link for further information -> Use RegEx to parse a string with complicated delimiting

especially this method:

function parseData(pathData)
  {
  var pieces = pathData.match(/([a-z]+[-.,\d ]*)/gi), i;
  /* now parse each piece into its own array */
  for (i=0; i<pieces.length; i++)
      pieces[i] = pieces[i].match(/([a-z]+|-?[.\d]*\d)/gi);
  return pieces;
  }

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

Exploring the Ins and Outs of Debugging JavaScript in Visual Studio Using

I encountered a peculiar issue while testing some code. When the program is executed without any breakpoints, it runs smoothly. However, if I introduce a breakpoint, it halts at a certain point in the JSON data and does not allow me to single-step through ...

Why do query values disappear when refreshing a page in Next.js? [Illustrative example provided]

In my current project, I am developing a simple Next Js application consisting of just two pages. index.tsx: import React from "react"; import Link from "next/link"; export default function Index() { return ( <di ...

Incorporating interactive maps into an AngularJS web application

I've been attempting to integrate Google Maps into my AngularJS application, using the script tag below: <script src="https://maps.googleapis.com/maps/api/js?key=[MySecretKeyHere]&callback=initMap" async defer></script> I found this ...

Creating a responsive table layout with CSS

I currently have the following code: .fiftyFiftySection { background-color: #000; } .odometer { font-size: 3em; text-align: center; } table td { column-width: 1000px; text-align: center; } @media (max-width: 500px) { table td { column ...

Leveraging ForEach to merge two arrays and generate a fresh entity

I am in search of my final result which should be as follows: result = [{x: '12/12', y: 90 }, {x: '12/11', y: 0}, {x: '12/10', y: 92}, {x: '12/9', y: 0}, ... ] Currently, I have two arrays to work with. The first a ...

Building VSCode on Windows: A step-by-step guide

I am currently in the process of compiling https://github.com/Microsoft/vscode from the source code, but I am facing some challenges. After successfully running scripts\npm.bat install, I proceeded to run scripts\code.bat and a strange window app ...

The ajax function's value will be delivered at a later time

Due to the AJAX function being executed after the main function, pos consistently returns a value of 0 and I am unable to retrieve the actual value. Is there a way for me to run the AJAX function before the main function? var pos = 0; jQuery(function ...

Problem detected in id modification

My JavaScript function is triggered with an onChange event, which works fine when there's only one. <input class="form-control" type="text" onchange="opert(<?php echo $fetch["id_prod"] ?>,1)" id="name" value="<?php echo $fetch["name_prod" ...

Is there a way to display various data with an onClick event without overwriting the existing render?

In the process of developing a text-based RPG using React/Context API/UseReducer, I wanted to hone my skills with useState in order to showcase objects from an onclick event. So far, I've succeeded in displaying an object from an array based on button ...

Tips for designing a HTML form using classes

I need help styling this form using CSS because I have similar areas like a search submit button that require different classes. Any assistance would be greatly appreciated. <perch:form id="contact" method="post" app="perch_forms"> <perch:cont ...

Issue with VideoJS: MP4 file does not play after dynamically updating video URL

I have been using videoJs to display videos on my website. Below is the HTML code: <video id="player-vjs_html5_api" class="vjs-tech" crossorigin="anonymous" preload="auto" src="http://path-to-video/small.mp4"> <p class="vjs-no-vjs">Your bro ...

Implement an event listener on the final element of a webpage utilizing querySelector

I need help with a password security check feature that changes field borders to green or red based on certain conditions. Despite successfully implementing it, the JavaScript code only selects the first field (nickname) instead of the last one. I've ...

Tips for accessing a unique window name in JavaScript

How can I make window.name persist between page refreshes? I need to use window.name to differentiate between multiple browser windows, allowing each one to display distinct data while sharing the same URL. However, my problem is that the value of window ...

Looking to transmit metadata in JSON format for Paystack integration

Lately, I've been exploring Paystack which is quite similar to Stripe. However, I'm encountering some difficulties with including metadata in my transactions. Despite following the instructions and adding it to my dashboard, I seem to have hit a ...

Invalid template detected within the Kendo dropdown component

I am trying to create a template that will only be displayed if the data value is "Low". This is how I have set up my template column: template: '# if( data=="Low" ){#<span><i class="fa fa-square blue"></i> <span># } ' U ...

Unable to choose the option from the modal that functions similarly to a drop-down menu

I need to choose a field that functions similarly to a dropdown box, but does not actually display as one. The select field reveals its values in a pop-up with values and sub-values that I need to select. Challenges : I'm struggling to locate the ob ...

the pause in execution before my function redirects to a different route

Currently, I am developing a page using nodeJs with express which is supposed to display a table. However, I encountered an issue with my variable "allMusique" that contains the data for my page. When trying to access it initially, there seems to be an err ...

The precedence of theme CSS is paramount

Check out this link for Smirnoff Espresso Vodka 70cl (password: hide) Upon inspecting the page source, you'll see that my main stylesheet (main-style) is loaded at the top of the head section with high priority, even above my theme's style. Why ...

HTML/JavaScript: Embrace the Power of Dynamic Page

I have a unique element in my HTML code: <image src="http://..." style='...'> Using Python-Flask, I pass on a dynamic source address and save it as window.dynamicEmbedding. Now, during page load, I want to change the image's ...

Receive File - Error 500 from Server

Getting a 500 Internal Server Error after uploading a large zip file using jQuery and CodeIgniter is causing some confusion. The progress bar completes, but the error appears in the console log without a clear reason. The strange part is that it works fine ...