Socket
Socket
Sign inDemoInstall

svg-themer

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

svg-themer

Apply a theme to SVG elements as well as image data and css rules constructed from SVG markup


Version published
Weekly downloads
148
increased by146.67%
Maintainers
1
Weekly downloads
 
Created
Source

svg-themer

Apply a theme to SVG elements as well as image data and css rules constructed from SVG markup.

Abstract

The basic function of this module is to "theme" an SVG data by setting arbitrary properties on the root <svg> element and/or its descendants. Typical use case is to apply stroke and fill via the style property.

This module is not necessary for <svg>...</svg> DOM elements which can be styled with CSS. Unfortunately, CSS cannot be used to style image data derived from SVG, such as <img/> elements and CSS style rule properties with url() values that reference SVG data.

With svg-themer you can theme such objects as easily as actual <svg> elements. You can also attach custom theming "scripts" (functions) so that all SVG data can be themed from a single theme object definition regardless of their individual levels of complexity.

Background

SVG data is displayed on a web page by the following DOM Elements:

  • SVGSVGElement — Represented in XML as <svg>...</svg> (with descendant elements)
  • HTMLImageElement — Represented in HTML as <img src="filename.svg"/> or <img src="data:image/svg+xml...">
  • HTMLElement — Any DOM element inheriting a CSS property value like url(filename.svg) or url(data:image/svg+xml...)

An SVGSVGElement, along with its descendant elements, picks up cascading style properties (including but not limited to stroke and fill) from CSS stylesheet rules. This works quite well, albeit at the memory cost of having to deep-clone the entire element everywhere it needs to appear. However, with the memory capacity of today's machines this cost is usually of no concern.

The situation is quite different, however, for <img/> elements with underlying SVG data and for any element referencing SVG data via a CSS url() function. In these cases applying styles has no effect on the image because it has already been rasterized.

With this module, you can apply a set of thematic styles directly to such SVG data.

IMPORTANT NOTE: For this to work, the SVG data must be "baked-in" to the object using data:image/svg+xml; this version does not handle file URLs.

Data encoding: This module properly handles both unencoded data (data:image/svg+xml, + raw SVG markup) as well as base64-encoded data (data:image/svg+xml;base64, + encoded string). If you experience any issues trying to use unencoded SVG markup directly (such as nested quotes), you can always encode it.

theme objects

Theming is performed in this module by calling property-setting functions that you supply. These "prop setters" take a theme parameter and applies it to the SVG element.

Your theming scheme (the shape of your theme object) is up to you and your prop setter functions. The standard implementation uses a very simple scheme with two properties, color and backgroundColor. A theme registry using this scheme might look like this:

var theme = {
    blackAndWhite: { backgroundColor: 'white', color: 'black' },
    highwaySignage: { backgroundColor: '#006A4D', color: 'white' }, // Pantone 342
    stopSignage: { backgroundColor: '#da291c', color: 'white' } // Pantone 485
};

If you don't specify a custom prop setter for your SVG image, the fallback (svgThemer.setSvgProps) will be called. The fallback assumes a particular simple scheme for theme objects. It may however be overridden to accommodate custom theming schemes.

API

Access npm module:

npm i svg-themer --save
var svgThemer = require('svg-themer');

Access UMD module (one of the following):

<script src="https://unpkg.com/svg-themer@1.0/umd/svg-themer.js"></script>
<script src="https://unpkg.com/svg-themer@1.0/umd/svg-themer.min.js"></script>

svgThemer.setSvgProps(theme)

Set properties on an SVGSVGElement element. Used by the other API methods to style an element extracted from an <img> element's src or a CSSStyleRule object property with a url() value. It then re-injects the styled version back into the src attribute or the CSS url().

This method serves primarily as a fallback when a custom method is not supplied to the other API methods.

The standard implementation

The standard implementation accommodates a basic theming scheme, which it applies only to the root SVGSVGElement:

Colortheme
property
SVG style
Foreground.colorstroke and color
Background.backgroundColorfill

Note: The reason the standard implementation also sets color style is to facilitate using fill: currentColor inside the svg.

Styling <svg> DOM elements

This method can also be called directly on "live" SVGSVGElements in the DOM:

