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

adaptive-pixel

v1.0.1

Published

Creating fully flexible / responsive web interfaces. Provides a multiplier value for interface scaling via CSS and JS.

Downloads

124

Readme

adaptive-pixel

This is a package for creating fully flexible / responsive web interfaces.

Provides a multiplier value for interface scaling via CSS and JS. Based on customizable media breakpoints.

Also contains SASS mixins for ease of use.

How it works

  1. You can set breakpoints for different scaling on different screen resolutions (depending on your mockups).
  2. The script will calculate the screen scaling multiplier value and add/remove listeners to recalculate on window 'resize' and 'orientationchange' events.
  3. This multiplier value will be stored/updated in CSS variable --apx in :root of documetn. And also sent as a numder to callback.
  4. In SASS you can use it with helpful mixins that convert incoming values to CSS syntax calc(var(--apx, 1px) * #{$your_value}).
  5. If you set breakpoints according to your mockups, you can take all sizes as is from there for use in mixins. In this case, mockup content will be scaled in the viewport with contain strategy.(see more below)

Demo

React + SASS live demo and code.

Installation

npm i adaptive-pixel

Usage JS

📜 getApxInterface

Function retun an interface that can calculates a multiplier value for scaling, and can add/remove listeneres for refresh value on window 'resize' and 'orientationchange' events.

After calculation (and if this is a new value) puts it to CSS variable --apx to the :root of document, and also sends a new value to the callback function.

import { getApxInterface } from "adaptive-pixel";

const params = {
  setter: (value: number) => console.log("apx", value),
  breakpoints: [[...], [...], ...],
};

const { calculate, startListeners, cleanListeners } = getApxInterface(params);

params

| Property | Describe | | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | setter | (optional) | (value: number) => voidCallback that fires when a new apx value is calculated. Recive a new value as a number. | | breakpoints | (optional) | [number, number, number?, number?][]Array of breakepionts.Default: see below. |

All breakepoints listed in descending order of priority. Each breakpoint contains [mockup width, mockup height, screen min-width, screen min-height]. Default values, for example:

[
  [1440, 750, 900, 540], // "Desktop"
  [360, 1, 300, 300], // "Mobile"
];

In this case we have two mockup resolutions: "Desktop" 1440 x 750 and "Mobile" 360 x any.

  1. First we check that the screen (min-width: 900px) and (min-height: 540px). If it's true, "Desktop" content will scale on screen with contain strategy. If not — go to the next breakpoint.
  2. Now we check that the screen (min-width: 300px) and (min-height: 300px). If it's true, "Mobile" content will scale on screen with contain strategy (and mockup height = 1 means that screen height does not need to be taken into account).
  3. If there are no more breakpoints in the list, then set scale multiplier to 1 (no scaling at all).

Instance methods

| Method | Describe | | ------------------ | ---------------------------------------------------------------------------------- | | calculate() | Run calculation. | | startListeners() | Add listeners to window 'resize' and 'orientationchange' events for recalculation. | | cleanListeners() | Remove listeners. |


Add CSS variables to the :root

| name | value | | --------- | ------------ | | --apx | ${value}px | | --scale | ${value} |

📜 getIsMobileInterface

Function retun an interface that can return match media check result (see below), and can add/remove listeneres for refresh value on match media update.

After match media checking or updating sends a new value to the callback function.

import { getIsMobileInterface } from "adaptive-pixel";

const params = {
  setter: (value: boolean) => console.log("isMobile", value),
  maxWidth: 900,
  maxHeight: 540,
};

const { calculate, startListeners, cleanListeners } =
  getIsMobileInterface(params);

params

| Property | Describe | | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | setter | (required) (value: boolean) => voidCallback that fires when a new "is mobile" state value is calculated. Recive a new value as a boolean. | | maxWidth | (optional) numberDefault: 900 | | maxHeight | (optional) numberDefault: 540 |

setter recive true when match media is (max-width: ${maxWidth}px), (max-height: ${maxHeight}px) (viewport width < maxWidth OR height < maxHeight).

Note: Deafult maxWidth and maxHeight of getIsMobileInterface works great with default breakpoints of getApxInterface. If you set your own breakpoints, update those too.

Instance methods

| Method | Describe | | ------------------ | --------------------------------------------------------- | | calculate() | Run calculation. | | startListeners() | Add window.matchMedia event listener for recalculation. | | cleanListeners() | Remove listeners. |

Usage SASS

This package contains SASS mixins and functions to work with adaptive-pixel.

To use them in a .sass file, place it at the top:

@use 'adaptive-pixel/dist/mixins' as *

Functions

📜 apx($value [$value2 [...]])

Arguments: number [number [...]]

Converts one or more values to calc(var(--apx, 1px) * #{$value}) each. Zero will remain 0.

.block
  padding: apx(20 0 12)

// output
.block
  padding: calc(var(--apx, 1px) * 20) 0 calc(var(--apx, 1px) * 12)

Mixins

📜 +afs($size [, $height [, $weight]])

Arguments: number [, (number | number% | null) [, (number | string)]]

+afs() will return font-size, and if values are given line-height and font-weight CSS properties.

| Argument | Output examples | | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | $sizenumber | 16 => font-size: apx(16) | | $height(optional)number \| number% \| null | zero0 => line-height: normalnumber non zero18 => line-height: apx(18)number + %130% => line-height: 130%nullnull => no line-height output | | $weight(optional)number \| string | 700 => font-weight: 700bold => font-weight: bold |

.text
  +afs(20, 130%, 700)

// output
.text
  font-size: apx(20)
  line-height: 130%
  font-weight: 700

📜 +awh($width [, $height])

📜 +alt($left [, $top])

📜 +art($right [, $top])

📜 +arb($right [, $bottom])

📜 +alb($left [, $bottom])

Arguments: number [, number]]

+awh() will return width and height CSS properties. If $height is not provided, $width will be used for the height (eg: +awh(100) is equal to +awh(100, 100)).

Same for other mixins, but for the left, top, right and bottom respectively.

.block
  +awh(100)

// output
.block
  width: apx(100)
  height: apx(100)

📜 +altrb($l, $t, $r, $b, $w, $h)

Return next:

position: absolute
margin: auto
+alt($l, $t)
+arb($r, $b)
+awh($w, $h)

📜 +desktop

📜 +mobile

This mixins will wrap CSS properties of the selector into the @media rules.

| Mixin | Media rule | | ---------- | -------------------------------------------- | | +desktop | (min-width: 901px) and (min-height: 541px) | | +mobile | (max-width: 900px), (max-height: 540px) |

.block
  background: #FFF
  +desktop
    +awh(100, 200)
  +mobile
    +awh(60)

// output
.block
  background: #FFF

@media (min-width: 901px) and (min-height: 541px)
  .block
    width: calc(var(--apx, 1px)* 100)
    height: calc(var(--apx, 1px)* 200)

@media (max-width: 900px), (max-height: 540px)
  .block
    width: calc(var(--apx, 1px)* 60)
    height: calc(var(--apx, 1px)* 60)

Note: If you set your own breakpoints, you should make your own media mixins.

JS Helpers

apxCssValue (val: number) => string

Get a number and return a string for inline css style: calc(var(--apx, 1px) * ${val}) (like a SASS mixin apx()).

Examples

Below are examples for the getApxInterface, but the same for the getIsMobileInterface.

TS

import { getApxInterface } from "adaptive-pixel";

// will be called when the value is updated
const yourSetterCallback = (value: number) => console.log("apx", value);

const { calculate, startListeners, cleanListeners } = getApxInterface({
  setter: yourSetterCallback,
});

calculate(); // first run (on load, eg)
startListeners();

cleanListeners(); // remove listeners for cleanup if necessary

React

import { getApxInterface } from "adaptive-pixel";

export const SomeRootComponent: React.FC = () => {
  const [apx, setApx] = useState(1);

  useEffect(() => {
    const { calculate, startListeners, cleanListeners } = getApxInterface({
      setter: setApx,
    });

    calculate();
    startListeners();

    return () => {
      cleanListeners();
    };
  }, []);

  useEffect(() => console.log("apx", apx), [apx]);
  // ...
};

Svelte

// $lib/store/adaptivePixel.ts
import { writable } from "svelte/store";
import { getApxInterface } from "adaptive-pixel";

const createApxStore = () => {
  const { subscribe, set } = writable(1);
  const { calculate, startListeners, cleanListeners } = getApxInterface({
    setter: set,
  });

  return { subscribe, calculate, startListeners, cleanListeners };
};

const adaptivePixel = createApxStore();
export default adaptivePixel;
// +layout.svelte
import adaptivePixel from "$lib/store/adaptivePixel";

onMount(() => {
  adaptivePixel.calculate();
  adaptivePixel.startListeners();

  return () => {
    adaptivePixel.cleanListeners();
  };
});

$: console.log("adaptivePixel", $adaptivePixel);

SASS

@use 'adaptive-pixel/dist/mixins' as *

.block
  +awh(100, 200)
  padding: apx(40 20 30)

  +desktop
    +alt(20)
  +mobile
    +arb(16, 24)

.text
  +afs(20, 130%, 700)

  +desktop
    color: #C00
  +mobile
    color: #0C0

License

MIT