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

polygon-paper

v1.0.0

Published

`polygon-paper` ## Что делает: Даёт возможность нарисовать один или несколько полигонов на изображении и получить координаты их вершин и центра в виде JS-объектов. Центр можно двигать отдельно.

Downloads

2

Readme

Библиотека для разметки картинки полигонами

polygon-paper

Что делает:

Даёт возможность нарисовать один или несколько полигонов на изображении и получить координаты их вершин и центра в виде JS-объектов. Центр можно двигать отдельно.

Для чего:

Например, для внутренней разметки изображений. Чтобы красиво подсветить какие-то участки изображения и показать около них подсказку, сначала нужно знать, что именно нужно подсвечивать.

Как это выглядит

img

Цвета выбираются псевдослучайно, см. src/utils/polygonColorGenerator.ts

Установка и подключение

  1. Установить библиотеку: npm install polygon-paper
  2. Создать canvas-элемент на странице с заданными высотой и шириной: <canvas width="1000" height="1000" id="mycanvas" /> Canvas-элемент будет сжиматься по одной из сторон в зависимости от пропорций картинки. Например, если картинка имеет разрешение 500x200 (ширина x высота), canvas из примера выше уменьшится до 1000x400 - сохраняя оригинальную максимальную ширину, но уменьшая высоту, чтобы итоговый canvas был пропорционален картинке.
  3. Импортировать библиотеку: import { Draw } from 'polygon-paper'
  4. Создать экземпляр класса Draw и инициализировать его, передав в него ссылку на ранее созданный canvas и url картинки для разметки:
const draw = new Draw();
const canvasElement = document.getElementById("mycanvas");
const imageUrl = "https://resource.com/image-to-draw-on.png";

draw.init(canvasElement, imageUrl);

Опционально, в конструктор new Draw() можно передать объект с настройками, о нём в разделе API.

Опционально, в draw.init(canvasElement, imageUrl, initialPolygons) можно передать массив с полигонами (initialPolygons), которые надо отрисовать изначально (например, сохранённые ранее и загруженные в текущей сессии). О структуре полигонов, которые нужно передать, смотрите в разделе API.

  1. Для получения информации об изменении полигонов, установить коллбэк-функцию:
const myCallback = (newPolygonArray) => { doSomethingWithPolygons(newPolygonArray); }

draw.setOnChangeListener(myCallback);

Коллбэк вызывается каждый раз, когда создаётся/передвигается/удаляется один из полигонов или когда создаётся/передвигается/удаляется одна из вершин существущих полигонов, или же передвигается центральная точка одного из полигонов. Также коллбэк вызывается во время изменения payload полигона c помощью функции draw.setPolygonPayloadByIndex(index, payload) (об этом также в разделе API).

  1. Во время завершения работы библиотеки рекомендуется (но не обязательно) вызвать draw.destroy() - это удалит подписку на изменение полигонов и вернёт некоторые хендлеры дефолтного поведения элементу canvas.

API

Типы

Формат полигонов

interface IPoint {
    x: number;
    y: number;
}

**Важно: координаты точек относительны к размеру canvas**.
К примеру, точка, имеющая абсолютные координаты `{ x: 200, y: 300 }`, сгенерированная на canvas
размером `1000x500`, будет иметь координаты `{ x: 0.2, y: 0.6 }`, то есть, абсолютная координата будет
поделена на длину соответствующей ей стороны (`x` - на ширину, `y` - на высоту).

Такой подход позволяет устранить возможные проблемы, связаные с разрешением картинки: чтобы получить абсолютные координаты достаточно умножить относительные координаты на размеры картинки в конкретной интерфейсной реализации.

interface IPolygonWithCenter {
    points: IPoint[];
    center: IPoint;
    payload?: Record<string, any>;
    color?: string;
}

Объект настроек, которые передаются в конструктор new Draw(config):

interface IDrawConfig {
    // дистанция срабатывания клика на элементах
    // например, при перетаскивании вершины полигона,
    // это значение устанавливает насколько далеко от точного пикселя вершины
    // можно кликнуть, чтобы начать "тащить" эту вершину, а не
    // начать рисовать новый полигон
    pointerEventsTolerance: number;

    // прозрачность полигонов, от 0 до 1
    polygonTransparency: number;

    // радиус кружка-центра полигона
    // игнорируется при наличии текста в центре (см. centerPointLabelFormatter)
    draggableCenterCircleRadius: number;

    // на сколько будет увеличиваться изображение при зуме
    // например, 0.1 будет значить, что при зуме площадь изображения будет увеличиваться на 10%
    zoomFactor: number;

    // форматтер, который будет строить текст, который нужно отобразить в
    // центре полигона; 
    // текст строится из payload полигона;
    // в случае возвращения null из форматтера,
    // в центре будет отображён обычный кружок
    centerPointLabelFormatter: (polygonCenterGroupPayload: Record<string, unknown>) => string | null;

    // размер шрифта для текста, отображаемого в центре полигона
    centerPointLabelFontSize: number;

    // если true, то центры полигонов будут скрыты
    centerPointsHidden: boolean;

    // если true, то вызывает window.confirm перед удалением полигона
    // через delete или контекстное меню
    shouldConfirmPolygonDeletion: boolean;

    // текст при подтверждении удаления полигона
    labelDeletePolygonConfirm: string;

    // текст на кнопке удаления полигона в контекстном меню
    labelDeletePolygon: string;

    // текст на кнопке удаления вершины полигона в контекстном меню
    labelDeleteVertex: string;
}

Управление

Создание полигона

Для создания полигона с центром надо "накликать" по холсту как минимум три точки и соединить первую точку с последней.

Первый клик не должен попасть на уже существующий полигон, остальные могут.

Изменение полигона

  • Полигон можно перетащить целиком, drag-n-drop'нув его за тело
  • Можно перетащить отдельную вершину полигона
  • Добавить новую вершину полигона можно, кликнув на ребро (или сразу "тащить" новую точку из ребра)
  • Удалить вершину можно, кликнув по ней с зажатым shift, либо через ПКМ-клик для открытия контекстного меню и пункт "Удалить вершину" в нём

Удаление полигона

  • Выделить полигон, кликнув на его тело и нажать delete
  • Или ПКМ-клик по телу полигона для открытия контекстного меню и "Удалить полигон"
  • Или извне через публичный метод deletePolygonByIndex

Публичные методы Draw

init

draw.init(canvas: HTMLCanvasElement, imgUrl: string, initialPolygons: IPolygonWithCenter[]): void

Инициализация библиотеки: загрузка картинки, изменение пропорций canvas'a, подключение внутренних обработчиков. Поле color в объектах initialPolygons игнорируется, библиотека выбирает цвет по внутреннему алгоритму.

destroy

draw.destroy(): void

Удаление overwrite'ов дефолтных поведений canvas'а, удаление коллбэка, установленного с помощью setOnChangeListener.

setOnChangeListener

draw.setOnChangeListener(null | (newPolygons: IPolygonWithCenter[]) => void): void

Добавление или изменение листенера изменений в полигонах.

highlightPolygonByIndex

draw.highlightPolygonByIndex(index: number): void

"Подсветить" полигон белым цветом для быстрого нахождения. Сбрасывает подсветку ранее подсвеченых полигонов. Может использоваться, например, для подсветки полигона на canvas'e при ховере по внешнему элементу.

unhighlightPolygons

draw.unhighlightPolygons(): void

Убрать подсветку со всех полигонов.

deletePolygonByIndex

draw.deletePolygonByIndex(index: number): void

Удалить полигон по индексу извне библиотеки. Индекс консистентен с массивом, возвращаемым в коллбэк из setOnChangeListener.

setPolygonPayloadByIndex

draw.setPolygonPayloadByIndex(index: number, payload: null | Record<string, unknown>): void

Установить payload полигону. При вызове этой функции, в коллбэк из setOnChangeListener бросается событие. payload может быть любым key-value объектом.

setConfigField

draw.setConfigField<T extends keyof IDrawConfig>(field: T, fieldValue: IDrawConfig[T]);

Установить поле конфига и перерисовать канвас с учётом обновлённого поля.

setConfig

draw.setConfig(field: Partial<IDrawConfig>);

Установить новый объект конфига (если какие-то из полей отсутствуют в новом конфиге, они будут взяты из прежнего) и перерисовать канвас с учётом нового конфига.

Ограничения

Размер минифицированного кода библиотеки - 368 KB. Подумайте перед тем, как затаскивать это в сервис, для которого скорость критична.

Ожидаются проблемы с работой библиотеки в условиях, когда на одной странице должно быть несколько "рисовалок". В коде используется глобальный скоуп paperjs, автоматически привязываемый к текущему canvas'у. Это может быть исправлено при необходимости.