<html>
<body>
  <svg viewBox="25 25 450 450" width="45" height="45" xmlns="http://www.w3.org/2000/svg">
      <polygon points="475 350 350 475 150 475 25 350 25 150 150 25 350 25 475 150"></polygon>
      <path d="M 450 339 L 339 450 L 161 450 L 50 339 L 50 161 L 161 50 L 339 50 L 450 161 Z" style="stroke-width:15px"></path>
      <text transform="matrix(1, 0, 0, 1.689489, 3.74598, -160.023605)" style="fill: currentColor; font: 140.871px sans-serif; font-weight: bold; letter-spacing: -4.1px;" x="61" y="292">STOP</text>
  </svg>
  <svg viewBox="25 25 450 450" width="45" height="45" xmlns="http://www.w3.org/2000/svg">
      <polygon points="475 350 350 475 150 475 25 350 25 150 150 25 350 25 475 150"></polygon>
      <path d="M 450 339 L 339 450 L 161 450 L 50 339 L 50 161 L 161 50 L 339 50 L 450 161 Z" style="stroke-width:15px"></path>
      <text transform="matrix(1, 0, 0, 1.689489, 3.74598, -160.023605)" style="fill: currentColor; font: 140.871px sans-serif; font-weight: bold; letter-spacing: -4.1px;" x="61" y="292">STOP</text>
  </svg>
</body>
var svg = document.querySelectorAll('svg');
svgThemer.setSvgProps.call(svg[0], theme.blackAndWhite);
svgThemer.setSvgProps.call(svg[1], theme.stopSignage);

Results (when <svg> elements use this markup):

black on white stop sign white on red stop sign

Overriding the standard implementation

The standard implementation may be overridden to accommodate custom theming schemes:

svgThemer.setSvgProps = function(theme) { ... };

svgThemer.setImgSvgProps(theme, setSvgProps = svgThemer.setSvgProps)

Themes SVG image data. Similar to calling setSvgProps on an <svg> element directly, except the context is expected to be an HTMLImageElement (shown here demonstrating both unencoded and encoded data):

<html>
<body>
  <img src='data:image/svg+xml,<svg viewBox="25 25 450 450" width="45" height="45" xmlns="http://www.w3.org/2000/svg"><polygon points="475 350 350 475 150 475 25 350 25 150 150 25 350 25 475 150"></polygon><path d="M 450 339 L 339 450 L 161 450 L 50 339 L 50 161 L 161 50 L 339 50 L 450 161 Z" style="stroke-width:15px"></path><text transform="matrix(1, 0, 0, 1.689489, 3.74598, -160.023605)" style="fill: currentColor; font: 140.871px sans-serif; font-weight: bold; letter-spacing: -4.1px;" x="61" y="292">STOP</text></svg>'>
    <img src="data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIyNSAyNSA0NTAgNDUwIiB3aWR0aD0iNDUiIGhlaWdodD0iNDUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBvbHlnb24gcG9pbnRzPSI0NzUgMzUwIDM1MCA0NzUgMTUwIDQ3NSAyNSAzNTAgMjUgMTUwIDE1MCAyNSAzNTAgMjUgNDc1IDE1MCI+PC9wb2x5Z29uPjxwYXRoIGQ9Ik0gNDUwIDMzOSBMIDMzOSA0NTAgTCAxNjEgNDUwIEwgNTAgMzM5IEwgNTAgMTYxIEwgMTYxIDUwIEwgMzM5IDUwIEwgNDUwIDE2MSBaIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOjE1cHgiPjwvcGF0aD48dGV4dCB0cmFuc2Zvcm09Im1hdHJpeCgxLCAwLCAwLCAxLjY4OTQ4OSwgMy43NDU5OCwgLTE2MC4wMjM2MDUpIiBzdHlsZT0iZmlsbDogY3VycmVudENvbG9yOyBmb250OiAxNDAuODcxcHggc2Fucy1zZXJpZjsgZm9udC13ZWlnaHQ6IGJvbGQ7IGxldHRlci1zcGFjaW5nOiAtNC4xcHg7IiB4PSI2MSIgeT0iMjkyIj5TVE9QPC90ZXh0Pjwvc3ZnPg==">
</body>
var img = document.querySelectorAll('img');
svgThemer.setImgSvgProps.call(img[0], theme.blackAndWhite);
svgThemer.setImgSvgProps.call(img[1], theme.stopSignage);

