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

pathfit

v1.0.4

Published

Transform CSS path() values to responsively fit a container

Downloads

124

Readme

Jasmine test spec

The CSS path() function does not accept units in its path string, because it is following the SVG path syntax. This makes it impossible to make it responsive with CSS alone. This script module helps by providing on-the-fly capabilities to re-compute the path data applying arbitrary SVG transformations.

The path data can be defined in relation to a view box. Then, if a target size is provided, the transformed path data will fit into that viewport the same way as if the path was part of an SVG with a viewBox defined on its root element. Either a SVG-style preserveAspectRatio attribute or CSS-style object-fit and object-position style properties can be used to position the view box in relation to the target viewport.

Usage

In a webpage

Include the script:

<script src="path/to/pathfit.js"></script>
<!-- or minified -->
<script src="path/to/pathfit.min.js"></script>

SVG-style sizing

Suppose your path source data are from a SVG, which either is a part of your DOM, or a standalone file. Read the path and size information you need:

// 
const svg = svgDocumentFragment.querySelector('svg');

const pathElement = svg.querySelector(`path#${id}`);
const path = pathElement.getAttribute('d');

Get all the relevant attributes from the root <svg> element. The module will figure out itself which of these it should use to define a base view box.

const base = {};
for (let key of ['width', 'height', 'viewBox', 'preserveAspectRatio']) {
    base.key = svg.getAttribute(key);
}

CSS-style sizing

Suppose you want to size your path data in relation to an <img> element. While you still need to give a base view box (i. e. at least base.width and base.height), the sizing algorithm might be governed by the object-fit and object-position CSS properties of the <img>. Read the properties from the element, and just pass the complete CSSStyleDeclaration, the module will pick out the values for the two properties:

const style = getComputedStyle(document.querySelector('img#img-id'));

In a node.js environment

Require the module.

const Pathfit = require('pathfit');

You have to provide path and size information directly

const path = 'M10.362 18.996s-6.046 21.453 1.47 25.329c10.158 5.238 18.033-21.308 29.039-18.23 13.125 3.672 18.325 36.55 18.325 36.55l12.031-47.544';

const base = {
    viewBox: '0 0 80 80',
    preserveAspectRatio: 'xMidYMid meet' // the default
};
// or for CSS sizing, note the camelCase for style properties
const style = {
    objectFit: 'fill', // the defaults
    objectPosition: '50% 50%'
}

Basic scaling

Scale the path to fit a container and then set the style property on the appropriate target element.

SVG-style sizing

const pathfitter = new Pathfit(base, undefined, path);

const scaled_path = pathfitter.scale_with_aspect_ratio(container.offsetWidth, container.offsetHeight);

container.style.offsetPath = `path('${scaled_path}')`;

CSS-style sizing

const pathfitter = new Pathfit(base, style, path);

const scaled_path = pathfitter.scale_with_object_fit(container.offsetWidth, container.offsetHeight);

container.style.clipPath = `path('${scaled_path}')`;

API

new Pathfit(base, style, path, pretransform, opt)

  • optional object base see .set_viewbox(base)

  • optional object {objectFit = 'fill', objectPosition = '50% 50%'} following the syntax of the CSS properties object-fit and object-position.

    In contrast to the method .set_object_style(style), if one of the properties or the parameter as a whole is missing, its value is set to the default.

  • optional string path see .set_path(path, pretransform)

  • optional string | Array<strings> pretransform see .set_path(path, pretransform). pretransform is ignored if path is not set.

  • optional object opt = { precision = 6 } sets the number of significant digits in the returned path data

All constructor arguments are optional.

.set_viewbox(base)

  • object base = {width, height, viewBox, preserveAspectRatio = 'xMidYMid meet'}

    • optional number | string width, height Strings can be followed by 'px'. Every other unit will raise an error.

    • optional string viewBox following the syntax of the SVG attribute

    • optional string preserveAspectRatio following the syntax of the SVG attribute

Sets or computes a view box used for a later transformation with .scale_with_aspect_ratio(width, height) or .scale_with_object_fit(width, height). If viewBox is not provided, width and height will be used instead. preserveAspectRatio is completely optional. An error will be raised if no size can be figured out.

.set_aspect_ratio(preserveAspectRatio)

  • string preserveAspectRatio following the syntax of the SVG attribute

Sets the method of fit for a later transformation with .scale_with_aspect_ratio(). This will raise an error if base was not previously set (although base.preserveAspectRatio could have been ommitted).

.set_object_style(style)

  • object {objectFit, objectPosition} following the syntax of the CSS properties object-fit and object-position.

    In contrast to the constructor, if one of the properties is missing, its value remains unchanged.

Sets the method of fit for a later transformation with .scale_with_object_fit(). This will raise an error if base was not previously set (although style could have been ommitted).

.set_path(path, pretransform)

  • string path following the syntax for path data in the SVG path d attribute or in the CSS path() function

  • optional string | Array<strings> pretransform containing one or more transform functions. Only the SVG syntax for transforms is supported. CSS syntax (i. e. with units and relying on a transform-origin) will fail.

  • returns string the path, optionally pretransformed, in the form that will be used as source for later transformations.

Sets the path for later use with .scale_to() or .transform(). An optional pretransformation can be applied to the path data. This might be especially useful if the path data were provided from a SVG where the path userspace coordinates were not identical to the root viewBox viewport.

Collect all transform attributes in descending tree order down to and including the <path> element and pass that array:

const transforms = [];

let ancestor = pathElement;
while (svg.contains(ancestor)) {
    const attr = ancestor.getAttribute('transform');

    if (attr && attr.length) transforms.unshift(attr);

    ancestor = ancestor.parentElement;
}

pathfitter.set_path(path, transforms);

.transform(trans)

  • string | Array<string> trans containing one or more transform functions. Only the SVG syntax for transforms is supported. CSS syntax (i. e. with units and relying on a transform-origin) will fail.

  • returns string the transformed path.

Transforms the presupplied path with any combination of affine transforms as supplied.

.scale_with_aspect_ratio(width, height)

  • number | string width, height Strings can be followed by 'px'. Every other unit will raise an error.

  • returns string the transformed path.

Transforms the presupplied path such that its computed view box will fit the given dimensions and the preserveAspectRatio rule is fullfilled. This will raise an error if base was not previously set (although base.preserveAspectRatio could have been ommitted).

.scale_with_object_fit(width, height)

  • number | string width, height Strings can be followed by 'px'. Every other unit will raise an error.

  • returns string the transformed path.

Transforms the presupplied path such that its computed view box will fit the dimensions of the objectFit rule and it is positioned according to the objectPosition rule. This will raise an error if base was not previously set (although style could have been ommitted).