Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change content of text elements in svg on a node.js server

I am using svg.js as well as svgdom on a node / express server to try to manage to manipulate an svg and then later turning it into a PNG to build a PDF out of.

Currently, I've made it this far

const window = require('svgdom');
const SVG = require('svg.js')(window);
const document = window.document;
const draw = SVG(document.documentElement);
const fs = require('fs');
const tag = fs.readFileSync(`images/name-tag-1-with-name.svg`,'utf8');
const svg = draw.svg(tag);

Here is the layout of the SVG

<svg id="name-tag" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 216 288">
  <defs>
    <style>
      .cls-1,
      .cls-2 {
        fill: #414042;
      }

      .cls-2 {
        opacity: 0.95;
      }

      .cls-3,
      .first-name,
      .last-name {
        fill: #fff;
      }

      .cls-4 {
        fill: none;
        stroke: #fff;
        stroke-miterlimit: 10;
      }

      .first-name,
      .last-name {
        font-size: 30.87px;
        font-family: Gibson-SemiBold, Gibson;
        font-weight: 700;
      }

      .cls-6 {
        letter-spacing: -0.01em;
      }

      .last-name {
        letter-spacing: -0.01em;
      }

      .cls-8 {
        letter-spacing: 0em;
      }
    </style>
  </defs>
  <polygon class="cls-1" points="0 0 0 288 216 0 0 0" />
  <polygon class="cls-2" points="0 288 216 288 216 0 0 288" />
  <polygon class="cls-3" points="119.35 66.27 109.12 17.38 98.95 66.02 72.4 85.51 72.4 101.58 72.41 101.61 109 74.78 145.5 101.58 145.5 85.45 119.35 66.27"
  />
  <polygon class="cls-3" points="109 82.28 108.97 82.25 72.4 109.08 72.4 125.15 72.41 125.19 109 98.37 145.5 125.15 145.5 109.04 109 82.25 109 82.28"
  />
  <polygon class="cls-3" points="109 105.85 108.97 105.83 72.4 132.66 72.4 148.75 72.41 148.77 109 121.95 145.5 148.75 145.5 132.63 109 105.83 109 105.85"
  />
  <line class="cls-4" x1="11.95" y1="183" x2="206.53" y2="183" />
  <text class="first-name" transform="translate(76.22 228.16)">
    First
  </text>
  <text class="last-name" transform="translate(47.47 266.32)">
    Last
  </text>
</svg>

I see that there is a get() method that accepts an index but the only way I can get at the first text elements is like this...

const fName = svg.get(2).get(8)

I'm not sure why I have to select a second element first and then the actual index of the element I'm trying to get

Also, I'm not sure what I do with a set which is what the .select() method is supposed to return, can I select the text element with it's class name somehow and then be able to get it's index or somehow change the text?

Also trying to change the text of that element at this point doesn't work

fName.plain(firstName)

Gives me this error

TypeError: fName.plain is not a function

I'm just trying to change the text for the .first-name and .last-name text elements in this SVG file and then I'll be able to pass that along to a function that converts it to a PNG that will go into a PDF page being generated.

Can anyone help me understand how to accomplish this in this library? I have been at this for hours

EDIT

I loaded in cheerio and am able to get at the element this way but am still struggling with how to use this to change the text. I can't seem to get a reference to an SVG.js element from this still

const cheerio = require('cheerio')
const $ = cheerio.load(tag);
const firstNameTag = $('text.first-name')
const lastNameTag = $('text.last-name')
like image 882
Jordan Avatar asked Dec 25 '17 03:12

Jordan


Video Answer


1 Answers

To your cheerio-edit, you can change the text-content of the nodes with

firstNameTag.text('This is the new first-name-text');
lastNameTag.text('This is the new last-name-text');

And then get the string of the entire updated file with

const updatedSvg = $.html();
like image 64
niorad Avatar answered Oct 07 '22 16:10

niorad