black on white stop sign white on red stop sign

svgThemer.setRuleSvgProps(theme, setSvgProps = svgThemer.setSvgProps, propName = undefined)

Themes an SVG style rule property. Similar to calling setSvgProps on an <svg> element directly, except the context is expected to be an CSSStyleRule (shown here using encoded data):

<html>
<body>
  <style>
    .stop-sign {
      background-image: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIyNSAyNSA0NTAgNDUwIiB3aWR0aD0iNDUiIGhlaWdodD0iNDUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBvbHlnb24gcG9pbnRzPSI0NzUgMzUwIDM1MCA0NzUgMTUwIDQ3NSAyNSAzNTAgMjUgMTUwIDE1MCAyNSAzNTAgMjUgNDc1IDE1MCI+PC9wb2x5Z29uPjxwYXRoIGQ9Ik0gNDUwIDMzOSBMIDMzOSA0NTAgTCAxNjEgNDUwIEwgNTAgMzM5IEwgNTAgMTYxIEwgMTYxIDUwIEwgMzM5IDUwIEwgNDUwIDE2MSBaIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOjE1cHgiPjwvcGF0aD48dGV4dCB0cmFuc2Zvcm09Im1hdHJpeCgxLCAwLCAwLCAxLjY4OTQ4OSwgMy43NDU5OCwgLTE2MC4wMjM2MDUpIiBzdHlsZT0iZmlsbDogY3VycmVudENvbG9yOyBmb250OiAxNDAuODcxcHggc2Fucy1zZXJpZjsgZm9udC13ZWlnaHQ6IGJvbGQ7IGxldHRlci1zcGFjaW5nOiAtNC4xcHg7IiB4PSI2MSIgeT0iMjkyIj5TVE9QPC90ZXh0Pjwvc3ZnPg==)
    }
  </style>
  <span class='stop-sign'></span>
  <span class='stop-sign'></span>
</body>
var rule = document.querySelector('style').sheet.rules[0]; // first rule in first stylesheet
svgThemer.setRuleSvgProps.call(rule, theme.stopSignage);

In this case, all referencing elements are themed simultaneously:

white on red stop sign white on red stop sign

If propName is not given, the following CSS style properties are searched in order for the first one with a url() value beginning with data:image/svg+xml:

  • background-image
  • list-style-image
  • border-image
  • content

svgThemer.mixin(svgOrImgOrRule, setSvgProps = svgThemer.setSvgProps)

This method installs the above calls on an object directly, providing an alternative means of theming the object.

Mixes in one of the above methods as setTheme into the object referenced by svgOrImgOrRule when that object is one of:

  • SVGSVGElement (<svg>...</svg>)
  • HTMLImageElement () with underlying SVG markup in the src` attribute
  • CSSStyleRule (a stylesheet rule) with SVG markup in a particular style's url function

The method returns the object for chaining.

var svgEl = document.querySelector('svg');
var imgEl = document.querySelector('img');
var rule = document.querySelector('style').sheet.rules[0]; // first rule in first stylesheet

svgThemer.mixin(svgEl, propSetter);
svgThemer.mixin(imgEl, propSetter);
svgThemer.mixin(styleRule, propSetter);

The 2nd parameter is optional. If specified, it is used during the theming call (below), overriding the fallback svgThemer.setSvgProps. It is mixed in as setSvgProps. Theme can then be applied the the above objects as follows:

svgEl.setTheme(theme); // calls setSvgProps on itself
imgEl.setTheme(theme); // calls setImgSvgProps on itself
styleRule.setTheme(theme); // calls setRuleSvgProps on itself

Recall that setImgSvgProps and setRuleSvgProps take an optional 2nd parameter to override the prop setter; and setRuleSvgProps takes and optional 3rd paramter to name the property holding the url() to operate on. As noted in the comments in the example, the setTheme methods are references to these methods and therefore can also accept these optional parameters.

mixin is chainable (returns its context) for setting a default theme:

svgThemer.mixin(object).setTheme(theme);

setTheme also returns its context so you can make the following assignment:

var imgEl = svgThemer.mixin(document.querySelector('img')).setTheme(theme);

FAQs

Package last updated on 10 Nov 2018

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc