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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@annotorious/plugin-boolean-operations

v0.4.0

Published

Adds functionality to merge and subtract annotation shapes

Readme

Annotorious Boolean Operations

Adds functionality to merge and subtract annotation shapes.

Demo

Important: This plugin currently only supports @annotorious/openseadragon. Support for plain (JPEG, PNG,...) images is not yet implemented. Join the discussion if you'd like to use this with @annotorious/annotorious or @annotorious/react.

Installation

npm install @annotorious/plugin-boolean-operations

Usage with OpenSeadragon

import OpenSeadragon from 'openseadragon';
import { createOSDAnnotator } from '@annotorious/openseadragon';
import { mountPlugin as mountBooleanPlugin  } from '@annotorious/plugin-boolean-operations';

import '@annotorious/openseadragon/annotorious-openseadragon.css';

/**
 * Important: the plugin requires multi-select to be enabled!
 */
const viewer = OpenSeadragon({
  /** Your viewer config **/
  multiSelect: true
});

const anno = createOSDAnnotator(viewer, { /* options */ });

// Initialize the plugin
const plugin = mountBooleanPlugin(anno);

// Merge example
document.getElementById('merge').addEventListener('click', () => {
  plugin.mergeSelected();
});

// Subtract example
document.getElementById('subtract').addEventListener('click', () => {
  plugin.subtractSelected();
});

API

| Method | Description | |--------|-------------| | canSubtractSelected() | Checks if the current selection allows subtraction (without producing an empty shape). | | mergeSelected(opts?: MergeOptions) | Merges all currently selected annotations. Accepts MergeOptions to control how annotation bodies are handled. | | subtractSelected() | Keeps the first selected annotation, clipping its geometry by subtracting all others. All other selected annotations are deleted. Selection order matters. |

MergeOptions

mergeSelected can be customized with a MergeOptions object that controls how annotation bodies are preserved in the merged shape.

You can either choose one of the built-in strategies or provide your own explicit override.

Built-in Strategies

  • { strategy: 'merge_bodies' } (default). Combine bodies from all selected shapes into the merged annotation, in the order of selection.
  • { strategy: 'keep_first_bodies' }. Keep only the bodies from the first selected annotation, discard all others.

Custom Merge

You can override the merge behavior by passing:

  • An explicit array of AnnotationBody objects to keep.
  • A function that receives the selected annotations and returns the bodies to keep.
// Keep specific bodies
plugin.mergeSelected({
  bodies: [myBody1, myBody2]
});

// Decide dynamically from the selection
plugin.mergeSelected({
  bodies: selected => selected.flatMap(a => a.bodies.filter(b => b.purpose === 'tagging'))
});