Various changes to I/O handling (#2513)
* Store coordinates as ratios of full size
* Use single definition for cappedCanvasSize()
* Move I/O review code into ts/image-occlusion
A bit simpler when it's all in one place.
* Reduce number precision, and round to whole pixels
>>> n=10000
>>> for i in range(1, int(n)): assert i == round(float("%0.4f" % (i/n))*n)
* Minor typing tweak
So, it turns out that typing is mostly broken in ts/image-occlusion.
We're importing from fabric which is a js file without types, so types
like fabric.Canvas are resolving to any.
I first tried switching to `@types/fabric`, which introduced a slew of
typing errors. Wasted a few hours trying to address them, before deciding
to give up on it, since the types were not complete. Then found fabric
has a 6.0 beta that introduces typing, and spent some time with that, but
ran into some new issues as it still seems to be a work in progress.
I think we're probably best off waiting until it's out and stabilized
before sinking more effort into this.
* Refactor (de)serialization of occlusions
To make the code easier to follow/maintain, cloze deletions are now decoded/
encoded into simple data classes, which can then be converted to Fabric objects
and back. The data objects handle converting from absolute/normal positions, and
producing values suitable for writing to text (eg truncated floats).
Various other changes:
- Polygon points are now stored as 'x,y x2,y2 ...' instead of JSON in cloze
divs, as that makes the handling consistent with reading from cloze deletion
text.
- Fixed the reviewer not showing updated placement when a polygon was moved.
- Disabled rotation controls in the editor, since we don't support rotation during
review.
- Renamed hideInactive to occludeInactive, as it wasn't clear whether the former
meant to hide the occlusions, or keep them (hiding the content). It's stored
as 'oi=1' in the cloze text.
* Increase canvas size limit, and double pixels when required.
* Size canvas based on container size
This results in sharper masks when the intrinsic image size is smaller
than the container, and more legible ones when the container is smaller than
the intrinsic image size.
By using the container instead of the viewport, we account for margins,
and when the pixel ratio is 1x, the canvas size and container size should
match.
* Disable zoom animation on editor load
* Default to rectangle when adding new occlusions
* Allow users to add/update notes directly from mask editing page
* The mask editor needs to work with css pixels, not actual pixels
The canvas and image were being scaled too large, which impacted
performance.
2023-05-31 05:45:12 +02:00
|
|
|
// Copyright: Ankitects Pty Ltd and contributors
|
|
|
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
|
|
|
|
|
|
import type { Canvas, Object as FabricObject } from "fabric";
|
2023-09-26 05:14:13 +02:00
|
|
|
import { fabric } from "fabric";
|
2023-10-10 05:51:35 +02:00
|
|
|
import { cloneDeep } from "lodash-es";
|
Various changes to I/O handling (#2513)
* Store coordinates as ratios of full size
* Use single definition for cappedCanvasSize()
* Move I/O review code into ts/image-occlusion
A bit simpler when it's all in one place.
* Reduce number precision, and round to whole pixels
>>> n=10000
>>> for i in range(1, int(n)): assert i == round(float("%0.4f" % (i/n))*n)
* Minor typing tweak
So, it turns out that typing is mostly broken in ts/image-occlusion.
We're importing from fabric which is a js file without types, so types
like fabric.Canvas are resolving to any.
I first tried switching to `@types/fabric`, which introduced a slew of
typing errors. Wasted a few hours trying to address them, before deciding
to give up on it, since the types were not complete. Then found fabric
has a 6.0 beta that introduces typing, and spent some time with that, but
ran into some new issues as it still seems to be a work in progress.
I think we're probably best off waiting until it's out and stabilized
before sinking more effort into this.
* Refactor (de)serialization of occlusions
To make the code easier to follow/maintain, cloze deletions are now decoded/
encoded into simple data classes, which can then be converted to Fabric objects
and back. The data objects handle converting from absolute/normal positions, and
producing values suitable for writing to text (eg truncated floats).
Various other changes:
- Polygon points are now stored as 'x,y x2,y2 ...' instead of JSON in cloze
divs, as that makes the handling consistent with reading from cloze deletion
text.
- Fixed the reviewer not showing updated placement when a polygon was moved.
- Disabled rotation controls in the editor, since we don't support rotation during
review.
- Renamed hideInactive to occludeInactive, as it wasn't clear whether the former
meant to hide the occlusions, or keep them (hiding the content). It's stored
as 'oi=1' in the cloze text.
* Increase canvas size limit, and double pixels when required.
* Size canvas based on container size
This results in sharper masks when the intrinsic image size is smaller
than the container, and more legible ones when the container is smaller than
the intrinsic image size.
By using the container instead of the viewport, we account for margins,
and when the pixel ratio is 1x, the canvas size and container size should
match.
* Disable zoom animation on editor load
* Default to rectangle when adding new occlusions
* Allow users to add/update notes directly from mask editing page
* The mask editor needs to work with css pixels, not actual pixels
The canvas and image were being scaled too large, which impacted
performance.
2023-05-31 05:45:12 +02:00
|
|
|
|
|
|
|
import { makeMaskTransparent } from "../tools/lib";
|
|
|
|
import type { Size } from "../types";
|
|
|
|
import type { Shape, ShapeOrShapes } from "./base";
|
|
|
|
import { Ellipse } from "./ellipse";
|
|
|
|
import { Polygon } from "./polygon";
|
|
|
|
import { Rectangle } from "./rectangle";
|
|
|
|
|
2023-09-26 05:14:13 +02:00
|
|
|
export function exportShapesToClozeDeletions(occludeInactive: boolean): {
|
|
|
|
clozes: string;
|
|
|
|
noteCount: number;
|
|
|
|
} {
|
Various changes to I/O handling (#2513)
* Store coordinates as ratios of full size
* Use single definition for cappedCanvasSize()
* Move I/O review code into ts/image-occlusion
A bit simpler when it's all in one place.
* Reduce number precision, and round to whole pixels
>>> n=10000
>>> for i in range(1, int(n)): assert i == round(float("%0.4f" % (i/n))*n)
* Minor typing tweak
So, it turns out that typing is mostly broken in ts/image-occlusion.
We're importing from fabric which is a js file without types, so types
like fabric.Canvas are resolving to any.
I first tried switching to `@types/fabric`, which introduced a slew of
typing errors. Wasted a few hours trying to address them, before deciding
to give up on it, since the types were not complete. Then found fabric
has a 6.0 beta that introduces typing, and spent some time with that, but
ran into some new issues as it still seems to be a work in progress.
I think we're probably best off waiting until it's out and stabilized
before sinking more effort into this.
* Refactor (de)serialization of occlusions
To make the code easier to follow/maintain, cloze deletions are now decoded/
encoded into simple data classes, which can then be converted to Fabric objects
and back. The data objects handle converting from absolute/normal positions, and
producing values suitable for writing to text (eg truncated floats).
Various other changes:
- Polygon points are now stored as 'x,y x2,y2 ...' instead of JSON in cloze
divs, as that makes the handling consistent with reading from cloze deletion
text.
- Fixed the reviewer not showing updated placement when a polygon was moved.
- Disabled rotation controls in the editor, since we don't support rotation during
review.
- Renamed hideInactive to occludeInactive, as it wasn't clear whether the former
meant to hide the occlusions, or keep them (hiding the content). It's stored
as 'oi=1' in the cloze text.
* Increase canvas size limit, and double pixels when required.
* Size canvas based on container size
This results in sharper masks when the intrinsic image size is smaller
than the container, and more legible ones when the container is smaller than
the intrinsic image size.
By using the container instead of the viewport, we account for margins,
and when the pixel ratio is 1x, the canvas size and container size should
match.
* Disable zoom animation on editor load
* Default to rectangle when adding new occlusions
* Allow users to add/update notes directly from mask editing page
* The mask editor needs to work with css pixels, not actual pixels
The canvas and image were being scaled too large, which impacted
performance.
2023-05-31 05:45:12 +02:00
|
|
|
const shapes = baseShapesFromFabric(occludeInactive);
|
|
|
|
|
|
|
|
let clozes = "";
|
|
|
|
shapes.forEach((shapeOrShapes, index) => {
|
|
|
|
clozes += shapeOrShapesToCloze(shapeOrShapes, index);
|
|
|
|
});
|
|
|
|
|
|
|
|
return { clozes, noteCount: shapes.length };
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Gather all Fabric shapes, and convert them into BaseShapes or
|
|
|
|
* BaseShape[]s.
|
|
|
|
*/
|
|
|
|
function baseShapesFromFabric(occludeInactive: boolean): ShapeOrShapes[] {
|
|
|
|
const canvas = globalThis.canvas as Canvas;
|
|
|
|
makeMaskTransparent(canvas, false);
|
|
|
|
const objects = canvas.getObjects() as FabricObject[];
|
2023-09-26 05:14:13 +02:00
|
|
|
return objects
|
|
|
|
.map((object) => {
|
|
|
|
return fabricObjectToBaseShapeOrShapes(
|
|
|
|
canvas,
|
|
|
|
object,
|
|
|
|
occludeInactive,
|
|
|
|
);
|
|
|
|
})
|
|
|
|
.filter((o): o is ShapeOrShapes => o !== null);
|
Various changes to I/O handling (#2513)
* Store coordinates as ratios of full size
* Use single definition for cappedCanvasSize()
* Move I/O review code into ts/image-occlusion
A bit simpler when it's all in one place.
* Reduce number precision, and round to whole pixels
>>> n=10000
>>> for i in range(1, int(n)): assert i == round(float("%0.4f" % (i/n))*n)
* Minor typing tweak
So, it turns out that typing is mostly broken in ts/image-occlusion.
We're importing from fabric which is a js file without types, so types
like fabric.Canvas are resolving to any.
I first tried switching to `@types/fabric`, which introduced a slew of
typing errors. Wasted a few hours trying to address them, before deciding
to give up on it, since the types were not complete. Then found fabric
has a 6.0 beta that introduces typing, and spent some time with that, but
ran into some new issues as it still seems to be a work in progress.
I think we're probably best off waiting until it's out and stabilized
before sinking more effort into this.
* Refactor (de)serialization of occlusions
To make the code easier to follow/maintain, cloze deletions are now decoded/
encoded into simple data classes, which can then be converted to Fabric objects
and back. The data objects handle converting from absolute/normal positions, and
producing values suitable for writing to text (eg truncated floats).
Various other changes:
- Polygon points are now stored as 'x,y x2,y2 ...' instead of JSON in cloze
divs, as that makes the handling consistent with reading from cloze deletion
text.
- Fixed the reviewer not showing updated placement when a polygon was moved.
- Disabled rotation controls in the editor, since we don't support rotation during
review.
- Renamed hideInactive to occludeInactive, as it wasn't clear whether the former
meant to hide the occlusions, or keep them (hiding the content). It's stored
as 'oi=1' in the cloze text.
* Increase canvas size limit, and double pixels when required.
* Size canvas based on container size
This results in sharper masks when the intrinsic image size is smaller
than the container, and more legible ones when the container is smaller than
the intrinsic image size.
By using the container instead of the viewport, we account for margins,
and when the pixel ratio is 1x, the canvas size and container size should
match.
* Disable zoom animation on editor load
* Default to rectangle when adding new occlusions
* Allow users to add/update notes directly from mask editing page
* The mask editor needs to work with css pixels, not actual pixels
The canvas and image were being scaled too large, which impacted
performance.
2023-05-31 05:45:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Convert a single Fabric object/group to one or more BaseShapes. */
|
|
|
|
function fabricObjectToBaseShapeOrShapes(
|
|
|
|
size: Size,
|
|
|
|
object: FabricObject,
|
|
|
|
occludeInactive: boolean,
|
2023-09-26 05:14:13 +02:00
|
|
|
parentObject?: FabricObject,
|
Various changes to I/O handling (#2513)
* Store coordinates as ratios of full size
* Use single definition for cappedCanvasSize()
* Move I/O review code into ts/image-occlusion
A bit simpler when it's all in one place.
* Reduce number precision, and round to whole pixels
>>> n=10000
>>> for i in range(1, int(n)): assert i == round(float("%0.4f" % (i/n))*n)
* Minor typing tweak
So, it turns out that typing is mostly broken in ts/image-occlusion.
We're importing from fabric which is a js file without types, so types
like fabric.Canvas are resolving to any.
I first tried switching to `@types/fabric`, which introduced a slew of
typing errors. Wasted a few hours trying to address them, before deciding
to give up on it, since the types were not complete. Then found fabric
has a 6.0 beta that introduces typing, and spent some time with that, but
ran into some new issues as it still seems to be a work in progress.
I think we're probably best off waiting until it's out and stabilized
before sinking more effort into this.
* Refactor (de)serialization of occlusions
To make the code easier to follow/maintain, cloze deletions are now decoded/
encoded into simple data classes, which can then be converted to Fabric objects
and back. The data objects handle converting from absolute/normal positions, and
producing values suitable for writing to text (eg truncated floats).
Various other changes:
- Polygon points are now stored as 'x,y x2,y2 ...' instead of JSON in cloze
divs, as that makes the handling consistent with reading from cloze deletion
text.
- Fixed the reviewer not showing updated placement when a polygon was moved.
- Disabled rotation controls in the editor, since we don't support rotation during
review.
- Renamed hideInactive to occludeInactive, as it wasn't clear whether the former
meant to hide the occlusions, or keep them (hiding the content). It's stored
as 'oi=1' in the cloze text.
* Increase canvas size limit, and double pixels when required.
* Size canvas based on container size
This results in sharper masks when the intrinsic image size is smaller
than the container, and more legible ones when the container is smaller than
the intrinsic image size.
By using the container instead of the viewport, we account for margins,
and when the pixel ratio is 1x, the canvas size and container size should
match.
* Disable zoom animation on editor load
* Default to rectangle when adding new occlusions
* Allow users to add/update notes directly from mask editing page
* The mask editor needs to work with css pixels, not actual pixels
The canvas and image were being scaled too large, which impacted
performance.
2023-05-31 05:45:12 +02:00
|
|
|
): ShapeOrShapes | null {
|
|
|
|
let shape: Shape;
|
2023-09-26 05:14:13 +02:00
|
|
|
|
2023-10-10 05:51:35 +02:00
|
|
|
// Prevents the original fabric object from mutating when a non-primitive
|
|
|
|
// property of a Shape mutates.
|
|
|
|
const cloned = cloneDeep(object);
|
|
|
|
|
Various changes to I/O handling (#2513)
* Store coordinates as ratios of full size
* Use single definition for cappedCanvasSize()
* Move I/O review code into ts/image-occlusion
A bit simpler when it's all in one place.
* Reduce number precision, and round to whole pixels
>>> n=10000
>>> for i in range(1, int(n)): assert i == round(float("%0.4f" % (i/n))*n)
* Minor typing tweak
So, it turns out that typing is mostly broken in ts/image-occlusion.
We're importing from fabric which is a js file without types, so types
like fabric.Canvas are resolving to any.
I first tried switching to `@types/fabric`, which introduced a slew of
typing errors. Wasted a few hours trying to address them, before deciding
to give up on it, since the types were not complete. Then found fabric
has a 6.0 beta that introduces typing, and spent some time with that, but
ran into some new issues as it still seems to be a work in progress.
I think we're probably best off waiting until it's out and stabilized
before sinking more effort into this.
* Refactor (de)serialization of occlusions
To make the code easier to follow/maintain, cloze deletions are now decoded/
encoded into simple data classes, which can then be converted to Fabric objects
and back. The data objects handle converting from absolute/normal positions, and
producing values suitable for writing to text (eg truncated floats).
Various other changes:
- Polygon points are now stored as 'x,y x2,y2 ...' instead of JSON in cloze
divs, as that makes the handling consistent with reading from cloze deletion
text.
- Fixed the reviewer not showing updated placement when a polygon was moved.
- Disabled rotation controls in the editor, since we don't support rotation during
review.
- Renamed hideInactive to occludeInactive, as it wasn't clear whether the former
meant to hide the occlusions, or keep them (hiding the content). It's stored
as 'oi=1' in the cloze text.
* Increase canvas size limit, and double pixels when required.
* Size canvas based on container size
This results in sharper masks when the intrinsic image size is smaller
than the container, and more legible ones when the container is smaller than
the intrinsic image size.
By using the container instead of the viewport, we account for margins,
and when the pixel ratio is 1x, the canvas size and container size should
match.
* Disable zoom animation on editor load
* Default to rectangle when adding new occlusions
* Allow users to add/update notes directly from mask editing page
* The mask editor needs to work with css pixels, not actual pixels
The canvas and image were being scaled too large, which impacted
performance.
2023-05-31 05:45:12 +02:00
|
|
|
switch (object.type) {
|
|
|
|
case "rect":
|
2023-10-10 05:51:35 +02:00
|
|
|
shape = new Rectangle(cloned);
|
Various changes to I/O handling (#2513)
* Store coordinates as ratios of full size
* Use single definition for cappedCanvasSize()
* Move I/O review code into ts/image-occlusion
A bit simpler when it's all in one place.
* Reduce number precision, and round to whole pixels
>>> n=10000
>>> for i in range(1, int(n)): assert i == round(float("%0.4f" % (i/n))*n)
* Minor typing tweak
So, it turns out that typing is mostly broken in ts/image-occlusion.
We're importing from fabric which is a js file without types, so types
like fabric.Canvas are resolving to any.
I first tried switching to `@types/fabric`, which introduced a slew of
typing errors. Wasted a few hours trying to address them, before deciding
to give up on it, since the types were not complete. Then found fabric
has a 6.0 beta that introduces typing, and spent some time with that, but
ran into some new issues as it still seems to be a work in progress.
I think we're probably best off waiting until it's out and stabilized
before sinking more effort into this.
* Refactor (de)serialization of occlusions
To make the code easier to follow/maintain, cloze deletions are now decoded/
encoded into simple data classes, which can then be converted to Fabric objects
and back. The data objects handle converting from absolute/normal positions, and
producing values suitable for writing to text (eg truncated floats).
Various other changes:
- Polygon points are now stored as 'x,y x2,y2 ...' instead of JSON in cloze
divs, as that makes the handling consistent with reading from cloze deletion
text.
- Fixed the reviewer not showing updated placement when a polygon was moved.
- Disabled rotation controls in the editor, since we don't support rotation during
review.
- Renamed hideInactive to occludeInactive, as it wasn't clear whether the former
meant to hide the occlusions, or keep them (hiding the content). It's stored
as 'oi=1' in the cloze text.
* Increase canvas size limit, and double pixels when required.
* Size canvas based on container size
This results in sharper masks when the intrinsic image size is smaller
than the container, and more legible ones when the container is smaller than
the intrinsic image size.
By using the container instead of the viewport, we account for margins,
and when the pixel ratio is 1x, the canvas size and container size should
match.
* Disable zoom animation on editor load
* Default to rectangle when adding new occlusions
* Allow users to add/update notes directly from mask editing page
* The mask editor needs to work with css pixels, not actual pixels
The canvas and image were being scaled too large, which impacted
performance.
2023-05-31 05:45:12 +02:00
|
|
|
break;
|
|
|
|
case "ellipse":
|
2023-10-10 05:51:35 +02:00
|
|
|
shape = new Ellipse(cloned);
|
Various changes to I/O handling (#2513)
* Store coordinates as ratios of full size
* Use single definition for cappedCanvasSize()
* Move I/O review code into ts/image-occlusion
A bit simpler when it's all in one place.
* Reduce number precision, and round to whole pixels
>>> n=10000
>>> for i in range(1, int(n)): assert i == round(float("%0.4f" % (i/n))*n)
* Minor typing tweak
So, it turns out that typing is mostly broken in ts/image-occlusion.
We're importing from fabric which is a js file without types, so types
like fabric.Canvas are resolving to any.
I first tried switching to `@types/fabric`, which introduced a slew of
typing errors. Wasted a few hours trying to address them, before deciding
to give up on it, since the types were not complete. Then found fabric
has a 6.0 beta that introduces typing, and spent some time with that, but
ran into some new issues as it still seems to be a work in progress.
I think we're probably best off waiting until it's out and stabilized
before sinking more effort into this.
* Refactor (de)serialization of occlusions
To make the code easier to follow/maintain, cloze deletions are now decoded/
encoded into simple data classes, which can then be converted to Fabric objects
and back. The data objects handle converting from absolute/normal positions, and
producing values suitable for writing to text (eg truncated floats).
Various other changes:
- Polygon points are now stored as 'x,y x2,y2 ...' instead of JSON in cloze
divs, as that makes the handling consistent with reading from cloze deletion
text.
- Fixed the reviewer not showing updated placement when a polygon was moved.
- Disabled rotation controls in the editor, since we don't support rotation during
review.
- Renamed hideInactive to occludeInactive, as it wasn't clear whether the former
meant to hide the occlusions, or keep them (hiding the content). It's stored
as 'oi=1' in the cloze text.
* Increase canvas size limit, and double pixels when required.
* Size canvas based on container size
This results in sharper masks when the intrinsic image size is smaller
than the container, and more legible ones when the container is smaller than
the intrinsic image size.
By using the container instead of the viewport, we account for margins,
and when the pixel ratio is 1x, the canvas size and container size should
match.
* Disable zoom animation on editor load
* Default to rectangle when adding new occlusions
* Allow users to add/update notes directly from mask editing page
* The mask editor needs to work with css pixels, not actual pixels
The canvas and image were being scaled too large, which impacted
performance.
2023-05-31 05:45:12 +02:00
|
|
|
break;
|
|
|
|
case "polygon":
|
2023-10-10 05:51:35 +02:00
|
|
|
shape = new Polygon(cloned);
|
Various changes to I/O handling (#2513)
* Store coordinates as ratios of full size
* Use single definition for cappedCanvasSize()
* Move I/O review code into ts/image-occlusion
A bit simpler when it's all in one place.
* Reduce number precision, and round to whole pixels
>>> n=10000
>>> for i in range(1, int(n)): assert i == round(float("%0.4f" % (i/n))*n)
* Minor typing tweak
So, it turns out that typing is mostly broken in ts/image-occlusion.
We're importing from fabric which is a js file without types, so types
like fabric.Canvas are resolving to any.
I first tried switching to `@types/fabric`, which introduced a slew of
typing errors. Wasted a few hours trying to address them, before deciding
to give up on it, since the types were not complete. Then found fabric
has a 6.0 beta that introduces typing, and spent some time with that, but
ran into some new issues as it still seems to be a work in progress.
I think we're probably best off waiting until it's out and stabilized
before sinking more effort into this.
* Refactor (de)serialization of occlusions
To make the code easier to follow/maintain, cloze deletions are now decoded/
encoded into simple data classes, which can then be converted to Fabric objects
and back. The data objects handle converting from absolute/normal positions, and
producing values suitable for writing to text (eg truncated floats).
Various other changes:
- Polygon points are now stored as 'x,y x2,y2 ...' instead of JSON in cloze
divs, as that makes the handling consistent with reading from cloze deletion
text.
- Fixed the reviewer not showing updated placement when a polygon was moved.
- Disabled rotation controls in the editor, since we don't support rotation during
review.
- Renamed hideInactive to occludeInactive, as it wasn't clear whether the former
meant to hide the occlusions, or keep them (hiding the content). It's stored
as 'oi=1' in the cloze text.
* Increase canvas size limit, and double pixels when required.
* Size canvas based on container size
This results in sharper masks when the intrinsic image size is smaller
than the container, and more legible ones when the container is smaller than
the intrinsic image size.
By using the container instead of the viewport, we account for margins,
and when the pixel ratio is 1x, the canvas size and container size should
match.
* Disable zoom animation on editor load
* Default to rectangle when adding new occlusions
* Allow users to add/update notes directly from mask editing page
* The mask editor needs to work with css pixels, not actual pixels
The canvas and image were being scaled too large, which impacted
performance.
2023-05-31 05:45:12 +02:00
|
|
|
break;
|
|
|
|
case "group":
|
2023-09-26 05:14:13 +02:00
|
|
|
return object._objects.map((child) => {
|
|
|
|
return fabricObjectToBaseShapeOrShapes(
|
|
|
|
size,
|
|
|
|
child,
|
|
|
|
occludeInactive,
|
|
|
|
object,
|
|
|
|
);
|
Various changes to I/O handling (#2513)
* Store coordinates as ratios of full size
* Use single definition for cappedCanvasSize()
* Move I/O review code into ts/image-occlusion
A bit simpler when it's all in one place.
* Reduce number precision, and round to whole pixels
>>> n=10000
>>> for i in range(1, int(n)): assert i == round(float("%0.4f" % (i/n))*n)
* Minor typing tweak
So, it turns out that typing is mostly broken in ts/image-occlusion.
We're importing from fabric which is a js file without types, so types
like fabric.Canvas are resolving to any.
I first tried switching to `@types/fabric`, which introduced a slew of
typing errors. Wasted a few hours trying to address them, before deciding
to give up on it, since the types were not complete. Then found fabric
has a 6.0 beta that introduces typing, and spent some time with that, but
ran into some new issues as it still seems to be a work in progress.
I think we're probably best off waiting until it's out and stabilized
before sinking more effort into this.
* Refactor (de)serialization of occlusions
To make the code easier to follow/maintain, cloze deletions are now decoded/
encoded into simple data classes, which can then be converted to Fabric objects
and back. The data objects handle converting from absolute/normal positions, and
producing values suitable for writing to text (eg truncated floats).
Various other changes:
- Polygon points are now stored as 'x,y x2,y2 ...' instead of JSON in cloze
divs, as that makes the handling consistent with reading from cloze deletion
text.
- Fixed the reviewer not showing updated placement when a polygon was moved.
- Disabled rotation controls in the editor, since we don't support rotation during
review.
- Renamed hideInactive to occludeInactive, as it wasn't clear whether the former
meant to hide the occlusions, or keep them (hiding the content). It's stored
as 'oi=1' in the cloze text.
* Increase canvas size limit, and double pixels when required.
* Size canvas based on container size
This results in sharper masks when the intrinsic image size is smaller
than the container, and more legible ones when the container is smaller than
the intrinsic image size.
By using the container instead of the viewport, we account for margins,
and when the pixel ratio is 1x, the canvas size and container size should
match.
* Disable zoom animation on editor load
* Default to rectangle when adding new occlusions
* Allow users to add/update notes directly from mask editing page
* The mask editor needs to work with css pixels, not actual pixels
The canvas and image were being scaled too large, which impacted
performance.
2023-05-31 05:45:12 +02:00
|
|
|
});
|
|
|
|
default:
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
shape.occludeInactive = occludeInactive;
|
2023-09-26 05:14:13 +02:00
|
|
|
if (parentObject) {
|
|
|
|
const newPosition = fabric.util.transformPoint(
|
|
|
|
{ x: shape.left, y: shape.top },
|
|
|
|
parentObject.calcTransformMatrix(),
|
|
|
|
);
|
|
|
|
shape.left = newPosition.x;
|
|
|
|
shape.top = newPosition.y;
|
|
|
|
}
|
|
|
|
|
Various changes to I/O handling (#2513)
* Store coordinates as ratios of full size
* Use single definition for cappedCanvasSize()
* Move I/O review code into ts/image-occlusion
A bit simpler when it's all in one place.
* Reduce number precision, and round to whole pixels
>>> n=10000
>>> for i in range(1, int(n)): assert i == round(float("%0.4f" % (i/n))*n)
* Minor typing tweak
So, it turns out that typing is mostly broken in ts/image-occlusion.
We're importing from fabric which is a js file without types, so types
like fabric.Canvas are resolving to any.
I first tried switching to `@types/fabric`, which introduced a slew of
typing errors. Wasted a few hours trying to address them, before deciding
to give up on it, since the types were not complete. Then found fabric
has a 6.0 beta that introduces typing, and spent some time with that, but
ran into some new issues as it still seems to be a work in progress.
I think we're probably best off waiting until it's out and stabilized
before sinking more effort into this.
* Refactor (de)serialization of occlusions
To make the code easier to follow/maintain, cloze deletions are now decoded/
encoded into simple data classes, which can then be converted to Fabric objects
and back. The data objects handle converting from absolute/normal positions, and
producing values suitable for writing to text (eg truncated floats).
Various other changes:
- Polygon points are now stored as 'x,y x2,y2 ...' instead of JSON in cloze
divs, as that makes the handling consistent with reading from cloze deletion
text.
- Fixed the reviewer not showing updated placement when a polygon was moved.
- Disabled rotation controls in the editor, since we don't support rotation during
review.
- Renamed hideInactive to occludeInactive, as it wasn't clear whether the former
meant to hide the occlusions, or keep them (hiding the content). It's stored
as 'oi=1' in the cloze text.
* Increase canvas size limit, and double pixels when required.
* Size canvas based on container size
This results in sharper masks when the intrinsic image size is smaller
than the container, and more legible ones when the container is smaller than
the intrinsic image size.
By using the container instead of the viewport, we account for margins,
and when the pixel ratio is 1x, the canvas size and container size should
match.
* Disable zoom animation on editor load
* Default to rectangle when adding new occlusions
* Allow users to add/update notes directly from mask editing page
* The mask editor needs to work with css pixels, not actual pixels
The canvas and image were being scaled too large, which impacted
performance.
2023-05-31 05:45:12 +02:00
|
|
|
shape.makeNormal(size);
|
|
|
|
return shape;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** generate cloze data in form of
|
|
|
|
{{c1::image-occlusion:rect:top=.1:left=.23:width=.4:height=.5}} */
|
2023-09-26 05:14:13 +02:00
|
|
|
function shapeOrShapesToCloze(
|
|
|
|
shapeOrShapes: ShapeOrShapes,
|
|
|
|
index: number,
|
|
|
|
): string {
|
Various changes to I/O handling (#2513)
* Store coordinates as ratios of full size
* Use single definition for cappedCanvasSize()
* Move I/O review code into ts/image-occlusion
A bit simpler when it's all in one place.
* Reduce number precision, and round to whole pixels
>>> n=10000
>>> for i in range(1, int(n)): assert i == round(float("%0.4f" % (i/n))*n)
* Minor typing tweak
So, it turns out that typing is mostly broken in ts/image-occlusion.
We're importing from fabric which is a js file without types, so types
like fabric.Canvas are resolving to any.
I first tried switching to `@types/fabric`, which introduced a slew of
typing errors. Wasted a few hours trying to address them, before deciding
to give up on it, since the types were not complete. Then found fabric
has a 6.0 beta that introduces typing, and spent some time with that, but
ran into some new issues as it still seems to be a work in progress.
I think we're probably best off waiting until it's out and stabilized
before sinking more effort into this.
* Refactor (de)serialization of occlusions
To make the code easier to follow/maintain, cloze deletions are now decoded/
encoded into simple data classes, which can then be converted to Fabric objects
and back. The data objects handle converting from absolute/normal positions, and
producing values suitable for writing to text (eg truncated floats).
Various other changes:
- Polygon points are now stored as 'x,y x2,y2 ...' instead of JSON in cloze
divs, as that makes the handling consistent with reading from cloze deletion
text.
- Fixed the reviewer not showing updated placement when a polygon was moved.
- Disabled rotation controls in the editor, since we don't support rotation during
review.
- Renamed hideInactive to occludeInactive, as it wasn't clear whether the former
meant to hide the occlusions, or keep them (hiding the content). It's stored
as 'oi=1' in the cloze text.
* Increase canvas size limit, and double pixels when required.
* Size canvas based on container size
This results in sharper masks when the intrinsic image size is smaller
than the container, and more legible ones when the container is smaller than
the intrinsic image size.
By using the container instead of the viewport, we account for margins,
and when the pixel ratio is 1x, the canvas size and container size should
match.
* Disable zoom animation on editor load
* Default to rectangle when adding new occlusions
* Allow users to add/update notes directly from mask editing page
* The mask editor needs to work with css pixels, not actual pixels
The canvas and image were being scaled too large, which impacted
performance.
2023-05-31 05:45:12 +02:00
|
|
|
let text = "";
|
|
|
|
function addKeyValue(key: string, value: string) {
|
2023-10-10 05:51:35 +02:00
|
|
|
if (key !== "points" && Number.isNaN(Number(value))) {
|
2023-07-27 14:45:49 +02:00
|
|
|
value = ".0000";
|
|
|
|
}
|
Various changes to I/O handling (#2513)
* Store coordinates as ratios of full size
* Use single definition for cappedCanvasSize()
* Move I/O review code into ts/image-occlusion
A bit simpler when it's all in one place.
* Reduce number precision, and round to whole pixels
>>> n=10000
>>> for i in range(1, int(n)): assert i == round(float("%0.4f" % (i/n))*n)
* Minor typing tweak
So, it turns out that typing is mostly broken in ts/image-occlusion.
We're importing from fabric which is a js file without types, so types
like fabric.Canvas are resolving to any.
I first tried switching to `@types/fabric`, which introduced a slew of
typing errors. Wasted a few hours trying to address them, before deciding
to give up on it, since the types were not complete. Then found fabric
has a 6.0 beta that introduces typing, and spent some time with that, but
ran into some new issues as it still seems to be a work in progress.
I think we're probably best off waiting until it's out and stabilized
before sinking more effort into this.
* Refactor (de)serialization of occlusions
To make the code easier to follow/maintain, cloze deletions are now decoded/
encoded into simple data classes, which can then be converted to Fabric objects
and back. The data objects handle converting from absolute/normal positions, and
producing values suitable for writing to text (eg truncated floats).
Various other changes:
- Polygon points are now stored as 'x,y x2,y2 ...' instead of JSON in cloze
divs, as that makes the handling consistent with reading from cloze deletion
text.
- Fixed the reviewer not showing updated placement when a polygon was moved.
- Disabled rotation controls in the editor, since we don't support rotation during
review.
- Renamed hideInactive to occludeInactive, as it wasn't clear whether the former
meant to hide the occlusions, or keep them (hiding the content). It's stored
as 'oi=1' in the cloze text.
* Increase canvas size limit, and double pixels when required.
* Size canvas based on container size
This results in sharper masks when the intrinsic image size is smaller
than the container, and more legible ones when the container is smaller than
the intrinsic image size.
By using the container instead of the viewport, we account for margins,
and when the pixel ratio is 1x, the canvas size and container size should
match.
* Disable zoom animation on editor load
* Default to rectangle when adding new occlusions
* Allow users to add/update notes directly from mask editing page
* The mask editor needs to work with css pixels, not actual pixels
The canvas and image were being scaled too large, which impacted
performance.
2023-05-31 05:45:12 +02:00
|
|
|
text += `:${key}=${value}`;
|
|
|
|
}
|
|
|
|
|
|
|
|
let type: string;
|
|
|
|
if (Array.isArray(shapeOrShapes)) {
|
2023-09-26 05:14:13 +02:00
|
|
|
return shapeOrShapes
|
|
|
|
.map((shape) => shapeOrShapesToCloze(shape, index))
|
|
|
|
.join("");
|
Various changes to I/O handling (#2513)
* Store coordinates as ratios of full size
* Use single definition for cappedCanvasSize()
* Move I/O review code into ts/image-occlusion
A bit simpler when it's all in one place.
* Reduce number precision, and round to whole pixels
>>> n=10000
>>> for i in range(1, int(n)): assert i == round(float("%0.4f" % (i/n))*n)
* Minor typing tweak
So, it turns out that typing is mostly broken in ts/image-occlusion.
We're importing from fabric which is a js file without types, so types
like fabric.Canvas are resolving to any.
I first tried switching to `@types/fabric`, which introduced a slew of
typing errors. Wasted a few hours trying to address them, before deciding
to give up on it, since the types were not complete. Then found fabric
has a 6.0 beta that introduces typing, and spent some time with that, but
ran into some new issues as it still seems to be a work in progress.
I think we're probably best off waiting until it's out and stabilized
before sinking more effort into this.
* Refactor (de)serialization of occlusions
To make the code easier to follow/maintain, cloze deletions are now decoded/
encoded into simple data classes, which can then be converted to Fabric objects
and back. The data objects handle converting from absolute/normal positions, and
producing values suitable for writing to text (eg truncated floats).
Various other changes:
- Polygon points are now stored as 'x,y x2,y2 ...' instead of JSON in cloze
divs, as that makes the handling consistent with reading from cloze deletion
text.
- Fixed the reviewer not showing updated placement when a polygon was moved.
- Disabled rotation controls in the editor, since we don't support rotation during
review.
- Renamed hideInactive to occludeInactive, as it wasn't clear whether the former
meant to hide the occlusions, or keep them (hiding the content). It's stored
as 'oi=1' in the cloze text.
* Increase canvas size limit, and double pixels when required.
* Size canvas based on container size
This results in sharper masks when the intrinsic image size is smaller
than the container, and more legible ones when the container is smaller than
the intrinsic image size.
By using the container instead of the viewport, we account for margins,
and when the pixel ratio is 1x, the canvas size and container size should
match.
* Disable zoom animation on editor load
* Default to rectangle when adding new occlusions
* Allow users to add/update notes directly from mask editing page
* The mask editor needs to work with css pixels, not actual pixels
The canvas and image were being scaled too large, which impacted
performance.
2023-05-31 05:45:12 +02:00
|
|
|
} else if (shapeOrShapes instanceof Rectangle) {
|
|
|
|
type = "rect";
|
|
|
|
} else if (shapeOrShapes instanceof Ellipse) {
|
|
|
|
type = "ellipse";
|
|
|
|
} else if (shapeOrShapes instanceof Polygon) {
|
|
|
|
type = "polygon";
|
|
|
|
} else {
|
|
|
|
throw new Error("Unknown shape type");
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const [key, value] of Object.entries(shapeOrShapes.toDataForCloze())) {
|
|
|
|
addKeyValue(key, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
text = `{{c${index + 1}::image-occlusion:${type}${text}}}<br>`;
|
|
|
|
return text;
|
|
|
|
}
|