Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/loader #190

Merged
merged 20 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dist/ulabel.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/ulabel.min.js

Large diffs are not rendered by default.

14 changes: 11 additions & 3 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ export class ULabel {
valid_class_ids: number[];
toolbox_order?: number[];
filter_distance_overlay?: FilterDistanceOverlay;
begining_time: number;
is_init: boolean;
resize_observers: ResizeObserver[];
/**
* @link https://github.com/SenteraLLC/ulabel/blob/main/api_spec.md#ulabel-constructor
Expand All @@ -219,6 +221,7 @@ export class ULabel {
* @link https://github.com/SenteraLLC/ulabel/blob/main/api_spec.md#display-utility-functions
*/
public init(callback: () => void): void;
public after_init(): void;
public show_initial_crop(): void;
public show_whole_image(): void;
public swap_frame_image(new_src: string, frame?: number): string;
Expand All @@ -244,7 +247,6 @@ export class ULabel {
public show_annotation_mode(
target_jq?: JQuery<HTMLElement>, // TODO (joshua-dean): validate this type
);
public rezoom(): void;
public update_frame(delta?: number, new_frame?: number): void;
public handle_id_dialog_hover(
mouse_event: JQuery.TriggeredEvent,
Expand All @@ -266,8 +268,14 @@ export class ULabel {
// Listeners
public remove_listeners(): void;
static get_allowed_toolbox_item_enum(): AllowedToolboxItem;
static process_classes(ulabel_obj: ULabel, arg1: string, subtask_obj: ULabelSubtask);
static build_id_dialogs(ulabel_obj: ULabel);
static process_classes(ulabel_obj: ULabel, arg1: string, subtask_obj: ULabelSubtask): void;
static build_id_dialogs(ulabel_obj: ULabel): void;

// Instance init functions
public create_overlays(): void;

// nops
TrevorBurgoyne marked this conversation as resolved.
Show resolved Hide resolved
public redraw_demo(): void;

// Annotation lifecycle
// TODO (joshua-dean): type for redo_payload
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/annotation_operators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export function mark_deprecated(
annotation.deprecated_by[deprecated_by_key] = deprecated;

// If the annotation has been deprecated by any method, then deprecate the annotation
if (Object.values(annotation.deprecated_by).some(x => x)) {
if (Object.values(annotation.deprecated_by).some((x) => x)) {
annotation.deprecated = true;
return;
}
Expand Down
2 changes: 1 addition & 1 deletion src/canvas_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function dynamically_set_n_annos_per_canvas(
if (config.n_annos_per_canvas === DEFAULT_N_ANNOS_PER_CANVAS) {
// Count max annotations per subtask
const max_annos = Math.max(
...Object.values(subtasks).map(subtask => subtask.annotations.ordering.length),
...Object.values(subtasks).map((subtask) => subtask.annotations.ordering.length),
);

// Performance starts to deteriorate when we require many canvases to be drawn on
Expand Down
2 changes: 1 addition & 1 deletion src/cookies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export abstract class NightModeCookie {
public static exists_in_document(): boolean {
const cookie_components = document.cookie.split(";");
const night_mode_comp = cookie_components.find(
row => row.trim().startsWith(`${NightModeCookie.COOKIE_NAME}=true`),
(row) => row.trim().startsWith(`${NightModeCookie.COOKIE_NAME}=true`),
);
return night_mode_comp !== undefined;
}
Expand Down
3 changes: 3 additions & 0 deletions src/html_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
GLOBAL_SVG,
get_init_style,
} from "../src/blobs";
import { ULabelLoader } from "./loader";
import { log_message, LogLevel } from "./error_logging";

/**
Expand Down Expand Up @@ -158,6 +159,8 @@ export function prep_window_html(ulabel: ULabel, toolbox_item_order: unknown[] =

// Set the container's html to the toolbox html we just created
$("#" + ulabel.config["container_id"]).html(tool_html);
const container = document.getElementById(ulabel.config["container_id"]);
ULabelLoader.add_loader_div(container);

// Build toolbox for the current subtask only
const current_subtask: string = Object.keys(ulabel.subtasks)[0];
Expand Down
136 changes: 12 additions & 124 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,8 @@ import {
mark_deprecated,
update_distance_from_line_to_each_point,
} from "../build/annotation_operators";
import {
add_style_to_document,
prep_window_html,
build_id_dialogs,
build_edit_suggestion,
build_confidence_dialog,
} from "../build/html_builder";

import { create_ulabel_listeners, remove_ulabel_listeners } from "../build/listeners";
import { NightModeCookie } from "../build/cookies";

import { remove_ulabel_listeners } from "../build/listeners";
import { log_message, LogLevel } from "../build/error_logging";
import { initialize_annotation_canvases } from "../build/canvas_utils";

Expand All @@ -56,6 +48,7 @@ import {
} from "./blobs";
import { ULABEL_VERSION } from "./version";
import { BrushToolboxItem } from "../build/toolbox";
import { ulabel_init } from "../build/initializer";

jQuery.fn.outer_html = function () {
return jQuery("<div />").append(this.eq(0).clone()).html();
Expand Down Expand Up @@ -235,7 +228,7 @@ export class ULabel {
}

// If the subtask has any DELETE_MODE enabled, add a class definition for it
if (subtask.allowed_modes.some(mode => DELETE_MODES.includes(mode))) {
if (subtask.allowed_modes.some((mode) => DELETE_MODES.includes(mode))) {
subtask.class_defs.push({
name: "Delete",
id: DELETE_CLASS_ID,
Expand Down Expand Up @@ -331,8 +324,8 @@ export class ULabel {
cand["classification_payloads"].sort(
(a, b) => {
return (
ul.subtasks[subtask_key]["class_ids"].find(e => e === a["class_id"]) -
ul.subtasks[subtask_key]["class_ids"].find(e => e === b["class_id"])
ul.subtasks[subtask_key]["class_ids"].find((e) => e === a["class_id"]) -
ul.subtasks[subtask_key]["class_ids"].find((e) => e === b["class_id"])
);
},
);
Expand Down Expand Up @@ -636,112 +629,7 @@ export class ULabel {
}

init(callback) {
// Add stylesheet
add_style_to_document(this);

// TODO (joshua-dean): Make this follow the rule
// https://typescript-eslint.io/rules/no-this-alias/
// eslint-disable-next-line @typescript-eslint/no-this-alias
let that = this;
that.state["current_subtask"] = Object.keys(that.subtasks)[0];

// Place image element
prep_window_html(this, this.config.toolbox_order);

// Detect night cookie
if (NightModeCookie.exists_in_document()) {
$("#" + this.config["container_id"]).addClass("ulabel-night");
}

let first_bg_img = document.getElementById(`${this.config["image_id_pfx"]}__0`);
first_bg_img.decode().then(() => {
// Store image dimensions
that.config["image_height"] = first_bg_img.naturalHeight;
that.config["image_width"] = first_bg_img.naturalWidth;

// Add canvasses for each subtask and get their rendering contexts
for (const st in that.subtasks) {
$("#" + that.config["imwrap_id"]).append(`
<div id="canvasses__${st}" class="canvasses">
<canvas
id="${that.subtasks[st]["canvas_bid"]}"
class="${that.config["canvas_class"]} ${that.config["imgsz_class"]} canvas_cls"
height=${that.config["image_height"] * this.config["px_per_px"]}
width=${that.config["image_width"] * this.config["px_per_px"]}></canvas>
<canvas
id="${that.subtasks[st]["canvas_fid"]}"
class="${that.config["canvas_class"]} ${that.config["imgsz_class"]} canvas_cls"
height=${that.config["image_height"] * this.config["px_per_px"]}
width=${that.config["image_width"] * this.config["px_per_px"]}
oncontextmenu="return false"></canvas>
<div id="dialogs__${st}" class="dialogs_container"></div>
</div>
`);
$("#" + that.config["container_id"] + ` div#fad_st__${st}`).append(`
<div id="front_dialogs__${st}" class="front_dialogs"></div>
`);

// Get canvas contexts
that.subtasks[st]["state"]["back_context"] = document.getElementById(
that.subtasks[st]["canvas_bid"],
).getContext("2d");
that.subtasks[st]["state"]["front_context"] = document.getElementById(
that.subtasks[st]["canvas_fid"],
).getContext("2d");
}

// Create the annotation canvases for the resume_from annotations
initialize_annotation_canvases(that);

// Add the ID dialogs' HTML to the document
build_id_dialogs(that);

// Add the HTML for the edit suggestion to the window
build_edit_suggestion(that);

// Add dialog to show annotation confidence
build_confidence_dialog(that);

// Create listers to manipulate and export this object
create_ulabel_listeners(that);

that.handle_toolbox_overflow();

// Set the canvas elements in the correct stacking order given current subtask
that.set_subtask(that.get_current_subtask_key());

that.create_overlays();

// Indicate that the object is now init!
that.is_init = true;
$(`div#${this.config["container_id"]}`).css("display", "block");

this.show_initial_crop();
this.update_frame();

// Draw demo annotation
that.redraw_demo();

// Draw resumed from annotations
that.redraw_all_annotations();

// Update class counter
that.toolbox.redraw_update_items(that);

// Call the user-provided callback
callback();
}).catch((err) => {
console.log(err);
log_message(
"Failed to load images: " + JSON.stringify(err),
LogLevel.ERROR,
);
});

// Final code to be called after the object is initialized
this.after_init();

console.log(`Time taken to construct and initialize: ${Date.now() - this.begining_time}`);
ulabel_init(this, callback);
}

/**
Expand Down Expand Up @@ -989,7 +877,7 @@ export class ULabel {
*/
switch_to_next_subtask() {
let current_subtask = this.get_current_subtask_key();
let new_subtask_index = this.toolbox.tabs.findIndex(tab => tab.subtask_key === current_subtask) + 1;
let new_subtask_index = this.toolbox.tabs.findIndex((tab) => tab.subtask_key === current_subtask) + 1;
// If the current subtask was the last one in the array, then
// loop around to the first subtask
if (new_subtask_index === this.toolbox.tabs.length) {
Expand Down Expand Up @@ -1086,7 +974,7 @@ export class ULabel {
update_filter_distance_during_polyline_move(annotation_id, redraw_update_items = true, force_filter_all = false, offset = null) {
if (
this.config.toolbox_order.includes(AllowedToolboxItem.FilterDistance) &&
this.toolbox.items.find(item => item.get_toolbox_item_type() === "FilterDistance").filter_during_polyline_move
this.toolbox.items.find((item) => item.get_toolbox_item_type() === "FilterDistance").filter_during_polyline_move
) {
this.update_filter_distance(annotation_id, redraw_update_items, force_filter_all, offset);
}
Expand Down Expand Up @@ -2780,7 +2668,7 @@ export class ULabel {
// Remove the delete annotation from access and ordering, and delete its canvas context
this.destroy_annotation_context(delete_annid);
delete this.get_current_subtask()["annotations"]["access"][delete_annid];
this.get_current_subtask()["annotations"]["ordering"] = this.get_current_subtask()["annotations"]["ordering"].filter(value => value !== delete_annid);
this.get_current_subtask()["annotations"]["ordering"] = this.get_current_subtask()["annotations"]["ordering"].filter((value) => value !== delete_annid);
this.remove_recorded_events_for_annotation(delete_annid);
}
}
Expand Down Expand Up @@ -3920,7 +3808,7 @@ export class ULabel {
this.destroy_annotation_context(unq_id);

// Remove from ordering
current_subtask["annotations"]["ordering"] = current_subtask["annotations"]["ordering"].filter(id => id !== unq_id);
current_subtask["annotations"]["ordering"] = current_subtask["annotations"]["ordering"].filter((id) => id !== unq_id);

// Remove from access
delete current_subtask["annotations"]["access"][unq_id];
Expand Down Expand Up @@ -5755,7 +5643,7 @@ export class ULabel {
// Check if the FilterDistance ToolboxItem is in this ULabel instance
if (this.config.toolbox_order.includes(AllowedToolboxItem.FilterDistance)) {
// Get the toolbox item
const filter_distance_toolbox_item = this.toolbox.items.filter(item => item.get_toolbox_item_type() === "FilterDistance")[0];
const filter_distance_toolbox_item = this.toolbox.items.filter((item) => item.get_toolbox_item_type() === "FilterDistance")[0];
// filter annotations if in multi_class_mode
if (filter_distance_toolbox_item.multi_class_mode) {
filter_points_distance_from_line(this, true);
Expand Down
Loading
Loading