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

simdope

v8.7.0

Published

SIMDope 🎨 - Color trafficking library faster than tools not mentioning it, lighting fast and around 1700 lines of code (~34kB and 0 dep.)

Downloads

115

Readme

Introducing SIMDope 8.5.0: The Rocket-Fast Color Processing King-Size library in JavaScript

Knock, knock, unleash the Power of Exceptional Color Handling with -> Unparalleled Speed <-

MIT License

SIMDope Branding Logo

🎨 Blend, Simplify, and Categorize Colors Like Never Before!

Bringing 250K colors (still manageable) down to a "BEST" manageable 25K with methods such as .simplify(ex: 1.6), or categorize skin tones using the (Boolean) property of Color's instances named .skin and other ones into clusters of 64, 256, or even 4096 possibilities, utilizing the .rgbaon[6,8,12,16]bits, and witness the magic of simplification and categorization like never before!

πŸš€ Incomparable Speed and Efficiency!

Experience unparalleled speed with the ability to process 2M operations a second, reducing ~103K colors down to 624 in just 162ms on an average "Intel I5" (CPU) equipped computer - an achievement of 2M+ OPS / SEC. that redefines the boundaries of traditional JavaScript!

SIMDope Performance NPM Downloads

πŸ“Š Transform 3D Color Data (r, g, b) to 1D Arrays!

Employ Lebesgue, Hilbert, and Moore algorithms to convert complex 3D color sets into neatly ordered 1D arrays, navigating through various hues, tones, saturations, chroma, and luminosity with finesse. SIMDope offers the only authentic way to navigate through complex color sets with such ease and precision! See: colors.get_deduplicated_sorted_uint32a(limit=200, background="#FFFFFFFF", algorithm="lebesgue")

_get_most_used_color_sorted_well_html5 = (simdopeColors) => {
    "use strict";
    // Optional "but" faaaaster as it recycles it (being a sequencial operation, only one isntance of "Color" is needed).
    var recycolor = new SIMDopeColor(new ArrayBuffer(4)), categories = new Map();
    for(var i = 0; i < simdopeColors.length; i++) {
        // Give you access to all properties and method of Color's instance
        recycolor = simdopeColors.get_element(i, recycolor);
        // Simplify the color of 320% (YEAH FAAAST)
        recycolor.simplify(3.2);
        // The color "i" is in the category being N (64 possibilities using 6 bits)
        // 4, 6, 8, 12, 16 BITS RESULTS IN (16, 64, 256, 4096, 65536) CATEGORIES
        categories.set(i, recycolor.rgbaon6bits);
        // = CLUSTERING METHOD FASTER THAN A thunderbolt being faster than a "TR-3B"
    }
    // Constants like "limit" is simply ignoring less redundant ones before sorting them (after "background" enabling us to ignore alpha) with the fine tuned and chosen "algorithm".
    var LIMIT = 999, BACKGROUND = "#FFFFFFFF", ALGORITHM = ["hilbert", "moore", "lebesgue"][Math.floor(Math.random() * 3 - 0.1)];
    // List of colors, given a uint32array's buffer, we get a SIMDope's Colors' instance right back into our JS code
    var colors = new SIMDopeColors(simdopeColors.get_deduplicated_sorted_uint32a(LIMIT, BACKGROUND, ALGORITHM).buffer);
    // Array of hexadecimal colors in the starting block
    var hexs1D = [], arrayTemp = [], hexs2D = new Array(64).fill([]);
    // Filling the 2D "list" with our champion's hexadecimal outputs
    for(var i = 0; i < LIMIT; i++) {
        recycolor = colors.get_element(i, recycolor);
        if(recycolor.is_not_skin()){ // Ignoring skin toned colours
            arrayTemp = hexs2D[recycolor.rgbaon6bits]; // Select the color's cluster
            arrayTemp.push(recycolor.hex); // Add color's "HEX" value to one of the 64 clusters
        }
    }
    // Returning an array of HTML5/CSS3 (ready) colors from a two dimension array of clusters with hexadecimal colors
    hexs1D = Array.prototype.concat.apply([], hexs2D);
    return hexs1D;
};

SIMDope Sorting Colors

How to Integrate SIMDope into Your Projects

npm install simdope

Importing the Library

Browser

// Use the file located in /dist/browser.min.js for proper polyfill support (pre-Chrome 61.0)
var Color = window.SIMDOPE.Color;
var Colors = window.SIMDOPE.Colors;

NodeJS

// simdope/dist/index.min.js is also available
import { Color, Colors } from "simdope";

