npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@tooooools/html-to-svg

v1.8.0

Published

Render HTML to SVG

Downloads

74

Readme

tooooools/html-to-svg

Render in the browser an HTML element to SVG with vectorised fonts.
This module uses the Range API for robust and precise text layout computation.

https://github.com/tooooools/html-to-svg/assets/2837959/9bf213c6-620d-4e9a-b9a7-b399c2a93430

Features

Supported elements

The renderer pipeline is structured such as every type of HTML element can have its own renderer, making contribution and testing much more simple.

renderers/div

Render HTML <div> with its background color and its border-radius.
Also acts as the fallback renderer for all HTML elements.

renderers/text

Render text node, using computed style and loaded fonts (will throw an error if no matching fonts declaration is found).

All fonts are outlined using Opentype.js.

renderers/image

Render HTML <img> as SVG <image> element.

renderers/canvas

Render a HTMLCanvas element as a base64 png in a SVG <image> element.

renderers/svg

Render inline <svg> element as a base64 in a SVG <image> element.

Roadmap

  • Support for HTML <hr> element
  • Support for CSS text-decoration property
  • Support for CSS background-image property
  • Support for CSS border property
  • Support for CSS opacity property
  • Support for CSS transform: rotate() property
  • Support for CSS transform: skew() property

Limitations

This project primarily aims at rendering printable SVG files, in which case font rendering is far more robust when outlining every texts.

Opentype.js does not support (yet) loading local fonts: as a result, every font used in in the rendering process should be explicitly declared in the render constructor (see Usage below).

At the time of writing, an an experimental Local Font Access API is being tested, which could circumvent this issue. Contributions on implementing this API, or using native opt-in (or fallback) SVG <text> will be really appreciated.

Installation

npm install @tooooools/html-to-svg

Usage

import HtmlToSvg from '@tooooools/html-to-svg'

// Instanciate a new renderer
const renderer = new HtmlToSvg({
  debug: false,
  ignore: '.html-only, video', // CSS selector
  fonts: [
    { family: 'Roboto', url: '/fonts/roboto-regular.otf' },
    { family: 'Roboto', url: '/fonts/roboto-bold.otf', weight: '600' },
    { family: 'Roboto', url: '/fonts/roboto-regular-italic.otf', style: 'italic' }
  ]
})

// Preload the fonts inside the renderer
await renderer.preload()
  
// Render a DOMElement
const options = { 
  rasterizeNestedSVG: true, // Convert <svg> into <image>
  splitText: false // Force text fragments to be renderered letter by letter
}

const transform = async (from, to) => to

const svg = await renderer.render(document.querySelector('main'), options, transform)

// Do whatever you want with the returned shadow SVGElement
document.body.appendChild(svg)
download(svg.outerHTML)

renderer.destroy()

Contributing

Support for various CSS properties and HTML element will be implemented based on personal usage.

Any contribution are much appreciated: if you have a suggestion that would make this better, please fork the repo and create a pull request.

Implementing a new renderer

To implement a new renderer for a specifc HTML element, simply export the renderer in the src/renderers.js, with the export name matching a HTMLElement.tagName.

The renderer is a curried function with the following signature, returning either a nullish value or a valid SVG HTMLElement:

renderers/example.js
import $ from '../utils/dom-render-svg'

export default ({ debug, fonts }) => async (element, props) => {
  // The coordinates system origin is the top-left corner of the rendered container
  const { x, y, width, height, style } = props

  const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
  rect.setAttribute('x', x)
  rect.setAttribute('y', y)
  rect.setAttribute('width', width)
  rect.setAttribute('height', height)
  return rect

  // or with utils/dom-render-svg:
  return $('rect', { x, y, width, height })
}

Development

$ yarn build
$ yarn example # build and live-serve example/
$ yarn version # build module, example, and publish to npm

Readings

Credits

License

MIT.