All notable changes to this project will be documented here.
- Add
get_keypoint_slider_value()public API method to get the current keypoint slider value (0-1). - Add
get_distance_filter_value()public API method to get the current distance filter slider values.
- Fix bug where multiple spaces in a submit button name would cause the button hook to not fire.
- Fix export of typescript types
- Add
ULabel.get_resize_toolbox_item()static method to get theAnnotationResizeItemclass, which has static methods that allow for programmatic control of annotation size for subtasks.
- Add vertex deletion keybind for polygon and polyline annotations
- New configurable
delete_vertex_keybind(default:x) - Delete individual vertices by hovering over them and pressing the keybind
- Automatically deletes entire polyline if only 1 point remains after deletion
- Automatically removes polygon layer if fewer than 3 points remain after deletion
- New configurable
- Fixed bug where deleting an annotation mid-edit would cause the ULabel state to be stuck in edit mode.
- Don't draw annotations when a subtask is vanished
- Add configurable
annotation_vanish_all_keybind - Track annotation size per subtask
- Remove annotation size cookie, since it was tracking just one size per annotation session
- Deprecated the
default_annotation_sizeargument in the configuration object. Use theinitial_line_sizeargument instead. See api_spec.md for details. - Fix toolbox collapse arrow positioning, and make frame annotation dialogs disappear on collapse
- Removed the
line_sizeproperty from annotation objects.subtask.state.line_sizedetermined the size of drawn annotations within a subtask.
- Add collapsible toolbox with arrow button at top
- Toolbox collapse state persists in browser
- Annotation canvas expands to fill space when toolbox is collapsed
- Add
Keybindstoolbox item for viewing and customizing keybinds- Display all configurable keybinds with labels and descriptions
- Edit keybinds by clicking and pressing new key combination
- Support for modifier key chords (shift, ctrl, alt, meta)
- Collision detection with red highlighting for duplicate keybinds
- Reset individual keybinds or all keybinds to defaults
- Visual indicator (yellow highlight) for user-customized keybinds
- User keybind settings persist in browser
- Rename
create_bbox_on_initial_croptocreate_bbox_on_initial_crop_keybindfor consistency - Split
change_zoom_keybindinto two separate keybinds:reset_zoom_keybind(default:r) - Reset zoom to fit imageshow_full_image_keybind(default:shift+r) - Zoom to show full image
- Store collapse/expand state for Keybinds, Annotation List, and Image Filters toolbox items
- Add comprehensive e2e tests for keybind functionality and keybind toolbox item
- Add toast notification that shows on
fly_tocalls and shows annotation position in the ordering (e.g., "3 / 10") - Add
AnnotationListtoolbox item for managing and navigating annotations- Displays all annotations in a scrollable list with spatial type icons and class names
- Bidirectional hover highlighting between list and canvas
- Filter options:
- Toggle show/hide deprecated annotations (default: hidden)
- Group annotations by class
- Collapsible interface to maximize toolbox space
- Add automated package deployment via GHA
- Add
fly-tofunctions, which sets the zoom and focus to a specific annotationfly_to_next_annotation()fly_to_annotation_id()fly_to_annotation()
- Add
TabandTab+Shiftdefault keybinds to fly-to the next/previous annotation, respectively- Keybinds are configurable:
fly_to_next_annotation_keybindfly_to_previous_annotation_keybind
- Keybinds are configurable:
- Add
ImageFilterstoolbox item to expose sliders for the following image css filters:- brightness
- contrast
- hue rotate
- invert
- saturate
- Removed redundant dependencies that were being unnecessarily installed by users using npm to install ulabel
- Updated webpack build process to properly provide both a minified (default) and unminified build (for better debugging)
- Added package
exportsfield with options:.(minified),./min(minified),./debug(unminified)
- Added package
- Add test coverage for both minified and unminified builds
- Update dependencies and fix 12 security vulnerabilities
- Add automated testing to the repo
- Fix circular webpack builds by forcibly cleaning the
dist/directory before each build- Also use
import type... from ".."instead of justimportto fix ts not properly resolving imports to js - Reduced bundle size from ~20 MB -> 1 MB
- Also use
- Refactor some more
console.warnandconsole.errorinstances to uselog_message - Remove deprecated
parent_idfield fromULabelAnnotation
- Add minimal lineage tracking via
last_edited_byandlast_edited_atannotation fields - Prevent creation of zero-length polylines
- Fixed
process_resume_fromnot actually populating missing annotation fields on load - Misc bug/QOL fixes
- Simplified/fixed non-spatial annotation creation/deletion
- Replaced
alert,throw, andconsolecalls withlog_message() - Cleanup of
suggest_edits()and other functions related to toggling dialogs - Refactor action stream management and undo/redo flow into
actions.ts- Move a lot of repeated rendering/cleanup steps after actions into general action listeners that trigger on similar actions
- Move
annotation_idout of undo/redo payloads and into the action itself
- Fix special characters in submit buttons breaking tool
- Fix "Annotation ID" text color in night mode
- add
allow_annotations_outside_imagearg to theULabelconstructor, which defaults totrue.- when set to
false, new annotations will be limited to points within the image, and attempts to move annotations outside the image will bounce back.
- when set to
- Add
anno_scaling_modeargument to theULabelconstructor, which allows users to specify how the size of annotations should be scaled when the zoom level is changed.- Options are
fixed,match-zoom, andinverse-zoom. - When set to
fixed, the line size of annotations will remain constant regardless of zoom level. - When set to
match-zoom, the line size of annotations will increase with increased zoom level. - When set to
inverse-zoom, the line size of annotations will decrease with increased zoom level.
- Options are
- Prior behavior is equivalent to
anno_scaling_mode = "fixed". - Fix bug where fully erased polygon annotations would cause the an error upon submit.
- Fix bug where empty polygon layers could be included in a
submit_buttonhook payload.
- Fix bug where the
Vanishbutton wouldn't update itslockedstate when switching between subtasks. - Fix bug where clicking the
Vanishbutton would unexpectedly set the size cookie, causing future annotations in the same subtask to be loaded in a very small size on subsequent sessions, with the only way to recover being to increase the annotation size.
- Fixed bug introduced in v0.15.0 where using the erase tool such that a polygon was separated into multiple disjoint regions would cause an unrecoverable error.
- Added
click_and_drag_poly_annotationsflag to the configuration object, that when set to false prevents continuous points from being added to a polyline or polygon annotations when clicking and dragging.
- Added loading overlay with spinning icon while ULabel is initializing
- Moved several existing utilties (mostly static methods) to isolated files:
- Event listener management to
listeners.ts - Night mode cookie to
cookies.ts - Logging to
error_logging.ts - Canvas initialization to
canvas_utils.ts - Initialization logic (vastly simplified) to
initializer.ts
- Event listener management to
- Changed
after_initto be an instance function - Removed
load_image_promisein favor of.decode() - Added many new entries in
index.d.ts
- Fix issue where legacy submit button functionality would break loading
- Change
set_savedon submit buttons to be a true boolean, rather than an optional boolean that could needlessly force a reload prompt
- Change deprecation cases to use dedicated
mark_deprecatedfunction
- Added ESLint to enforce code quality and consistency
- Add a
brush-button-activeCSS class to the "brush" and "erase" buttons that visually depicts when the brush or erase tool is active
- Add
.get_current_subtask_key()and.get_current_subtask()utility methods- Updated almost all internal methods to use these utility methods
- Remove unecessary and confusing default in global edit dialog
- Squash
active_annotationintoedit_candidatein subtask state - Fix missing fields in
ULabelSubtask.state.edit_candidate
- Fix bug where the
filter_annotations_on_load = trueoption would not work as expected.- The
keypoint_slider_default_valueoption was not being properly multiplied by 100 internally.
- The
- Move several config argument defaults into the configuration class instead of in the ULabel constructor.
- Add
get_allowed_toolbox_item_enum()static method to ULabel.
- Changed default for
filter_annotations_on_loadfromfalsetotrue. - Deprecated the
default_toolbox_item_orderargument in the ULabel constructor. Usetoolbox_orderinstead. - Deprecated
config_dataargument in the ULabel constructor. Instead, pass all configuration options as keyword arguments directly to the ULabel constructor.- For now, the
config_dataargument will still work, but may be removed in a future release.
- For now, the
- Fix release workflow using actions on
node16, which is now deprecated.
- Prevent default mouseup event when listening for the end to a drag event.
- Multiple publishes are from testing in a netlify app.
- Improvements to performance of the
FilterDistanceToolbox item:- Switch to new redrawing util functions and only redraw annotations when necessary
- Greatly reduce the number of distance calculations by only calculating distances for the newly modified annotation (polyline or point), rather than recalculating all distances for all annotations everytime.
- Each point now tracks the
idof the closest line in each class to further reduce the number of redundant calculations.
- Improvements to performance of the
KeypointSliderToolbox item:- Switch to new redrawing util functions and only redraw annotations when necessary
- Fix bug where
deletemodes and theFilterDistancetoolbox item would clash. - Expose
n_annos_per_canvasarg toconfig_dataas an advanced feature for performance tuning.- Also added some dynamic scaling of this value based on the max number of annotations in a single subtask if no value is provided by the user.
- Added
disable_multi_class_modeflag toFilterDistanceConfig, which defaults tofalse. Whentrue, the multi-class mode will be disabled and the checkbox will not be shown. - Added
filter_during_polyline_moveflag toFilterDistanceConfig, which defaults totrue. Whenfalse, the filter/overlay will not be updated until polyline moves/edits are completed. This can be useful for boosting performance when working with many annotations.- This option is also present as a checkbox option in the
FilterDistancetoolbox item.
- This option is also present as a checkbox option in the
- Renamed
FilterDistanceConfigargshow_overlay_on_load->show_overlayfor internal consistency. - Changed format of
default_valuesarg inFilterDistanceConfig. The name for the single class mode default has changed from"single"->"closest_row", and each entry in the object should be aDistanceFromPolylineobject ({distance: <number>}), rather than a single number. See the updatedapi_spec.mdfor more details. KeypointSlidernow works on all points in every subtask, even when the subtask is not active.- Deprecated the
newandis_newfields inULabelAnnotation. There was internal inconsistency in their use, and some internal logic that depended on them was buggy and was sometimes preventing theFilterDistanceslider from working as expected.
- Fix bug where class counts wouldn't update when changing subtasks.
- Add
size_factorarg to submit buttons to allow for custom sizing. - Add
row_numberarg to submit buttons to allow for grouping buttons into rows.
- Update
api_spec.mdindicating thatpolylineis no longer "under construction" - Correct a few typos where
init_cropshould beinitial_crop - Correct typo where
filter_low_confidence_default_valueshould bekeypoint_slider_default_value
- Catch a couple event listeners that were not being removed by
remove_listeners(). - Suppress rare error from
handle_toolbox_overflow().
- Correctly update class counter after calling
set_annotations().
- Fix bug where very rarely, certain polygon annotations created outside of ULabel would cause ULabel to fail when processing resume_from.
- Fix various bugs relating to the annotation count not updating as expected.
- Fix broken undo/redo behavior for polygons.
- General improvements aimed at reducing memory usage and improving performance.
- Fix bug where using the
toggle_annotation_mode_keybindto switch to/from a delete mode would unexpectedly change the class of the hovered annotation. - Fix bug where pressing a class keybind when using a delete mode would deselect the delete class.
- Fix bug where using
set_annotations()with multiple subtasks would fail.
- Fix bug where using
Escapeto cancel delete modes would sometimes create unexpected annotations - Fix bug where undoing a cancelation of a delete mode did not allow for continuing with the delete mode annotation
- Fix bug where confidence dialog didn't update properly.
- Fix bug introduced in 0.10.3 where dialogs don't show up for points annotations.
- Create method to remove all ULabel event listeners. This is handy for single page applications when the page is not reloaded after navigating away from a ULabel page.
- Fix bug where hovering over an id dialog would set the class, instead of waiting for a click.
- Fix bug where using the brush tool on an existing annotation would unexpectedly change its class.
- Fix bug where clicking a class' keybind when hovering over an annotation would not update the annotation's class if the new class was already selected in the toolbox.
- Fix very rare case where
deletemodes were being exported on submit. - Changing id of a hovered annotation via the id dialog will no longer also change the active toolbox class id.
- Enable the
"change_zoom_keybind"to function even when theZoomPanToolboxItemisn't present. - Fix bug where using "
set_annotations" would cause some loaded annotations to not generate edit dialogs. - Fix bug where clicking the
Annotation IDtoolbox item would not update the brush color.
- Fix bug introduced in 0.10.5 that caused non-polygon annotations not to load.
- Fix bug where annotations could be saved with empty spatial payloads, which would cause an error when loading the annotations.
- Change polygon ender icon to be smaller, partially transparent, and scaled with zoom.
- Color polygon ender and the brush circle based on the active class color.
- Fix bug where hitting the middle mouse button would sometimes open a new tab.
- Improvements to hitboxes for polygons, points, and bboxes. The cursor must now actually be inside the annotation before showing the edit dialogs.
- Fix duplicate keybinds for increase/decrease of line size and brush size
[and]now decrement/increment brush sizealt+scrollstill decrements/increments brush size-and=still decrements/increments line size
- Fix bug where using the erase tool to completely erase a polygon would sometimes cause an error.
- Fix npm publishing error from 0.10.1
- Add optional
keybindargument for each class in theclassesarray to allow for custom keybinds for each class. - Double the zoom sensitivity
- Change the default scroll wheel behavior to zoom in/out on the cursor location instead of scroll up/down.
- When frames are present,
ctrl+scrollorshift+scrollorcmd+scrollwill now scroll through the frames.
- When frames are present,
- Fix
create_bbox_on_initial_cropto only work when inbboxmode, and make it start as the active class. - Fix longstanding bug where the
Annotation IDtoolbox item would not update the annotation ID unless explicitly clicked. - Fix bug where panning during brush mode would open a new tab.
- Fix bug where panning was disabled when actively drawing an annotation
- Fix rare bug where undoing an annotation would cause future annotations to never finish.
- Fix bug where vanish mode was disabled during brush/erase mode
- Align
undobehavior for polygons and polylines with that of other annotations (once complete, the undo will delete the entire annotation rather than undoing only the last point) Escapekeybind to cancel an in-progress annotation
- Fix bug where erase mode could perist when changing annotation mode
- When user provides an
initial_line_size, use that as the default size for new annotations, independent of zoom- When this argument is not provided, the behavior is unchanged from before (the size of new annotations will still scale with the zoom level).
- Fix bug where the
DELETE_CLASS_IDwould show up as an option in the id dialog for polygons and bounding boxes
- Small fixes to
submit_buttonsin the toolbox.- Added optional
set_savedargument for eachsubmit_buttonto allow for the page to unload without warning if the button is clicked. - Changed default button css to better center the text.
- Added optional
- Refactor of how annotations are drawn on the canvas. This change should make the drawing of annotations more efficient and less prone to lagging, especially when working with a large number of annotations or annotations with many vertices.
- Minor improvements to how
resume_fromerrors are handled in the case of incorreclty formattedpolygonannotations.
Added DELETE_MODES = ["delete_polygon", "delete_bbox"], additional annotation modes for deleting annotations by drawing a polygon or bounding box around them.
"delete_polygon": Allows drawing a polygon around an area, and all annotations within that area will be deleted"delete_bbox": Allows drawing a bounding box around an area, and all annotations within that area will be deleted
Added a brush/erase tool for working with polygon annotations.
- Press
gto toggle brush mode. This refers to a state in which click-dragging will place (or erase, if in erase mode) a circle at the cursor location to either augment an existing polygon or create a new one. - Press
eto toggle erase mode (indicated by the color of the brush circle: red for erase). When click-dragging in erase mode, the area in a circle around the cursor will be removed from an existing polygon. Can be used to create holes, isolated fills, or even delete annotations. - Press
=while in brush mode to increment the brush circle size by 10% - Press
-while in brush mode to decrement the brush circle size by 10% - Hold
Altand scroll while in brush mode to increment/decrement the brush circle size - Press
Escapewhile in brush mode to exit brush mode and return to normal annotation mode - Also added a
BrushToolboxItemwith buttons to perform the same function as the configurable keybinds listed above.
- Added click-and-drag functionality when drawing polygons or polylines.
- Changed polygon representation from that of a simple polygon to a complex polygon. This allows for polygons to contain holes and/or multiple disjoint regions.
- Hold
shiftwhen closing a polygon to continue annotating a new region or hole. - Hold
shiftwhen moving the cursor inside a polygon to begin annotating a new region or hole. - Press
Escapeorcrtl+zto cancel the start of a new region or hole. - Added fill to polygons by default, excluding any holes in the polygon.
- Added check to ensure that deprecated simple polygons are auto converted to complex polygons when loaded by ULabel.
- Fix class ID sort order requirement.
- Added the "Tag It" github job which will automatically tag the git version after a pr into main.
- Fixed the package entrypoints in
package.jsonto point to the correct files. This should fix the issue where the package was not being imported correctly.
- Fixed a bug that prevented custom submit buttons from being used with the legacy constructor arguments.
- Reworked the overlay rendering logic.
- Results in no longer having "infinite" zoom, but zooming should take no longer than ~2ms per operation instead of the >600ms it was previously taking.
- Also fixed a bug that caused ULabel to rerender the page on any keypress.
- Updated ULabel's constructor to use keyword arguments instead of 11 arguments that must be passed in in the correct order.
- This was frustrating because most default arguments use their default option and JavaScript doesn't allow you to ommit optional arguments if you want to modify a later argument.
- Added
utilities.tsto contain miscellaneous helper functions. - Added
is_object_and_not_arraytoutilities.tsto help check if something is an object and neither null nor an array.
- Added multi-class support for the
FilterPointDistanceFromRowToolboxItem. - Added an overlay for the
FilterPointDistanceFromRowToolboxItemthat shows the range of the filter. - Added a helper class
SliderHandlerto help with creation of new sliders and their event listeners.
- Added helper function
apply_gradient_maththat reduces duplicated code fromapply_gradient.
- Added the
FilterPointDistanceFromRowToolboxItem.
- Massive update with lots of under the hood changes.
- Added a toolbox item for changing annotation color.
- Added a toolbox item for changing annotation size.
- Added a toolbox item for filtering out annotations based on annotation confidence.
- Added support for adding diffrent Submit buttons, such as a Reject button or Failure button.
- Added a display for annotation's confidence on hover.
- Added keybinds for most operations.
- Fixed an issue with setting annotations at the frame/global level.
- bugfix in
resume_fromprocessing
- bugfix in
resume_fromprocessing
- added checks to ensure
resume_fromobject is compatible
- Provides an example of how users can be requested to annotate just a window within an image
- Has better support for zooming into that region in the image
- Added a button to "re-center" on the initial crop that was provided
- Fixed security vulnerability
- Fixed security vulnerability
- ULabel now allows for classification payloads without items for certain classes, and just assumes that omitted classes have a confidence of zero
- Fixed issue with detecting undo/redo on Firefox and Mac
- Detected
shift+scrollfor zooming as well ascmd/ctrl+scroll - Fixed small issue with
beforeunloadwarning
- Allow submission when page first loads without having to make an edit first
- Call
on_submitasynchronouly using await, and show loader until it finishes
- Added support for
polylineannotation mode - Added basic typescript typings
- Fixed the main property in package.json so it points to a valid file. Also added the module field which points to the es6 module at the src folder
- Moved express to the dev-dependencies because users of this module do not need to install express for the frontend only component
- Exported the ULabel class in the module
- Added the
pointannotation mode - Added support for a link to instructions
- Added a
set_saved()function so page can unload without warning - Bound ulabel instance to submit callback so above function can be easily called
- Bugfix for resuming from nonspatial annotations
- Created interface for
getandsetto allow for custom annotation processing - Changed to more inclusive keyboard event handling
- Added a function to swap background color for the annotation box
- Added generic callback support
- Added initial line size to the constructor
- Made cursor represent line size and color to be drawn
- Fixed incorrect links to repo from within package.json
- Now keeping track of whether edited since last save, and shows warning before unload if so
- Callback is to return
falseif save is unsuccessful
- Callback is to return
- Removed a console debugging message that I forgot to remove for 0.4.4
- Fixed bug with "resuming from" in sessions with a single frame
- Fixed bug with
initcallback not getting called
- Added a changelog :)
- Added changelog entry to pull request checklist
- Fixed silent errors in src found by eslint
- Fixed shortcut suggestion for switching frames
- Fixed link to ulabel repo
- Added ctrl+s listener and attached it to the submit button
- Added option for inactive opacity to be configured for each subtask
- Added contructor parameter to start annotation session with image cropped to a specific bounding box
- Updated CSS rules to prevent unintuitive occlusion by global edit suggestion