NEW (AWESOME) FEATURE V.6+ => "SIMDopeCreate(mode)"

// simdope/dist/index.min.js is also available
import { SIMDopeCreate, SIMDopeCreateConfAdd, SIMDopeCreateConfRemove } from "simdope";
// Exemple
var MODE = SIMDopeCreateConfAdd({
    "create": {
        "new_of": true,
        "new_uint32": true
    },
    "properties": {},
    "methods": {
        "get_use_element": true,
        "set_tail": true,
        "is_dark": true,
        "blend_first_with": true,
        "blend_first_with_tails": true
    }
}), SIMDOPE = SIMDopeCreate(MODE), Color = SIMDOPE.Color;
var color = Color.new_uint32(0x0D00CDBF); // Blue 25% transparent

// DEFAULT (Slower because it is a big class)
var SIMDopeObjectConf = {
    "create": {
        "new_zero": true,
        "new_splat": true,
        "new_of": true,
        "new_safe_of": true,
        "new_from": true,
        "new_array": true,
        "new_array_safe": true,
        "new_uint32": true,
        "new_uint32b": true,
        "new_hsla": true,
        "new_hex": true,
        "new_hex_name": true
    },
    "properties": {
        "tail": true,
        "pos": true,
        "hilbert": true,
        "lebesgue": true,
        "moore": true,
        "uint32": true,
        "uint32b": true,
        "hex": true,
        "ycbcra": true,
        "laba": true,
        "hsla": true,
        "rgbaon4bits": true,
        "rgbaon6bits": true,
        "rgbaon8bits": true,
        "rgbaon12bits": true,
        "rgbaon16bits": true,
        "skin": true
    },
    "methods": {
        "set": true,
        "set_from_array": true,
        "simplify": true,
        "set_from_simdope": true,
        "set_from_buffer": true,
        "get_tail_opacity": true,
        "get_tail_opacity_and_reset": true,
        "get_tail": true,
        "get_tail_and_reset": true,
        "reset_tail": true,
        "set_tail": true,
        "normalize": true,
        "set_out_of": true,
        "get_subarray": true,
        "get_slice": true,
        "get_buffer": true,
        "is_skin": true,
        "is_not_skin": true,
        "sum_rgba": true,
        "sum_rgb": true,
        "average_rgb": true,
        "is_dark": true,
        "is_fully_transparent": true,
        "is_fully_opaque": true,
        "is_not_fully_transparent": true,
        "is_not_fully_opaque": true,
        "match_with": true,
        "euclidean_match_with": true,
        "manhattan_match_with": true,
        "cie76_match_with": true,
        "set_r": true,
        "set_g": true,
        "set_b": true,
        "set_a": true,
        "to_greyscale": true,
        "to_greyscale_luma": true,
        "multiply_a_255": true,
        "copy": true,
        "get_difference_with": true,
        "merge_with_a_fixed": true,
        "blend_first_with": true,
        "blend_all": true,
        "blend_all_with_tails": true,
        "blend_with": true,
        "blend_first_with_tails": true,
        "get_deduplicated_sorted_uint32a": true,
        "get_element": true,
        "get_new_element": true,
        "get_use_element": true
    }
};

How to use SIMDope.Color?

πŸ”§ Functions, Methods, and Properties of SIMDope.Color

Instantiate an object of the single color class

// We often use a uint32array just as: new Uint32Array(imagedata.data.buffer)
// Better just put the uint32array inside the constructor Colors using the class named: Color
Color(with_main_buffer, offset_4bytes_optional) // Uint8Array.of(127, 95, 0, 255) as "r, g, b, a" works too
Color.new_zero()
Color.new_of(r, g, b, a)
Color.new_safe_of(r, g, b, a)
Color.new_from(agbr_array)
Color.new_array(rgba_array)
Color.new_array_safe(rgba_array)
Color.new_uint32(uint32) 
Color.new_uint32b(uint32b)
Color.new_hsla(h, s, l, a)
Color.new_hex(hex_anything)

πŸ” Color's Properties:

