MAKIO135 / svg5.js

A tiny JS library to generate static SVGs for plotters, lasercutting, embroidery and more, based on Processing/p5js syntax.
MIT License
138 stars 8 forks source link

Package for node #1

Closed jtpio closed 4 years ago

jtpio commented 4 years ago

Hey, nice project!

It would be interesting if this library could also be used in node. For example to generate the svg as text while using the nice p5 API that svg5.js exposes.

Quickly glancing over the code, it probably means updating the way the render function works:

https://github.com/MAKIO135/svg5.js/blob/c2108a8165b3184b604d58b2b7d8f97245b07891/svg5.js#L47

Or exposing a new one for "offline" mode only.

Thanks!

MAKIO135 commented 4 years ago

@jtpio would an getHTML method work for you ?

const getHTML = () => `<svg id="${svg5.id}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ${height}" width="${width}" height="${height}">${svg5.html}</svg>`

This method could actually be called from the render and save methods where this part of code is similar

jtpio commented 4 years ago

Yes sounds good :+1:

MAKIO135 commented 4 years ago

Added that this morning 🙂
As well as a precision method to set numbers of digits after floating points

MAKIO135 commented 4 years ago

@jtpio About the Node package, could you tell me more about your usage?
I want to keep the library as easy as possible to use and had the browser in mind, therefore the global variables to keep it like Processing or p5js.
But am not sure how to approach it in a Node package 🤔
What would be your ideal usage ?

jtpio commented 4 years ago

Added that this morning

Ah nice, thanks!

About the Node package, the use case would mostly be to be able to use on the server, for example on Vercel as a serverless function. So an API endpoint would return a randomly generated SVG.

const svg5 = require('svg5');

svg5.createSVG(500, 500)
svg5.background('red')
svg5.stroke('black')

const html = svg5.getHTML();
console.log(html);

Ideally we could even think of an instance mode like in p5. But yes I agree this would complicate the setup a little bit (also if this is packaged and published to npm).

MAKIO135 commented 4 years ago

So working with a module in Node and keeping the global mode for browsers.
Seems like a good proposition, I'll try to do that 👍

MAKIO135 commented 4 years ago

🎉🎉🎉
npm install svg5

hello_svg5.js:

const svg5 = require('svg5')

svg5.createSVG(500, 500)
svg5.precision(2) // define the number of digits after floating point

// Add content / elements
svg5.background('cyan')
svg5.stroke('black')
svg5.noFill()

for(let y = -150; y <= svg5.height + 150; y += 5){
    svg5.beginShape()
    svg5.vertex(-10, svg5.height + 100)
    for(let x = -10; x <= svg5.width + 10; x += 10){
        svg5.vertex(x, y + svg5.noise(x/500, y/200) * 50)
    }
    svg5.vertex(svg5.width + 10, svg5.height + 100)
    svg5.endShape(svg5.CLOSE)
}

console.log(svg5.getHTML())

then node hello_svg5.js > waves.svg

jtpio commented 4 years ago

Perfect, thanks a lot!

This will for example make it possible for people to embed some nice (dynamic) svg in their GitHub README profile (or any other README).

image

MAKIO135 commented 4 years ago

OMG I NEED TO TRY THAT! 😄

jtpio commented 4 years ago

Something like this should do the trick on Vercel :slightly_smiling_face:

import { NowRequest, NowResponse } from "@vercel/node";

import svg5 from 'svg5';

function random(min: number, max: number) {
  return Math.floor(Math.random() * (max - min) + min);
}

const COLORS = ['cyan', 'limegreen', 'lightsalmon', 'mediumslateblue'];

export default function (req: NowRequest, res: NowResponse) {

  svg5.createSVG(500, 500)

  const color = COLORS[random(0, COLORS.length - 1)];
  svg5.background(color);
  svg5.stroke('black')
  svg5.noFill()
  svg5.noiseSeed(Date.now());

  for(let y = -150; y <= svg5.height + 150; y += 5){
      svg5.beginShape()
      svg5.vertex(-10, svg5.height + 100)
      for(let x = -10; x <= svg5.width + 10; x += 10){
          svg5.vertex(x, y + svg5.noise(x/500, y/200) * 50)
      }
      svg5.vertex(svg5.width + 10, svg5.height + 100)
      svg5.endShape(svg5.CLOSE)
  }

  const svg = svg5.getHTML();
  res.setHeader("Content-Type", "image/svg+xml");
  res.send(svg);
}
MAKIO135 commented 4 years ago

Love that ! I now see a whole new dimension for svg5 🤩

MAKIO135 commented 4 years ago

https://glitch.com/edit/#!/svg5?path=server.js 🎉 https://svg5.glitch.me/svg

MAKIO135 commented 4 years ago