| Property | Description | |------------------------|--------------------------------------------------------------| |color.r | Red component (readonly) | |color.g | Green component (readonly) | |color.b | Blue component (readonly) | |color.a | Alpha component (readonly) | |color.uint32 | Integer representation (readonly) | |color.uint32b | Integer representation (readonly) | |color.hex | Hex representation (readonly) | |color.hsla | HSLA representation (readonly) | |color.lab | LAB color space (readonly) | |color.ycbcra | YCbCrA color representation (readonly) | |color.skin | Indicates if the color matches skin tones (Boolean) | |color.tail | Utility for chaining multiple colors before blending | |color.hilbert | Indicates the 1D (uint32) index of the RGB coordinates | |color.moore | Indicates the 1D (uint32) index of the RGB coordinates | |color.lebesgue | Indicates the 1D (uint32) index of the RGB coordinates | |color.rgbaon4bits | RGBA on 4 bits representation (readonly) | |color.rgbaon6bits | RGBA on 6 bits representation (readonly) | |color.rgbaon8bits | RGBA on 8 bits representation (readonly) | |color.rgbaon12bits | RGBA on 12 bits representation (readonly) | |color.offset | Offset of the color data (readonly) | |color.buffer_ | Primary buffer (private; use methods for access) | |color.subarray_ | Provides a "pointer" instance without copying data (private) | |color.slice_ | Clones the data into a new Uint8Array (private) |

πŸ” Color's Methods:

Get:

| Method | Description | | ------ | ----------- | |color.get_buffer( ) | Retrieve the primary buffer | |color.get_subarray( ) | Access the "pointer" instance of the color data | |color.get_slice( ) | Clone and retrieve the color data | |color.sum_rgba( ) | Sum of RGBA values | |color.sum_rgb( ) | Sum of RGB values | |color.is_dark( ) | Check if color is dark | |color.is_skin( ) | Check if color matches skin tones | |color.is_fully_transparent( ) | Check if color is fully transparent | |color.is_fully_opaque( ) | Check if color is fully opaque | |color.is_not_skin( ) | Check if color doesn't match skin tones | |color.is_not_fully_transparent( ) | Check if color isn't fully transparent | |color.is_not_fully_opaque( ) | Check if color isn't fully opaque |

Set:

| Method | Description | |-------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------| | color.set(with_buffer ) | Set the color using (Uint8Array or ArrayBuffer) | | color.set_from_simdope(color ) | Set a color from a Color instance | | color.set_from_array(new Uint8Array(4) ) | Set the color from an RGBA | | color.set_from_buffer(with_buffer, offset_four_bytes ) | Reuse the instanced object | | color.set_tail(simdope_instance, premultiply_alpha_255_optional ) | Set a tail | | color.simplify(divider ) | Peg the color (e.g., 1.6, 2, 3.2) | | color.blend_with(another_color, strength_on_255, should_return_transparent, is_alpha_addition ) | Blend | | color.blend_first_with(another_color, strength_on_255, should_return_transparent, is_alpha_addition ) | Blend | | color.blend_first_with_tails(is_alpha_addition ) | Blend color with tails then deletes tail links | | color.match_with(another_color, threshold_on_255 ) | Match color | | color.manhattan_match_with(another_color, threshold_float_optional ) | Match color using Manhattan algorithm (Return a Boolean or a Float if no threshold is given) | | color.euclidean_match_with(another_color, threshold_float_optional ) | Match color using Euclidean algorithm (Return a Boolean or a Float if no threshold is given) | | color.cie76_match_with(another_color, threshold_float_optional ) | Match color using CIE76 algorithm (Return a Boolean or a Float if no threshold is given) | | color.set_r(r ) | Set red component to r | | color.set_g(g ) | Set green component to g | | color.set_b(b ) | Set blue component to b | | color.set_a(a ) | Set alpha component to a | | color.to_greyscale( ) | Convert color to greyscale | | color.to_greyscale_luma( ) | Convert color to greyscale using luma |

πŸ” Color's Functions:

| Function | Description | | -------- | ----------- | |Color.with_r(color, r ) | Create a new color instance using color with specified red component r | |Color.with_g(color, g ) | Create a new color instance using color with specified green component g | |Color.with_b(color, b ) | Create a new color instance using color with specified blue component b | |Color.with_a(color, a ) | Create a new color instance using color with specified alpha component a | |Color.with_inverse(color ) | Create a new color instance with inverted colors of color | |Color.with_match(color_a, color_b, threshold_on_255 ) | Match two colors color_a and color_b with a threshold threshold_on_255 | |Color.blend(color_a, color_b, strength_on_one, should_return_transparent, is_alpha_addition ) | Blend two colors color_a and color_b with strength_on_one, should_return_transparent, and is_alpha_addition |

Please, look at the source code to know more about other cool ways of using it ...

How to use SIMDope.Colors?

πŸ”§ Functions, Methods, and Properties of SIMDope.Colors

πŸ” Colors' Properties:

| Property | Description | | -------- | ----------- | | colors.length | Number of colors in the list (readonly) | | colors.buffer | Buffer containing the color data (readonly) |

πŸ” Colors' Methods:

Get:

| Method | Parameters | Description | |-----------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------| | colors.get_element(index, old_color_object_optional_faster ) | index: Position of color in the list old_color_object_optional_faster: (Optional) Previous color object for faster access | Retrieve the color at a specified index. When you get an element and apply changes, it updates the color within your list's buffer. | | colors.get_new_element(index) | index: Position of color in the list | Retrieve the color at a specified index. When you get an element and apply changes, it updates the color within your list's buffer. | | colors.get_use_element(index, old_color_object_optional_faster ) | index: Position of color in the list old_color_object_optional_faster: (Required) Previous color object for faster access | Retrieve the color at a specified index. When you get an element and apply changes, it updates the color within your list's buffer. | | colors.subarray_uint32(start, end ) | start: Start index end: End index | Get a subarray from the Uint32Array representation. | | colors.slice_uint32(start, end ) | start: Start index end: End index | Get a slice from the Uint32Array representation. | | colors.subarray_uint8(start, end ) | start: Start index end: End index | Get a subarray from the Uint8Array representation. | | colors.slice_uint8(start, end ) | start: Start index end: End index | Get a slice from the Uint8Array representation. | | colors.get_hex() | None | List all the hexadecimal values of each colors within the Colors' instance. | | colors.get_properties(key) | key: ("hex", "r", "skin", or any other property...) | Return an array of the properties of all colors. | | colors.get_deduplicated_uint32a( ) | None | Removes duplicate uint32 entries. May need polyfills for older browsers. | | colors.get_deduplicated_sorted_uint32a(limit, background, algorithm ) | Optional | Use a high-performance 8bits curve algorithm (one of "hilbert", "moore", "lebesgue") |

Set:

| Method | Parameters | Description | | ------ | ---------- | ----------- | | colors.set_element(index, color_object ) | index: Position in the list to set the color color_object: The color object to set | Set a color at the specified index | | colors.buffer_setUint8(index, number ) | index: Position in the buffer to set the byte number: Byte value to set | Set a byte in the buffer | | colors.buffer_setUint32(index, number ) | index: Position in the buffer to set the Uint32 value number: Uint32 value to set | Set a Uint32 value in the buffer |

How it should be used (LOOK HERE)

var white = Color.new_of(255, 255, 255, 255);
var green = Color.new_of(0, 255, 0, 255);
var red = Color.new_of(255, 0, 0, 255);

var simdope_my_colors = Colors(imagedata);
    // That rewrite the inner data of our array but also white if we don't copy it
    simdope_my_colors.get_element(0).blend_with(white.copy(), 192, false, false);
    simdope_my_colors.get_element(1).blend_with(white, 0.25*255, false, false) ;

simdope_my_colors.get_element(2)
    .blend_with(white.copy(), 0.25*255, false, true)
    .blend_with(green.copy(), 0.75*255, false, true)
    .blend_with(red.copy(), 0.25*255, false, true)
    
var purple = simdope_my_colors.get_element(2);
var purple_copy = purple.copy();
var purple_hex = purple.hex;
var purple_uint32 = purple.uint32;
var is_purple_dark = purple.is_dark();
var is_purple_dark_but_from_hex = Color.new_hex(purple_hex).is_dark();
var purple_alpha_but_from_uint32 = Color.new_uint32(purple_uint32).a;

var some_uint32array_colors = simdope_my_colors.subarray_uint32(0, 3);
var some_colors = new Colors(some_uint32array_colors.buffer);

  some_colors.set_uint32_element(0, purple.uint32);
  some_colors.set_uint32_element(1, purple.uint32);

For more usage scenarios than those which follows, explore the source code.

  • You can write a quantization algorithm using it that can detect skin tones quickly and simplify millions of colors fast benefiting clustering using rgbaonXbits.
  • You can make a rendering engine which re-use Color's instance and link them through the tail property before blending them modifying the first one only as if you were using layers with a Colors' (list) + Color's (current) instance per layer.
  • You can simply detect which contrast color to use depending on a given color Color.new_hex("greenyellow").is_dark() ? "white": "black";.
  • You can sort colors within a palette using new Colors(colors.get_deduplicated_sorted_uint32a(200, Color.new_hex("white"), "lebesgue").buffer).get_properties("hex").

Please refer to the source code for additional information and advanced usage scenarios.

About me

"Philosophy is the science of estimating values, yet technology is the value of estimating science. My design is my voice while my code is my weapon of choice..."

I am (sometimes) open to work^^ ==> https://www.linkedin.com/in/matias-affolter/